Update ooo320-m1
[ooovba.git] / slideshow / source / engine / transitions / snakewipe.cxx
blob28bade527101927ad6551fb28bcf86143a7c221e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: snakewipe.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <canvas/debug.hxx>
35 #include <basegfx/matrix/b2dhommatrix.hxx>
36 #include <basegfx/point/b2dpoint.hxx>
37 #include <basegfx/polygon/b2dpolygon.hxx>
38 #include "snakewipe.hxx"
39 #include "transitiontools.hxx"
42 namespace slideshow {
43 namespace internal {
45 SnakeWipe::SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis )
46 : m_sqrtElements( static_cast<sal_Int32>(
47 sqrt( static_cast<double>(nElements) ) ) ),
48 m_elementEdge( 1.0 / m_sqrtElements ),
49 m_diagonal(diagonal),
50 m_flipOnYAxis(flipOnYAxis)
54 ::basegfx::B2DPolyPolygon SnakeWipe::calcSnake( double t ) const
56 ::basegfx::B2DPolyPolygon res;
57 const double area = (t * m_sqrtElements * m_sqrtElements);
58 const sal_Int32 line_ = (static_cast<sal_Int32>(area) / m_sqrtElements);
59 const double line = ::basegfx::pruneScaleValue(
60 static_cast<double>(line_) / m_sqrtElements );
61 const double col = ::basegfx::pruneScaleValue(
62 (area - (line_ * m_sqrtElements)) / m_sqrtElements );
64 if (! ::basegfx::fTools::equalZero( line )) {
65 ::basegfx::B2DPolygon poly;
66 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
67 poly.append( ::basegfx::B2DPoint( 0.0, line ) );
68 poly.append( ::basegfx::B2DPoint( 1.0, line ) );
69 poly.append( ::basegfx::B2DPoint( 1.0, 0.0 ) );
70 poly.setClosed(true);
71 res.append(poly);
73 if (! ::basegfx::fTools::equalZero( col ))
75 double offset = 0.0;
76 if ((line_ & 1) == 1) {
77 // odd line: => right to left
78 offset = (1.0 - col);
80 ::basegfx::B2DPolygon poly;
81 poly.append( ::basegfx::B2DPoint( offset, line ) );
82 poly.append( ::basegfx::B2DPoint( offset,
83 line + m_elementEdge ) );
84 poly.append( ::basegfx::B2DPoint( offset + col,
85 line + m_elementEdge ) );
86 poly.append( ::basegfx::B2DPoint( offset + col, line ) );
87 poly.setClosed(true);
88 res.append(poly);
91 return res;
94 ::basegfx::B2DPolyPolygon SnakeWipe::calcHalfDiagonalSnake(
95 double t, bool in ) const
97 ::basegfx::B2DPolyPolygon res;
99 if (in) {
100 const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements );
101 const double edge = ::basegfx::pruneScaleValue(
102 static_cast<double>( static_cast<sal_Int32>(sqrtArea2) ) /
103 m_sqrtElements );
105 ::basegfx::B2DPolygon poly;
106 if (! ::basegfx::fTools::equalZero( edge )) {
107 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
108 poly.append( ::basegfx::B2DPoint( 0.0, edge ) );
109 poly.append( ::basegfx::B2DPoint( edge, 0.0 ) );
110 poly.setClosed(true);
111 res.append(poly);
113 const double a = (M_SQRT1_2 / m_sqrtElements);
114 const double d = (sqrtArea2 - static_cast<sal_Int32>(sqrtArea2));
115 const double len = (t * M_SQRT2 * d);
116 const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements );
117 poly.clear();
118 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
119 poly.append( ::basegfx::B2DPoint( 0.0, height ) );
120 poly.append( ::basegfx::B2DPoint( len + a, height ) );
121 poly.append( ::basegfx::B2DPoint( len + a, 0.0 ) );
122 poly.setClosed(true);
123 ::basegfx::B2DHomMatrix aTransform;
124 if ((static_cast<sal_Int32>(sqrtArea2) & 1) == 1) {
125 // odd line
126 aTransform.rotate( M_PI_2 + M_PI_4 );
127 aTransform.translate( edge + m_elementEdge, 0.0 );
129 else {
130 aTransform.translate( -a, 0.0 );
131 aTransform.rotate( -M_PI_4 );
132 aTransform.translate( 0.0, edge );
134 poly.transform( aTransform );
135 res.append(poly);
137 else // out
139 const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements );
140 const double edge = ::basegfx::pruneScaleValue(
141 static_cast<double>( static_cast<sal_Int32>(sqrtArea2) ) /
142 m_sqrtElements );
144 ::basegfx::B2DPolygon poly;
145 if (! ::basegfx::fTools::equalZero( edge )) {
146 poly.append( ::basegfx::B2DPoint( 0.0, 1.0 ) );
147 poly.append( ::basegfx::B2DPoint( edge, 1.0 ) );
148 poly.append( ::basegfx::B2DPoint( 1.0, edge ) );
149 poly.append( ::basegfx::B2DPoint( 1.0, 0.0 ) );
150 poly.setClosed(true);
151 res.append(poly);
153 const double a = (M_SQRT1_2 / m_sqrtElements);
154 const double d = (sqrtArea2 - static_cast<sal_Int32>(sqrtArea2));
155 const double len = ((1.0 - t) * M_SQRT2 * d);
156 const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements );
157 poly.clear();
158 poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) );
159 poly.append( ::basegfx::B2DPoint( 0.0, height ) );
160 poly.append( ::basegfx::B2DPoint( len + a, height ) );
161 poly.append( ::basegfx::B2DPoint( len + a, 0.0 ) );
162 poly.setClosed(true);
163 ::basegfx::B2DHomMatrix aTransform;
164 if ((static_cast<sal_Int32>(sqrtArea2) & 1) == 1) {
165 // odd line
166 aTransform.translate( 0.0, -height );
167 aTransform.rotate( M_PI_2 + M_PI_4 );
168 aTransform.translate( 1.0, edge );
170 else {
171 aTransform.rotate( -M_PI_4 );
172 aTransform.translate( edge, 1.0 );
174 poly.transform( aTransform );
175 res.append(poly);
178 return res;
181 ::basegfx::B2DPolyPolygon SnakeWipe::operator () ( double t )
183 ::basegfx::B2DPolyPolygon res;
184 if (m_diagonal)
186 if (t >= 0.5) {
187 res.append( calcHalfDiagonalSnake( 1.0, true ) );
188 res.append( calcHalfDiagonalSnake( 2.0 * (t - 0.5), false ) );
190 else
191 res.append( calcHalfDiagonalSnake( 2.0 * t, true ) );
193 else
194 res = calcSnake(t);
196 return m_flipOnYAxis ? flipOnYAxis(res) : res;
199 ::basegfx::B2DPolyPolygon ParallelSnakesWipe::operator () ( double t )
201 ::basegfx::B2DPolyPolygon res;
202 if (m_diagonal)
204 OSL_ASSERT( m_opposite );
205 ::basegfx::B2DPolyPolygon half(
206 calcHalfDiagonalSnake( t, false /* out */ ) );
207 // flip on x axis and rotate 90 degrees:
208 ::basegfx::B2DHomMatrix aTransform;
209 aTransform.scale( 1.0, -1.0 );
210 aTransform.translate( -0.5, 0.5 );
211 aTransform.rotate( M_PI_2 );
212 aTransform.translate( 0.5, 0.5 );
213 half.transform( aTransform );
214 half.flip();
215 res.append( half );
216 // rotate 180 degrees:
217 aTransform.identity();
218 aTransform.translate( -0.5, -0.5 );
219 aTransform.rotate( M_PI );
220 aTransform.translate( 0.5, 0.5 );
221 half.transform( aTransform );
222 res.append( half );
224 else
226 ::basegfx::B2DPolyPolygon half( calcSnake( t / 2.0 ) );
227 // rotate 90 degrees:
228 ::basegfx::B2DHomMatrix aTransform;
229 aTransform.translate( -0.5, -0.5 );
230 aTransform.rotate( M_PI_2 );
231 aTransform.translate( 0.5, 0.5 );
232 half.transform( aTransform );
233 res.append( flipOnYAxis(half) );
234 res.append( m_opposite ? flipOnXAxis(half) : half );
237 return m_flipOnYAxis ? flipOnYAxis(res) : res;