1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_slideshow.hxx"
26 
27 #include <canvas/debug.hxx>
28 #include "spiralwipe.hxx"
29 #include "transitiontools.hxx"
30 
31 #include <basegfx/matrix/b2dhommatrix.hxx>
32 #include <basegfx/polygon/b2dpolygon.hxx>
33 #include <basegfx/numeric/ftools.hxx>
34 #include <basegfx/matrix/b2dhommatrixtools.hxx>
35 
36 
37 namespace slideshow {
38 namespace internal {
39 
SpiralWipe(sal_Int32 nElements,bool flipOnYAxis)40 SpiralWipe::SpiralWipe( sal_Int32 nElements, bool flipOnYAxis )
41     : m_elements(nElements),
42       m_sqrtElements( static_cast<sal_Int32>(
43                           sqrt( static_cast<double>(nElements) ) ) ),
44       m_flipOnYAxis(flipOnYAxis)
45 {
46 }
47 
calcNegSpiral(double t) const48 ::basegfx::B2DPolyPolygon SpiralWipe::calcNegSpiral( double t ) const
49 {
50     const double area = (t * m_elements);
51     const double e = (sqrt(area) / 2.0);
52     const sal_Int32 edge = (static_cast<sal_Int32>(e) * 2);
53 
54     basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(-0.5, -0.5));
55     const double edge_ = ::basegfx::pruneScaleValue(
56         static_cast<double>(edge) / m_sqrtElements );
57     aTransform.scale( edge_, edge_ );
58     aTransform.translate( 0.5, 0.5 );
59     ::basegfx::B2DPolygon poly( createUnitRect() );
60     poly.transform( aTransform );
61     ::basegfx::B2DPolyPolygon res(poly);
62 
63     if (! ::basegfx::fTools::equalZero( 1.0 - t )) {
64         const sal_Int32 edge1 = (edge + 1);
65         sal_Int32 len = static_cast<sal_Int32>( (e - (edge /2)) * edge1 * 4 );
66         double w = M_PI_2;
67         while (len > 0) {
68             const sal_Int32 alen = (len > edge1 ? edge1 : len);
69             len -= alen;
70             poly = createUnitRect();
71             aTransform = basegfx::tools::createScaleB2DHomMatrix(
72                 ::basegfx::pruneScaleValue( static_cast<double>(alen) / m_sqrtElements ),
73                 ::basegfx::pruneScaleValue( 1.0 / m_sqrtElements ) );
74             aTransform.translate(
75                 - ::basegfx::pruneScaleValue(
76                     static_cast<double>(edge / 2) / m_sqrtElements ),
77                 ::basegfx::pruneScaleValue(
78                     static_cast<double>(edge / 2) / m_sqrtElements ) );
79             aTransform.rotate( w );
80             w -= M_PI_2;
81             aTransform.translate( 0.5, 0.5 );
82             poly.transform( aTransform );
83             res.append(poly);
84         }
85     }
86 
87     return res;
88 }
89 
operator ()(double t)90 ::basegfx::B2DPolyPolygon SpiralWipe::operator () ( double t )
91 {
92     ::basegfx::B2DPolyPolygon res( createUnitRect() );
93     ::basegfx::B2DPolyPolygon innerSpiral( calcNegSpiral( 1.0 - t ) );
94     innerSpiral.flip();
95     res.append(innerSpiral);
96     return m_flipOnYAxis ? flipOnYAxis(res) : res;
97 }
98 
operator ()(double t)99 ::basegfx::B2DPolyPolygon BoxSnakesWipe::operator () ( double t )
100 {
101     ::basegfx::B2DPolyPolygon res( createUnitRect() );
102     ::basegfx::B2DPolyPolygon innerSpiral( calcNegSpiral( 1.0 - t ) );
103     innerSpiral.flip();
104 
105     if (m_fourBox) {
106         ::basegfx::B2DHomMatrix aTransform;
107         aTransform.scale( 0.5, 0.5 );
108         innerSpiral.transform( aTransform );
109         res.append(innerSpiral);
110         res.append( flipOnXAxis(innerSpiral) );
111         innerSpiral = flipOnYAxis(innerSpiral);
112         res.append(innerSpiral);
113         res.append( flipOnXAxis(innerSpiral) );
114     }
115     else {
116         ::basegfx::B2DHomMatrix aTransform;
117         aTransform.scale( 1.0, 0.5 );
118         innerSpiral.transform( aTransform );
119         res.append(innerSpiral);
120         res.append( flipOnXAxis(innerSpiral) );
121     }
122 
123     return m_flipOnYAxis ? flipOnYAxis(res) : res;
124 }
125 
126 }
127 }
128