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 #ifndef _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX 29 #define _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX 30 31 #include <sal/types.h> 32 #include <basegfx/matrix/b2dhommatrix.hxx> 33 #include <basegfx/vector/b2dvector.hxx> 34 35 namespace rtl { class OUString; } 36 37 /////////////////////////////////////////////////////////////////////////////// 38 39 namespace basegfx 40 { 41 namespace tools 42 { 43 /** If the rotation angle is an approximate multiple of pi/2, 44 force fSin/fCos to -1/0/1, to maintain orthogonality (which 45 might also be advantageous for the other cases, but: for 46 multiples of pi/2, the exact values _can_ be attained. It 47 would be largely unintuitive, if a 180 degrees rotation 48 would introduce slight roundoff errors, instead of exactly 49 mirroring the coordinate system) 50 */ 51 void createSinCosOrthogonal(double& o_rSin, double& rCos, double fRadiant); 52 53 /** Tooling methods for on-the-fly matrix generation e.g. for inline 54 multiplications 55 */ 56 B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY); 57 B2DHomMatrix createShearXB2DHomMatrix(double fShearX); 58 B2DHomMatrix createShearYB2DHomMatrix(double fShearY); 59 B2DHomMatrix createRotateB2DHomMatrix(double fRadiant); 60 B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY); 61 62 /// inline versions for parameters as tuples 63 inline B2DHomMatrix createScaleB2DHomMatrix(const B2DTuple& rScale) 64 { 65 return createScaleB2DHomMatrix(rScale.getX(), rScale.getY()); 66 } 67 68 inline B2DHomMatrix createTranslateB2DHomMatrix(const B2DTuple& rTranslate) 69 { 70 return createTranslateB2DHomMatrix(rTranslate.getX(), rTranslate.getY()); 71 } 72 73 /** Tooling methods for faster completely combined matrix creation 74 when scale, shearX, rotation and translation needs to be done in 75 exactly that order. It's faster since it direcly calculates 76 each matrix value based on a symbolic calculation of the three 77 matrix multiplications. 78 Inline versions for parameters as tuples added, too. 79 */ 80 B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix( 81 double fScaleX, double fScaleY, 82 double fShearX, 83 double fRadiant, 84 double fTranslateX, double fTranslateY); 85 inline B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix( 86 const B2DTuple& rScale, 87 double fShearX, 88 double fRadiant, 89 const B2DTuple& rTranslate) 90 { 91 return createScaleShearXRotateTranslateB2DHomMatrix( 92 rScale.getX(), rScale.getY(), 93 fShearX, 94 fRadiant, 95 rTranslate.getX(), rTranslate.getY()); 96 } 97 98 B2DHomMatrix createShearXRotateTranslateB2DHomMatrix( 99 double fShearX, 100 double fRadiant, 101 double fTranslateX, double fTranslateY); 102 inline B2DHomMatrix createShearXRotateTranslateB2DHomMatrix( 103 double fShearX, 104 double fRadiant, 105 const B2DTuple& rTranslate) 106 { 107 return createShearXRotateTranslateB2DHomMatrix( 108 fShearX, 109 fRadiant, 110 rTranslate.getX(), rTranslate.getY()); 111 } 112 113 B2DHomMatrix createScaleTranslateB2DHomMatrix( 114 double fScaleX, double fScaleY, 115 double fTranslateX, double fTranslateY); 116 inline B2DHomMatrix createScaleTranslateB2DHomMatrix( 117 const B2DTuple& rScale, 118 const B2DTuple& rTranslate) 119 { 120 return createScaleTranslateB2DHomMatrix( 121 rScale.getX(), rScale.getY(), 122 rTranslate.getX(), rTranslate.getY()); 123 } 124 125 /// special for the often used case of rotation around a point 126 B2DHomMatrix createRotateAroundPoint( 127 double fPointX, double fPointY, 128 double fRadiant); 129 inline B2DHomMatrix createRotateAroundPoint( 130 const B2DTuple& rPoint, 131 double fRadiant) 132 { 133 return createRotateAroundPoint( 134 rPoint.getX(), rPoint.getY(), 135 fRadiant); 136 } 137 138 } // end of namespace tools 139 } // end of namespace basegfx 140 141 /////////////////////////////////////////////////////////////////////////////// 142 143 namespace basegfx 144 { 145 namespace tools 146 { 147 class B2DHomMatrixBufferedDecompose 148 { 149 private: 150 B2DVector maScale; 151 B2DVector maTranslate; 152 double mfRotate; 153 double mfShearX; 154 155 public: 156 B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix) 157 : maScale(), 158 maTranslate(), 159 mfRotate(0.0), 160 mfShearX(0.0) 161 { 162 rB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX); 163 } 164 165 // data access 166 B2DHomMatrix getB2DHomMatrix() const 167 { 168 return createScaleShearXRotateTranslateB2DHomMatrix( 169 maScale, mfShearX, mfRotate, maTranslate); 170 } 171 172 const B2DVector& getScale() const { return maScale; } 173 const B2DVector& getTranslate() const { return maTranslate; } 174 double getRotate() const { return mfRotate; } 175 double getShearX() const { return mfShearX; } 176 }; 177 } // end of namespace tools 178 } // end of namespace basegfx 179 180 /////////////////////////////////////////////////////////////////////////////// 181 182 namespace basegfx 183 { 184 namespace tools 185 { 186 class B2DHomMatrixBufferedOnDemandDecompose 187 { 188 private: 189 B2DHomMatrix maB2DHomMatrix; 190 B2DVector maScale; 191 B2DVector maTranslate; 192 double mfRotate; 193 double mfShearX; 194 195 // bitfield 196 unsigned mbDecomposed : 1; 197 198 void impCheckDecompose() 199 { 200 if(!mbDecomposed) 201 { 202 maB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX); 203 mbDecomposed = true; 204 } 205 } 206 207 public: 208 B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix) 209 : maB2DHomMatrix(rB2DHomMatrix), 210 maScale(), 211 maTranslate(), 212 mfRotate(0.0), 213 mfShearX(0.0), 214 mbDecomposed(false) 215 { 216 } 217 218 // data access 219 const B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; } 220 const B2DVector& getScale() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maScale; } 221 const B2DVector& getTranslate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maTranslate; } 222 double getRotate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfRotate; } 223 double getShearX() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfShearX; } 224 }; 225 } // end of namespace tools 226 227 /// Returns a string with svg's "matrix(m00,m10,m01,m11,m02,m12)" representation 228 ::rtl::OUString exportToSvg( const B2DHomMatrix& rMatrix ); 229 230 } // end of namespace basegfx 231 232 /////////////////////////////////////////////////////////////////////////////// 233 234 #endif /* _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX */ 235