1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_slideshow.hxx"
30 
31 #include <canvas/debug.hxx>
32 #include "spiralwipe.hxx"
33 #include "transitiontools.hxx"
34 
35 #include <basegfx/matrix/b2dhommatrix.hxx>
36 #include <basegfx/polygon/b2dpolygon.hxx>
37 #include <basegfx/numeric/ftools.hxx>
38 #include <basegfx/matrix/b2dhommatrixtools.hxx>
39 
40 
41 namespace slideshow {
42 namespace internal {
43 
44 SpiralWipe::SpiralWipe( sal_Int32 nElements, bool flipOnYAxis )
45     : m_elements(nElements),
46       m_sqrtElements( static_cast<sal_Int32>(
47                           sqrt( static_cast<double>(nElements) ) ) ),
48       m_flipOnYAxis(flipOnYAxis)
49 {
50 }
51 
52 ::basegfx::B2DPolyPolygon SpiralWipe::calcNegSpiral( double t ) const
53 {
54     const double area = (t * m_elements);
55     const double e = (sqrt(area) / 2.0);
56     const sal_Int32 edge = (static_cast<sal_Int32>(e) * 2);
57 
58     basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(-0.5, -0.5));
59     const double edge_ = ::basegfx::pruneScaleValue(
60         static_cast<double>(edge) / m_sqrtElements );
61     aTransform.scale( edge_, edge_ );
62     aTransform.translate( 0.5, 0.5 );
63     ::basegfx::B2DPolygon poly( createUnitRect() );
64     poly.transform( aTransform );
65     ::basegfx::B2DPolyPolygon res(poly);
66 
67     if (! ::basegfx::fTools::equalZero( 1.0 - t )) {
68         const sal_Int32 edge1 = (edge + 1);
69         sal_Int32 len = static_cast<sal_Int32>( (e - (edge /2)) * edge1 * 4 );
70         double w = M_PI_2;
71         while (len > 0) {
72             const sal_Int32 alen = (len > edge1 ? edge1 : len);
73             len -= alen;
74             poly = createUnitRect();
75             aTransform = basegfx::tools::createScaleB2DHomMatrix(
76                 ::basegfx::pruneScaleValue( static_cast<double>(alen) / m_sqrtElements ),
77                 ::basegfx::pruneScaleValue( 1.0 / m_sqrtElements ) );
78             aTransform.translate(
79                 - ::basegfx::pruneScaleValue(
80                     static_cast<double>(edge / 2) / m_sqrtElements ),
81                 ::basegfx::pruneScaleValue(
82                     static_cast<double>(edge / 2) / m_sqrtElements ) );
83             aTransform.rotate( w );
84             w -= M_PI_2;
85             aTransform.translate( 0.5, 0.5 );
86             poly.transform( aTransform );
87             res.append(poly);
88         }
89     }
90 
91     return res;
92 }
93 
94 ::basegfx::B2DPolyPolygon SpiralWipe::operator () ( double t )
95 {
96     ::basegfx::B2DPolyPolygon res( createUnitRect() );
97     ::basegfx::B2DPolyPolygon innerSpiral( calcNegSpiral( 1.0 - t ) );
98     innerSpiral.flip();
99     res.append(innerSpiral);
100     return m_flipOnYAxis ? flipOnYAxis(res) : res;
101 }
102 
103 ::basegfx::B2DPolyPolygon BoxSnakesWipe::operator () ( double t )
104 {
105     ::basegfx::B2DPolyPolygon res( createUnitRect() );
106     ::basegfx::B2DPolyPolygon innerSpiral( calcNegSpiral( 1.0 - t ) );
107     innerSpiral.flip();
108 
109     if (m_fourBox) {
110         ::basegfx::B2DHomMatrix aTransform;
111         aTransform.scale( 0.5, 0.5 );
112         innerSpiral.transform( aTransform );
113         res.append(innerSpiral);
114         res.append( flipOnXAxis(innerSpiral) );
115         innerSpiral = flipOnYAxis(innerSpiral);
116         res.append(innerSpiral);
117         res.append( flipOnXAxis(innerSpiral) );
118     }
119     else {
120         ::basegfx::B2DHomMatrix aTransform;
121         aTransform.scale( 1.0, 0.5 );
122         innerSpiral.transform( aTransform );
123         res.append(innerSpiral);
124         res.append( flipOnXAxis(innerSpiral) );
125     }
126 
127     return m_flipOnYAxis ? flipOnYAxis(res) : res;
128 }
129 
130 }
131 }
132