1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basegfx.hxx"
31 #include <basegfx/matrix/b2dhommatrixtools.hxx>
32 #include <rtl/ustring.hxx>
33 #include <rtl/ustrbuf.hxx>
35 ///////////////////////////////////////////////////////////////////////////////
39 ::rtl::OUString
exportToSvg( const B2DHomMatrix
& rMatrix
)
41 rtl::OUStringBuffer aStrBuf
;
42 aStrBuf
.appendAscii("matrix(");
44 aStrBuf
.append(rMatrix
.get(0,0));
45 aStrBuf
.appendAscii(", ");
47 aStrBuf
.append(rMatrix
.get(1,0));
48 aStrBuf
.appendAscii(", ");
50 aStrBuf
.append(rMatrix
.get(0,1));
51 aStrBuf
.appendAscii(", ");
53 aStrBuf
.append(rMatrix
.get(1,1));
54 aStrBuf
.appendAscii(", ");
56 aStrBuf
.append(rMatrix
.get(0,2));
57 aStrBuf
.appendAscii(", ");
59 aStrBuf
.append(rMatrix
.get(1,2));
60 aStrBuf
.appendAscii(")");
62 return aStrBuf
.makeStringAndClear();
67 void createSinCosOrthogonal(double& o_rSin
, double& o_rCos
, double fRadiant
)
69 if( fTools::equalZero( fmod( fRadiant
, F_PI2
) ) )
72 const sal_Int32
nQuad(
73 (4 + fround( 4/F_2PI
*fmod( fRadiant
, F_2PI
) )) % 4 );
81 case 1: // -3/2pi,1/2pi
91 case 3: // -1/2pi,3/2pi
97 OSL_ENSURE( false, "createSinCos: Impossible case reached" );
102 // TODO(P1): Maybe use glibc's sincos here (though
103 // that's kinda non-portable...)
104 o_rSin
= sin(fRadiant
);
105 o_rCos
= cos(fRadiant
);
109 B2DHomMatrix
createScaleB2DHomMatrix(double fScaleX
, double fScaleY
)
111 B2DHomMatrix aRetval
;
112 const double fOne(1.0);
114 if(!fTools::equal(fScaleX
, fOne
))
116 aRetval
.set(0, 0, fScaleX
);
119 if(!fTools::equal(fScaleY
, fOne
))
121 aRetval
.set(1, 1, fScaleY
);
127 B2DHomMatrix
createShearXB2DHomMatrix(double fShearX
)
129 B2DHomMatrix aRetval
;
131 if(!fTools::equalZero(fShearX
))
133 aRetval
.set(0, 1, fShearX
);
139 B2DHomMatrix
createShearYB2DHomMatrix(double fShearY
)
141 B2DHomMatrix aRetval
;
143 if(!fTools::equalZero(fShearY
))
145 aRetval
.set(1, 0, fShearY
);
151 B2DHomMatrix
createRotateB2DHomMatrix(double fRadiant
)
153 B2DHomMatrix aRetval
;
155 if(!fTools::equalZero(fRadiant
))
160 createSinCosOrthogonal(fSin
, fCos
, fRadiant
);
161 aRetval
.set(0, 0, fCos
);
162 aRetval
.set(1, 1, fCos
);
163 aRetval
.set(1, 0, fSin
);
164 aRetval
.set(0, 1, -fSin
);
170 B2DHomMatrix
createTranslateB2DHomMatrix(double fTranslateX
, double fTranslateY
)
172 B2DHomMatrix aRetval
;
174 if(!(fTools::equalZero(fTranslateX
) && fTools::equalZero(fTranslateY
)))
176 aRetval
.set(0, 2, fTranslateX
);
177 aRetval
.set(1, 2, fTranslateY
);
183 B2DHomMatrix
createScaleShearXRotateTranslateB2DHomMatrix(
184 double fScaleX
, double fScaleY
,
187 double fTranslateX
, double fTranslateY
)
189 const double fOne(1.0);
191 if(fTools::equal(fScaleX
, fOne
) && fTools::equal(fScaleY
, fOne
))
193 /// no scale, take shortcut
194 return createShearXRotateTranslateB2DHomMatrix(fShearX
, fRadiant
, fTranslateX
, fTranslateY
);
199 if(fTools::equalZero(fShearX
))
202 if(fTools::equalZero(fRadiant
))
204 /// no rotate, take shortcut
205 return createScaleTranslateB2DHomMatrix(fScaleX
, fScaleY
, fTranslateX
, fTranslateY
);
209 /// rotate and scale used, no shear
213 createSinCosOrthogonal(fSin
, fCos
, fRadiant
);
215 B2DHomMatrix
aRetval(
216 /* Row 0, Column 0 */ fCos
* fScaleX
,
217 /* Row 0, Column 1 */ fScaleY
* -fSin
,
218 /* Row 0, Column 2 */ fTranslateX
,
219 /* Row 1, Column 0 */ fSin
* fScaleX
,
220 /* Row 1, Column 1 */ fScaleY
* fCos
,
221 /* Row 1, Column 2 */ fTranslateY
);
228 /// scale and shear used
229 if(fTools::equalZero(fRadiant
))
231 /// scale and shear, but no rotate
232 B2DHomMatrix
aRetval(
233 /* Row 0, Column 0 */ fScaleX
,
234 /* Row 0, Column 1 */ fScaleY
* fShearX
,
235 /* Row 0, Column 2 */ fTranslateX
,
236 /* Row 1, Column 0 */ 0.0,
237 /* Row 1, Column 1 */ fScaleY
,
238 /* Row 1, Column 2 */ fTranslateY
);
244 /// scale, shear and rotate used
248 createSinCosOrthogonal(fSin
, fCos
, fRadiant
);
250 B2DHomMatrix
aRetval(
251 /* Row 0, Column 0 */ fCos
* fScaleX
,
252 /* Row 0, Column 1 */ fScaleY
* ((fCos
* fShearX
) - fSin
),
253 /* Row 0, Column 2 */ fTranslateX
,
254 /* Row 1, Column 0 */ fSin
* fScaleX
,
255 /* Row 1, Column 1 */ fScaleY
* ((fSin
* fShearX
) + fCos
),
256 /* Row 1, Column 2 */ fTranslateY
);
264 B2DHomMatrix
createShearXRotateTranslateB2DHomMatrix(
267 double fTranslateX
, double fTranslateY
)
269 if(fTools::equalZero(fShearX
))
272 if(fTools::equalZero(fRadiant
))
274 /// no shear, no rotate, take shortcut
275 return createTranslateB2DHomMatrix(fTranslateX
, fTranslateY
);
279 /// no shear, but rotate used
283 createSinCosOrthogonal(fSin
, fCos
, fRadiant
);
285 B2DHomMatrix
aRetval(
286 /* Row 0, Column 0 */ fCos
,
287 /* Row 0, Column 1 */ -fSin
,
288 /* Row 0, Column 2 */ fTranslateX
,
289 /* Row 1, Column 0 */ fSin
,
290 /* Row 1, Column 1 */ fCos
,
291 /* Row 1, Column 2 */ fTranslateY
);
299 if(fTools::equalZero(fRadiant
))
301 /// no rotate, but shear used
302 B2DHomMatrix
aRetval(
303 /* Row 0, Column 0 */ 1.0,
304 /* Row 0, Column 1 */ fShearX
,
305 /* Row 0, Column 2 */ fTranslateX
,
306 /* Row 1, Column 0 */ 0.0,
307 /* Row 1, Column 1 */ 1.0,
308 /* Row 1, Column 2 */ fTranslateY
);
314 /// shear and rotate used
318 createSinCosOrthogonal(fSin
, fCos
, fRadiant
);
320 B2DHomMatrix
aRetval(
321 /* Row 0, Column 0 */ fCos
,
322 /* Row 0, Column 1 */ (fCos
* fShearX
) - fSin
,
323 /* Row 0, Column 2 */ fTranslateX
,
324 /* Row 1, Column 0 */ fSin
,
325 /* Row 1, Column 1 */ (fSin
* fShearX
) + fCos
,
326 /* Row 1, Column 2 */ fTranslateY
);
333 B2DHomMatrix
createScaleTranslateB2DHomMatrix(
334 double fScaleX
, double fScaleY
,
335 double fTranslateX
, double fTranslateY
)
337 const double fOne(1.0);
339 if(fTools::equal(fScaleX
, fOne
) && fTools::equal(fScaleY
, fOne
))
341 /// no scale, take shortcut
342 return createTranslateB2DHomMatrix(fTranslateX
, fTranslateY
);
347 if(fTools::equalZero(fTranslateX
) && fTools::equalZero(fTranslateY
))
349 /// no translate, but scale.
350 B2DHomMatrix aRetval
;
352 aRetval
.set(0, 0, fScaleX
);
353 aRetval
.set(1, 1, fScaleY
);
359 /// translate and scale
360 B2DHomMatrix
aRetval(
361 /* Row 0, Column 0 */ fScaleX
,
362 /* Row 0, Column 1 */ 0.0,
363 /* Row 0, Column 2 */ fTranslateX
,
364 /* Row 1, Column 0 */ 0.0,
365 /* Row 1, Column 1 */ fScaleY
,
366 /* Row 1, Column 2 */ fTranslateY
);
373 B2DHomMatrix
createRotateAroundPoint(
374 double fPointX
, double fPointY
,
377 B2DHomMatrix aRetval
;
379 if(!fTools::equalZero(fRadiant
))
384 createSinCosOrthogonal(fSin
, fCos
, fRadiant
);
387 /* Row 0, Column 0 */ fCos
,
388 /* Row 0, Column 1 */ -fSin
,
389 /* Row 0, Column 2 */ (fPointX
* (1.0 - fCos
)) + (fSin
* fPointY
),
390 /* Row 1, Column 0 */ fSin
,
391 /* Row 1, Column 1 */ fCos
,
392 /* Row 1, Column 2 */ (fPointY
* (1.0 - fCos
)) - (fSin
* fPointX
));
397 } // end of namespace tools
398 } // end of namespace basegfx
400 ///////////////////////////////////////////////////////////////////////////////