bump product version to 5.0.4.1
[LibreOffice.git] / slideshow / source / engine / transitions / snakewipe.cxx
blob0fe917f65afebb28904f9e327b1070eb19533a41
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <osl/diagnose.h>
22 #include <canvas/debug.hxx>
23 #include <basegfx/matrix/b2dhommatrix.hxx>
24 #include <basegfx/point/b2dpoint.hxx>
25 #include <basegfx/polygon/b2dpolygon.hxx>
26 #include <basegfx/matrix/b2dhommatrixtools.hxx>
27 #include "snakewipe.hxx"
28 #include "transitiontools.hxx"
31 namespace slideshow {
32 namespace internal {
34 SnakeWipe::SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis )
35 : m_sqrtElements( static_cast<sal_Int32>(
36 sqrt( static_cast<double>(nElements) ) ) ),
37 m_elementEdge( 1.0 / m_sqrtElements ),
38 m_diagonal(diagonal),
39 m_flipOnYAxis(flipOnYAxis)
43 ::basegfx::B2DPolyPolygon SnakeWipe::calcSnake( double t ) const
45 ::basegfx::B2DPolyPolygon res;
46 const double area = (t * m_sqrtElements * m_sqrtElements);
47 const sal_Int32 line_ = (static_cast<sal_Int32>(area) / m_sqrtElements);
48 const double line = ::basegfx::pruneScaleValue(
49 static_cast<double>(line_) / m_sqrtElements );
50 const double col = ::basegfx::pruneScaleValue(
51 (area - (line_ * m_sqrtElements)) / m_sqrtElements );
53 if (! ::basegfx::fTools::equalZero( line )) {
54 ::basegfx::B2DPolygon poly;
55 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
56 poly.append( ::basegfx::B2DPoint( 0.0, line ) );
57 poly.append( ::basegfx::B2DPoint( 1.0, line ) );
58 poly.append( ::basegfx::B2DPoint( 1.0, 0.0 ) );
59 poly.setClosed(true);
60 res.append(poly);
62 if (! ::basegfx::fTools::equalZero( col ))
64 double offset = 0.0;
65 if ((line_ & 1) == 1) {
66 // odd line: => right to left
67 offset = (1.0 - col);
69 ::basegfx::B2DPolygon poly;
70 poly.append( ::basegfx::B2DPoint( offset, line ) );
71 poly.append( ::basegfx::B2DPoint( offset,
72 line + m_elementEdge ) );
73 poly.append( ::basegfx::B2DPoint( offset + col,
74 line + m_elementEdge ) );
75 poly.append( ::basegfx::B2DPoint( offset + col, line ) );
76 poly.setClosed(true);
77 res.append(poly);
80 return res;
83 ::basegfx::B2DPolyPolygon SnakeWipe::calcHalfDiagonalSnake(
84 double t, bool in ) const
86 ::basegfx::B2DPolyPolygon res;
88 if (in) {
89 const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements );
90 const double edge = ::basegfx::pruneScaleValue(
91 static_cast<double>( static_cast<sal_Int32>(sqrtArea2) ) /
92 m_sqrtElements );
94 ::basegfx::B2DPolygon poly;
95 if (! ::basegfx::fTools::equalZero( edge )) {
96 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
97 poly.append( ::basegfx::B2DPoint( 0.0, edge ) );
98 poly.append( ::basegfx::B2DPoint( edge, 0.0 ) );
99 poly.setClosed(true);
100 res.append(poly);
102 const double a = (M_SQRT1_2 / m_sqrtElements);
103 const double d = (sqrtArea2 - static_cast<sal_Int32>(sqrtArea2));
104 const double len = (t * M_SQRT2 * d);
105 const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements );
106 poly.clear();
107 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
108 poly.append( ::basegfx::B2DPoint( 0.0, height ) );
109 poly.append( ::basegfx::B2DPoint( len + a, height ) );
110 poly.append( ::basegfx::B2DPoint( len + a, 0.0 ) );
111 poly.setClosed(true);
112 ::basegfx::B2DHomMatrix aTransform;
114 if ((static_cast<sal_Int32>(sqrtArea2) & 1) == 1)
116 // odd line
117 aTransform = basegfx::tools::createRotateB2DHomMatrix(M_PI_2 + M_PI_4);
118 aTransform.translate(edge + m_elementEdge, 0.0);
120 else
122 aTransform = basegfx::tools::createTranslateB2DHomMatrix(-a, 0.0);
123 aTransform.rotate( -M_PI_4 );
124 aTransform.translate( 0.0, edge );
127 poly.transform( aTransform );
128 res.append(poly);
130 else // out
132 const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements );
133 const double edge = ::basegfx::pruneScaleValue(
134 static_cast<double>( static_cast<sal_Int32>(sqrtArea2) ) /
135 m_sqrtElements );
137 ::basegfx::B2DPolygon poly;
138 if (! ::basegfx::fTools::equalZero( edge )) {
139 poly.append( ::basegfx::B2DPoint( 0.0, 1.0 ) );
140 poly.append( ::basegfx::B2DPoint( edge, 1.0 ) );
141 poly.append( ::basegfx::B2DPoint( 1.0, edge ) );
142 poly.append( ::basegfx::B2DPoint( 1.0, 0.0 ) );
143 poly.setClosed(true);
144 res.append(poly);
146 const double a = (M_SQRT1_2 / m_sqrtElements);
147 const double d = (sqrtArea2 - static_cast<sal_Int32>(sqrtArea2));
148 const double len = ((1.0 - t) * M_SQRT2 * d);
149 const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements );
150 poly.clear();
151 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
152 poly.append( ::basegfx::B2DPoint( 0.0, height ) );
153 poly.append( ::basegfx::B2DPoint( len + a, height ) );
154 poly.append( ::basegfx::B2DPoint( len + a, 0.0 ) );
155 poly.setClosed(true);
156 ::basegfx::B2DHomMatrix aTransform;
158 if ((static_cast<sal_Int32>(sqrtArea2) & 1) == 1)
160 // odd line
161 aTransform = basegfx::tools::createTranslateB2DHomMatrix(0.0, -height);
162 aTransform.rotate( M_PI_2 + M_PI_4 );
163 aTransform.translate( 1.0, edge );
165 else
167 aTransform = basegfx::tools::createRotateB2DHomMatrix(-M_PI_4);
168 aTransform.translate( edge, 1.0 );
170 poly.transform( aTransform );
171 res.append(poly);
174 return res;
177 ::basegfx::B2DPolyPolygon SnakeWipe::operator () ( double t )
179 ::basegfx::B2DPolyPolygon res;
180 if (m_diagonal)
182 if (t >= 0.5) {
183 res.append( calcHalfDiagonalSnake( 1.0, true ) );
184 res.append( calcHalfDiagonalSnake( 2.0 * (t - 0.5), false ) );
186 else
187 res.append( calcHalfDiagonalSnake( 2.0 * t, true ) );
189 else
190 res = calcSnake(t);
192 return m_flipOnYAxis ? flipOnYAxis(res) : res;
195 ::basegfx::B2DPolyPolygon ParallelSnakesWipe::operator () ( double t )
197 ::basegfx::B2DPolyPolygon res;
198 if (m_diagonal)
200 OSL_ASSERT( m_opposite );
201 ::basegfx::B2DPolyPolygon half(
202 calcHalfDiagonalSnake( t, false /* out */ ) );
203 // flip on x axis and rotate 90 degrees:
204 basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleB2DHomMatrix(1.0, -1.0));
205 aTransform.translate( -0.5, 0.5 );
206 aTransform.rotate( M_PI_2 );
207 aTransform.translate( 0.5, 0.5 );
208 half.transform( aTransform );
209 half.flip();
210 res.append( half );
212 // rotate 180 degrees:
213 aTransform = basegfx::tools::createTranslateB2DHomMatrix(-0.5, -0.5);
214 aTransform.rotate( M_PI );
215 aTransform.translate( 0.5, 0.5 );
216 half.transform( aTransform );
217 res.append( half );
219 else
221 ::basegfx::B2DPolyPolygon half( calcSnake( t / 2.0 ) );
222 // rotate 90 degrees:
223 basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(-0.5, -0.5));
224 aTransform.rotate( M_PI_2 );
225 aTransform.translate( 0.5, 0.5 );
226 half.transform( aTransform );
227 res.append( flipOnYAxis(half) );
228 res.append( m_opposite ? flipOnXAxis(half) : half );
231 return m_flipOnYAxis ? flipOnYAxis(res) : res;
237 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */