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