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