Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <basegfx/matrix/b2dhommatrixtools.hxx>
30 : : #include <rtl/ustring.hxx>
31 : : #include <rtl/ustrbuf.hxx>
32 : :
33 : : ///////////////////////////////////////////////////////////////////////////////
34 : :
35 : : namespace basegfx
36 : : {
37 : : namespace tools
38 : : {
39 : 52890 : void createSinCosOrthogonal(double& o_rSin, double& o_rCos, double fRadiant)
40 : : {
41 [ + + ]: 52890 : if( fTools::equalZero( fmod( fRadiant, F_PI2 ) ) )
42 : : {
43 : : // determine quadrant
44 : : const sal_Int32 nQuad(
45 : 41511 : (4 + fround( 4/F_2PI*fmod( fRadiant, F_2PI ) )) % 4 );
46 [ - + + + : 41511 : switch( nQuad )
- ]
47 : : {
48 : : case 0: // -2pi,0,2pi
49 : 0 : o_rSin = 0.0;
50 : 0 : o_rCos = 1.0;
51 : 0 : break;
52 : :
53 : : case 1: // -3/2pi,1/2pi
54 : 33819 : o_rSin = 1.0;
55 : 33819 : o_rCos = 0.0;
56 : 33819 : break;
57 : :
58 : : case 2: // -pi,pi
59 : 153 : o_rSin = 0.0;
60 : 153 : o_rCos = -1.0;
61 : 153 : break;
62 : :
63 : : case 3: // -1/2pi,3/2pi
64 : 7539 : o_rSin = -1.0;
65 : 7539 : o_rCos = 0.0;
66 : 41511 : break;
67 : :
68 : : default:
69 : : OSL_FAIL( "createSinCos: Impossible case reached" );
70 : : }
71 : : }
72 : : else
73 : : {
74 : : // TODO(P1): Maybe use glibc's sincos here (though
75 : : // that's kinda non-portable...)
76 : 11379 : o_rSin = sin(fRadiant);
77 : 11379 : o_rCos = cos(fRadiant);
78 : : }
79 : 52890 : }
80 : :
81 : 2371 : B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY)
82 : : {
83 [ + - ]: 2371 : B2DHomMatrix aRetval;
84 : 2371 : const double fOne(1.0);
85 : :
86 [ + - ]: 2371 : if(!fTools::equal(fScaleX, fOne))
87 : : {
88 [ + - ]: 2371 : aRetval.set(0, 0, fScaleX);
89 : : }
90 : :
91 [ + - ]: 2371 : if(!fTools::equal(fScaleY, fOne))
92 : : {
93 [ + - ]: 2371 : aRetval.set(1, 1, fScaleY);
94 : : }
95 : :
96 : 2371 : return aRetval;
97 : : }
98 : :
99 : 542 : B2DHomMatrix createRotateB2DHomMatrix(double fRadiant)
100 : : {
101 : 542 : B2DHomMatrix aRetval;
102 : :
103 [ + - ]: 542 : if(!fTools::equalZero(fRadiant))
104 : : {
105 : 542 : double fSin(0.0);
106 : 542 : double fCos(1.0);
107 : :
108 [ + - ]: 542 : createSinCosOrthogonal(fSin, fCos, fRadiant);
109 [ + - ]: 542 : aRetval.set(0, 0, fCos);
110 [ + - ]: 542 : aRetval.set(1, 1, fCos);
111 [ + - ]: 542 : aRetval.set(1, 0, fSin);
112 [ + - ]: 542 : aRetval.set(0, 1, -fSin);
113 : : }
114 : :
115 : 542 : return aRetval;
116 : : }
117 : :
118 : 138625 : B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
119 : : {
120 : 138625 : B2DHomMatrix aRetval;
121 : :
122 [ + + ][ + + ]: 138625 : if(!(fTools::equalZero(fTranslateX) && fTools::equalZero(fTranslateY)))
[ + + ]
123 : : {
124 [ + - ]: 61445 : aRetval.set(0, 2, fTranslateX);
125 [ + - ]: 61445 : aRetval.set(1, 2, fTranslateY);
126 : : }
127 : :
128 : 138625 : return aRetval;
129 : : }
130 : :
131 : 147997 : B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
132 : : double fScaleX, double fScaleY,
133 : : double fShearX,
134 : : double fRadiant,
135 : : double fTranslateX, double fTranslateY)
136 : : {
137 : 147997 : const double fOne(1.0);
138 : :
139 [ + + ][ + + ]: 147997 : if(fTools::equal(fScaleX, fOne) && fTools::equal(fScaleY, fOne))
[ + + ]
140 : : {
141 : : /// no scale, take shortcut
142 [ + - ]: 31737 : return createShearXRotateTranslateB2DHomMatrix(fShearX, fRadiant, fTranslateX, fTranslateY);
143 : : }
144 : : else
145 : : {
146 : : /// scale used
147 [ + - ]: 116260 : if(fTools::equalZero(fShearX))
148 : : {
149 : : /// no shear
150 [ + + ]: 116260 : if(fTools::equalZero(fRadiant))
151 : : {
152 : : /// no rotate, take shortcut
153 [ + - ]: 112265 : return createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, fTranslateX, fTranslateY);
154 : : }
155 : : else
156 : : {
157 : : /// rotate and scale used, no shear
158 : 3995 : double fSin(0.0);
159 : 3995 : double fCos(1.0);
160 : :
161 [ + - ]: 3995 : createSinCosOrthogonal(fSin, fCos, fRadiant);
162 : :
163 : : B2DHomMatrix aRetval(
164 : : /* Row 0, Column 0 */ fCos * fScaleX,
165 : : /* Row 0, Column 1 */ fScaleY * -fSin,
166 : : /* Row 0, Column 2 */ fTranslateX,
167 : : /* Row 1, Column 0 */ fSin * fScaleX,
168 : : /* Row 1, Column 1 */ fScaleY * fCos,
169 [ + - ]: 3995 : /* Row 1, Column 2 */ fTranslateY);
170 : :
171 [ + - ][ + - ]: 3995 : return aRetval;
172 : : }
173 : : }
174 : : else
175 : : {
176 : : /// scale and shear used
177 [ # # ]: 0 : if(fTools::equalZero(fRadiant))
178 : : {
179 : : /// scale and shear, but no rotate
180 : : B2DHomMatrix aRetval(
181 : : /* Row 0, Column 0 */ fScaleX,
182 : : /* Row 0, Column 1 */ fScaleY * fShearX,
183 : : /* Row 0, Column 2 */ fTranslateX,
184 : : /* Row 1, Column 0 */ 0.0,
185 : : /* Row 1, Column 1 */ fScaleY,
186 [ # # ]: 0 : /* Row 1, Column 2 */ fTranslateY);
187 : :
188 [ # # ][ # # ]: 0 : return aRetval;
189 : : }
190 : : else
191 : : {
192 : : /// scale, shear and rotate used
193 : 0 : double fSin(0.0);
194 : 0 : double fCos(1.0);
195 : :
196 [ # # ]: 0 : createSinCosOrthogonal(fSin, fCos, fRadiant);
197 : :
198 : : B2DHomMatrix aRetval(
199 : : /* Row 0, Column 0 */ fCos * fScaleX,
200 : : /* Row 0, Column 1 */ fScaleY * ((fCos * fShearX) - fSin),
201 : : /* Row 0, Column 2 */ fTranslateX,
202 : : /* Row 1, Column 0 */ fSin * fScaleX,
203 : : /* Row 1, Column 1 */ fScaleY * ((fSin * fShearX) + fCos),
204 [ # # ]: 0 : /* Row 1, Column 2 */ fTranslateY);
205 : :
206 [ # # ][ # # ]: 147997 : return aRetval;
207 : : }
208 : : }
209 : : }
210 : : }
211 : :
212 : 50682 : B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
213 : : double fShearX,
214 : : double fRadiant,
215 : : double fTranslateX, double fTranslateY)
216 : : {
217 [ + - ]: 50682 : if(fTools::equalZero(fShearX))
218 : : {
219 : : /// no shear
220 [ + + ]: 50682 : if(fTools::equalZero(fRadiant))
221 : : {
222 : : /// no shear, no rotate, take shortcut
223 : 46669 : return createTranslateB2DHomMatrix(fTranslateX, fTranslateY);
224 : : }
225 : : else
226 : : {
227 : : /// no shear, but rotate used
228 : 4013 : double fSin(0.0);
229 : 4013 : double fCos(1.0);
230 : :
231 [ + - ]: 4013 : createSinCosOrthogonal(fSin, fCos, fRadiant);
232 : :
233 : : B2DHomMatrix aRetval(
234 : : /* Row 0, Column 0 */ fCos,
235 : : /* Row 0, Column 1 */ -fSin,
236 : : /* Row 0, Column 2 */ fTranslateX,
237 : : /* Row 1, Column 0 */ fSin,
238 : : /* Row 1, Column 1 */ fCos,
239 [ + - ]: 4013 : /* Row 1, Column 2 */ fTranslateY);
240 : :
241 [ + - ][ + - ]: 4013 : return aRetval;
242 : : }
243 : : }
244 : : else
245 : : {
246 : : /// shear used
247 [ # # ]: 0 : if(fTools::equalZero(fRadiant))
248 : : {
249 : : /// no rotate, but shear used
250 : : B2DHomMatrix aRetval(
251 : : /* Row 0, Column 0 */ 1.0,
252 : : /* Row 0, Column 1 */ fShearX,
253 : : /* Row 0, Column 2 */ fTranslateX,
254 : : /* Row 1, Column 0 */ 0.0,
255 : : /* Row 1, Column 1 */ 1.0,
256 [ # # ]: 0 : /* Row 1, Column 2 */ fTranslateY);
257 : :
258 [ # # ][ # # ]: 0 : return aRetval;
259 : : }
260 : : else
261 : : {
262 : : /// shear and rotate used
263 : 0 : double fSin(0.0);
264 : 0 : double fCos(1.0);
265 : :
266 [ # # ]: 0 : createSinCosOrthogonal(fSin, fCos, fRadiant);
267 : :
268 : : B2DHomMatrix aRetval(
269 : : /* Row 0, Column 0 */ fCos,
270 : : /* Row 0, Column 1 */ (fCos * fShearX) - fSin,
271 : : /* Row 0, Column 2 */ fTranslateX,
272 : : /* Row 1, Column 0 */ fSin,
273 : : /* Row 1, Column 1 */ (fSin * fShearX) + fCos,
274 [ # # ]: 0 : /* Row 1, Column 2 */ fTranslateY);
275 : :
276 [ # # ][ # # ]: 50682 : return aRetval;
277 : : }
278 : : }
279 : : }
280 : :
281 : 164086 : B2DHomMatrix createScaleTranslateB2DHomMatrix(
282 : : double fScaleX, double fScaleY,
283 : : double fTranslateX, double fTranslateY)
284 : : {
285 : 164086 : const double fOne(1.0);
286 : :
287 [ + + ][ + + ]: 164086 : if(fTools::equal(fScaleX, fOne) && fTools::equal(fScaleY, fOne))
[ + + ]
288 : : {
289 : : /// no scale, take shortcut
290 [ + - ]: 844 : return createTranslateB2DHomMatrix(fTranslateX, fTranslateY);
291 : : }
292 : : else
293 : : {
294 : : /// scale used
295 [ + + ][ + + ]: 163242 : if(fTools::equalZero(fTranslateX) && fTools::equalZero(fTranslateY))
[ + + ]
296 : : {
297 : : /// no translate, but scale.
298 [ + - ]: 50589 : B2DHomMatrix aRetval;
299 : :
300 [ + - ]: 50589 : aRetval.set(0, 0, fScaleX);
301 [ + - ]: 50589 : aRetval.set(1, 1, fScaleY);
302 : :
303 [ + - ][ + - ]: 50589 : return aRetval;
304 : : }
305 : : else
306 : : {
307 : : /// translate and scale
308 : : B2DHomMatrix aRetval(
309 : : /* Row 0, Column 0 */ fScaleX,
310 : : /* Row 0, Column 1 */ 0.0,
311 : : /* Row 0, Column 2 */ fTranslateX,
312 : : /* Row 1, Column 0 */ 0.0,
313 : : /* Row 1, Column 1 */ fScaleY,
314 [ + - ]: 112653 : /* Row 1, Column 2 */ fTranslateY);
315 : :
316 [ + - ][ + - ]: 164086 : return aRetval;
317 : : }
318 : : }
319 : : }
320 : :
321 : 341 : B2DHomMatrix createRotateAroundPoint(
322 : : double fPointX, double fPointY,
323 : : double fRadiant)
324 : : {
325 : 341 : B2DHomMatrix aRetval;
326 : :
327 [ + - ]: 341 : if(!fTools::equalZero(fRadiant))
328 : : {
329 : 341 : double fSin(0.0);
330 : 341 : double fCos(1.0);
331 : :
332 [ + - ]: 341 : createSinCosOrthogonal(fSin, fCos, fRadiant);
333 : :
334 : : aRetval.set3x2(
335 : : /* Row 0, Column 0 */ fCos,
336 : : /* Row 0, Column 1 */ -fSin,
337 : : /* Row 0, Column 2 */ (fPointX * (1.0 - fCos)) + (fSin * fPointY),
338 : : /* Row 1, Column 0 */ fSin,
339 : : /* Row 1, Column 1 */ fCos,
340 [ + - ]: 341 : /* Row 1, Column 2 */ (fPointY * (1.0 - fCos)) - (fSin * fPointX));
341 : : }
342 : :
343 : 341 : return aRetval;
344 : : }
345 : : } // end of namespace tools
346 : : } // end of namespace basegfx
347 : :
348 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|