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