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