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 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 48 ::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 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 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