xref: /AOO41X/main/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX
29 #define _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX
30 
31 #include <sal/types.h>
32 #include <basegfx/matrix/b2dhommatrix.hxx>
33 #include <basegfx/vector/b2dvector.hxx>
34 
35 namespace rtl { class OUString; }
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 
39 namespace basegfx
40 {
41 	namespace tools
42 	{
43 		/** If the rotation angle is an approximate multiple of pi/2,
44 			force fSin/fCos to -1/0/1, to maintain orthogonality (which
45 			might also be advantageous for the other cases, but: for
46 			multiples of pi/2, the exact values _can_ be attained. It
47 			would be largely unintuitive, if a 180 degrees rotation
48 			would introduce slight roundoff errors, instead of exactly
49 			mirroring the coordinate system)
50 		 */
51 		void createSinCosOrthogonal(double& o_rSin, double& rCos, double fRadiant);
52 
53 		/** Tooling methods for on-the-fly matrix generation e.g. for inline
54 			multiplications
55 		 */
56 		B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY);
57 		B2DHomMatrix createShearXB2DHomMatrix(double fShearX);
58 		B2DHomMatrix createShearYB2DHomMatrix(double fShearY);
59 		B2DHomMatrix createRotateB2DHomMatrix(double fRadiant);
60 		B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY);
61 
62 		/// inline versions for parameters as tuples
63 		inline B2DHomMatrix createScaleB2DHomMatrix(const B2DTuple& rScale)
64 		{
65 			return createScaleB2DHomMatrix(rScale.getX(), rScale.getY());
66 		}
67 
68 		inline B2DHomMatrix createTranslateB2DHomMatrix(const B2DTuple& rTranslate)
69 		{
70 			return createTranslateB2DHomMatrix(rTranslate.getX(), rTranslate.getY());
71 		}
72 
73 		/** Tooling methods for faster completely combined matrix creation
74 			when scale, shearX, rotation and translation needs to be done in
75 			exactly that order. It's faster since it direcly calculates
76 			each matrix value based on a symbolic calculation of the three
77 			matrix multiplications.
78 			Inline versions for parameters as tuples added, too.
79 		 */
80 		B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
81 			double fScaleX, double fScaleY,
82 			double fShearX,
83 			double fRadiant,
84 			double fTranslateX, double fTranslateY);
85 		inline B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
86 			const B2DTuple& rScale,
87 			double fShearX,
88 			double fRadiant,
89 			const B2DTuple& rTranslate)
90 		{
91 			return createScaleShearXRotateTranslateB2DHomMatrix(
92 				rScale.getX(), rScale.getY(),
93 				fShearX,
94 				fRadiant,
95 				rTranslate.getX(), rTranslate.getY());
96 		}
97 
98 		B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
99 			double fShearX,
100 			double fRadiant,
101 			double fTranslateX, double fTranslateY);
102 		inline B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
103 			double fShearX,
104 			double fRadiant,
105 			const B2DTuple& rTranslate)
106 		{
107 			return createShearXRotateTranslateB2DHomMatrix(
108 				fShearX,
109 				fRadiant,
110 				rTranslate.getX(), rTranslate.getY());
111 		}
112 
113 		B2DHomMatrix createScaleTranslateB2DHomMatrix(
114 			double fScaleX, double fScaleY,
115 			double fTranslateX, double fTranslateY);
116 		inline B2DHomMatrix createScaleTranslateB2DHomMatrix(
117 			const B2DTuple& rScale,
118 			const B2DTuple& rTranslate)
119 		{
120 			return createScaleTranslateB2DHomMatrix(
121 				rScale.getX(), rScale.getY(),
122 				rTranslate.getX(), rTranslate.getY());
123 		}
124 
125         /// special for the often used case of rotation around a point
126         B2DHomMatrix createRotateAroundPoint(
127             double fPointX, double fPointY,
128             double fRadiant);
129         inline B2DHomMatrix createRotateAroundPoint(
130             const B2DTuple& rPoint,
131             double fRadiant)
132         {
133             return createRotateAroundPoint(
134                 rPoint.getX(), rPoint.getY(),
135                 fRadiant);
136         }
137 
138     } // end of namespace tools
139 } // end of namespace basegfx
140 
141 ///////////////////////////////////////////////////////////////////////////////
142 
143 namespace basegfx
144 {
145 	namespace tools
146 	{
147 		class B2DHomMatrixBufferedDecompose
148 		{
149 		private:
150 			B2DVector              maScale;
151 			B2DVector              maTranslate;
152 			double                 mfRotate;
153 			double                 mfShearX;
154 
155 		public:
156 			B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix)
157 			:   maScale(),
158 				maTranslate(),
159 				mfRotate(0.0),
160 				mfShearX(0.0)
161 			{
162 				rB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
163 			}
164 
165 			// data access
166 			B2DHomMatrix getB2DHomMatrix() const
167 			{
168 				return createScaleShearXRotateTranslateB2DHomMatrix(
169 					maScale, mfShearX, mfRotate, maTranslate);
170 			}
171 
172 			const B2DVector& getScale() const { return maScale; }
173 			const B2DVector& getTranslate() const { return maTranslate; }
174 			double getRotate() const { return mfRotate; }
175 			double getShearX() const { return mfShearX; }
176 		};
177     } // end of namespace tools
178 } // end of namespace basegfx
179 
180 ///////////////////////////////////////////////////////////////////////////////
181 
182 namespace basegfx
183 {
184 	namespace tools
185 	{
186 		class B2DHomMatrixBufferedOnDemandDecompose
187 		{
188 		private:
189 			B2DHomMatrix           maB2DHomMatrix;
190 			B2DVector              maScale;
191 			B2DVector              maTranslate;
192 			double                 mfRotate;
193 			double                 mfShearX;
194 
195 			// bitfield
196 			unsigned               mbDecomposed : 1;
197 
198 			void impCheckDecompose()
199 			{
200 				if(!mbDecomposed)
201 				{
202 					maB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
203 					mbDecomposed = true;
204 				}
205 			}
206 
207 		public:
208 			B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix)
209 			:   maB2DHomMatrix(rB2DHomMatrix),
210 				maScale(),
211 				maTranslate(),
212 				mfRotate(0.0),
213 				mfShearX(0.0),
214 				mbDecomposed(false)
215 			{
216 			}
217 
218 			// data access
219 			const B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; }
220 			const B2DVector& getScale() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maScale; }
221 			const B2DVector& getTranslate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maTranslate; }
222 			double getRotate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfRotate; }
223 			double getShearX() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfShearX; }
224 		};
225     } // end of namespace tools
226 
227     /// Returns a string with svg's "matrix(m00,m10,m01,m11,m02,m12)" representation
228     ::rtl::OUString exportToSvg( const B2DHomMatrix& rMatrix );
229 
230 } // end of namespace basegfx
231 
232 ///////////////////////////////////////////////////////////////////////////////
233 
234 #endif /* _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX */
235