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