xref: /AOO41X/main/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx (revision d3e0dd8eb215533c15e891ee35bd141abe9397ee)
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