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