1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "xexptran.hxx"
21 #include <rtl/ustrbuf.hxx>
22 #include <sax/tools/converter.hxx>
23 #include <xmloff/xmluconv.hxx>
24 #include <xmloff/xmlexp.hxx>
25 #include <xmloff/xmlimp.hxx>
26 #include <tools/helpers.hxx>
27 #include <basegfx/vector/b2dvector.hxx>
28 #include <basegfx/matrix/b2dhommatrix.hxx>
29 #include <basegfx/tuple/b3dtuple.hxx>
30 #include <basegfx/matrix/b3dhommatrix.hxx>
31 #include <basegfx/numeric/ftools.hxx>
32 #include <basegfx/polygon/b2dpolypolygon.hxx>
33 #include <basegfx/polygon/b2dpolypolygontools.hxx>
34 #include <basegfx/tools/unotools.hxx>
36 using namespace ::com::sun::star
;
38 // parsing help functions for simple chars
39 void Imp_SkipSpaces(const OUString
& rStr
, sal_Int32
& rPos
, const sal_Int32 nLen
)
46 void Imp_SkipSpacesAndOpeningBraces(const OUString
& rStr
, sal_Int32
& rPos
, const sal_Int32 nLen
)
49 && (' ' == rStr
[rPos
] || '(' == rStr
[rPos
]))
53 void Imp_SkipSpacesAndCommas(const OUString
& rStr
, sal_Int32
& rPos
, const sal_Int32 nLen
)
56 && (' ' == rStr
[rPos
] || ',' == rStr
[rPos
]))
60 void Imp_SkipSpacesAndClosingBraces(const OUString
& rStr
, sal_Int32
& rPos
, const sal_Int32 nLen
)
63 && (' ' == rStr
[rPos
] || ')' == rStr
[rPos
]))
67 // parsing help functions for integer numbers
69 bool Imp_IsOnUnitChar(const OUString
& rStr
, const sal_Int32 nPos
)
71 sal_Unicode
aChar(rStr
[nPos
]);
73 if(('a' <= aChar
&& 'z' >= aChar
)
74 || ('A' <= aChar
&& 'Z' >= aChar
)
81 double Imp_GetDoubleChar(const OUString
& rStr
, sal_Int32
& rPos
, const sal_Int32 nLen
,
82 const SvXMLUnitConverter
& rConv
, double fRetval
, bool bLookForUnits
= false)
84 sal_Unicode
aChar(rStr
[rPos
]);
85 OUStringBuffer sNumberString
;
87 if('+' == aChar
|| '-' == aChar
)
89 sNumberString
.append(rStr
[rPos
]);
91 aChar
= rPos
>= nLen
? 0 : rStr
[rPos
];
94 while(('0' <= aChar
&& '9' >= aChar
)
97 sNumberString
.append(rStr
[rPos
]);
99 aChar
= rPos
>= nLen
? 0 : rStr
[rPos
];
102 if('e' == aChar
|| 'E' == aChar
)
104 sNumberString
.append(rStr
[rPos
]);
106 aChar
= rPos
>= nLen
? 0 : rStr
[rPos
];
108 if('+' == aChar
|| '-' == aChar
)
110 sNumberString
.append(rStr
[rPos
]);
112 aChar
= rPos
>= nLen
? 0 : rStr
[rPos
];
115 while('0' <= aChar
&& '9' >= aChar
)
117 sNumberString
.append(rStr
[rPos
]);
119 aChar
= rPos
>= nLen
? 0 : rStr
[rPos
];
125 Imp_SkipSpaces(rStr
, rPos
, nLen
);
126 while(rPos
< nLen
&& Imp_IsOnUnitChar(rStr
, rPos
))
127 sNumberString
.append(rStr
[rPos
++]);
130 if(!sNumberString
.isEmpty())
133 rConv
.convertDouble(fRetval
, sNumberString
.makeStringAndClear(), true);
136 ::sax::Converter::convertDouble(fRetval
,
137 sNumberString
.makeStringAndClear());
144 void Imp_PutDoubleChar(OUString
& rStr
, double fValue
)
146 OUStringBuffer sStringBuffer
;
147 ::sax::Converter::convertDouble(sStringBuffer
, fValue
);
148 rStr
+= OUString(sStringBuffer
.makeStringAndClear());
151 void Imp_PutDoubleChar(OUString
& rStr
, const SvXMLUnitConverter
& rConv
, double fValue
,
152 bool bConvertUnits
= false)
154 OUStringBuffer sStringBuffer
;
157 rConv
.convertDouble(sStringBuffer
, fValue
, true);
160 ::sax::Converter::convertDouble(sStringBuffer
, fValue
);
163 rStr
+= OUString(sStringBuffer
.makeStringAndClear());
166 // base class of all 2D transform objects
168 struct ImpSdXMLExpTransObj2DBase
171 ImpSdXMLExpTransObj2DBase(sal_uInt16 nType
)
175 // possible object types for 2D
177 #define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE 0x0000
178 #define IMP_SDXMLEXP_TRANSOBJ2D_SCALE 0x0001
179 #define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE 0x0002
180 #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX 0x0003
181 #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY 0x0004
182 #define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX 0x0005
184 // classes of objects, different sizes
186 struct ImpSdXMLExpTransObj2DRotate
: public ImpSdXMLExpTransObj2DBase
189 ImpSdXMLExpTransObj2DRotate(double fVal
)
190 : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_ROTATE
), mfRotate(fVal
) {}
192 struct ImpSdXMLExpTransObj2DScale
: public ImpSdXMLExpTransObj2DBase
194 ::basegfx::B2DTuple maScale
;
195 ImpSdXMLExpTransObj2DScale(const ::basegfx::B2DTuple
& rNew
)
196 : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SCALE
), maScale(rNew
) {}
198 struct ImpSdXMLExpTransObj2DTranslate
: public ImpSdXMLExpTransObj2DBase
200 ::basegfx::B2DTuple maTranslate
;
201 ImpSdXMLExpTransObj2DTranslate(const ::basegfx::B2DTuple
& rNew
)
202 : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE
), maTranslate(rNew
) {}
204 struct ImpSdXMLExpTransObj2DSkewX
: public ImpSdXMLExpTransObj2DBase
207 ImpSdXMLExpTransObj2DSkewX(double fVal
)
208 : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWX
), mfSkewX(fVal
) {}
210 struct ImpSdXMLExpTransObj2DSkewY
: public ImpSdXMLExpTransObj2DBase
213 ImpSdXMLExpTransObj2DSkewY(double fVal
)
214 : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWY
), mfSkewY(fVal
) {}
216 struct ImpSdXMLExpTransObj2DMatrix
: public ImpSdXMLExpTransObj2DBase
218 ::basegfx::B2DHomMatrix maMatrix
;
219 ImpSdXMLExpTransObj2DMatrix(const ::basegfx::B2DHomMatrix
& rNew
)
220 : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_MATRIX
), maMatrix(rNew
) {}
223 // delete all entries in list
225 void SdXMLImExTransform2D::EmptyList()
227 const sal_uInt32 nCount
= maList
.size();
228 for(sal_uInt32
a(0L); a
< nCount
; a
++)
230 ImpSdXMLExpTransObj2DBase
* pObj
= maList
[a
];
234 case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE
:
236 delete static_cast<ImpSdXMLExpTransObj2DRotate
*>(pObj
);
239 case IMP_SDXMLEXP_TRANSOBJ2D_SCALE
:
241 delete static_cast<ImpSdXMLExpTransObj2DScale
*>(pObj
);
244 case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE
:
246 delete static_cast<ImpSdXMLExpTransObj2DTranslate
*>(pObj
);
249 case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX
:
251 delete static_cast<ImpSdXMLExpTransObj2DSkewX
*>(pObj
);
254 case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY
:
256 delete static_cast<ImpSdXMLExpTransObj2DSkewY
*>(pObj
);
259 case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX
:
261 delete static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
);
266 OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
277 void SdXMLImExTransform2D::AddRotate(double fNew
)
280 maList
.push_back(new ImpSdXMLExpTransObj2DRotate(fNew
));
283 void SdXMLImExTransform2D::AddTranslate(const ::basegfx::B2DTuple
& rNew
)
285 if(!rNew
.equalZero())
286 maList
.push_back(new ImpSdXMLExpTransObj2DTranslate(rNew
));
289 void SdXMLImExTransform2D::AddSkewX(double fNew
)
292 maList
.push_back(new ImpSdXMLExpTransObj2DSkewX(fNew
));
295 // gen string for export
296 const OUString
& SdXMLImExTransform2D::GetExportString(const SvXMLUnitConverter
& rConv
)
299 OUString
aClosingBrace(")");
300 OUString
aEmptySpace(" ");
302 const sal_uInt32 nCount
= maList
.size();
303 for(sal_uInt32
a(0L); a
< nCount
; a
++)
305 ImpSdXMLExpTransObj2DBase
* pObj
= maList
[a
];
308 case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE
:
310 aNewString
+= "rotate (";
311 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DRotate
*>(pObj
)->mfRotate
);
312 aNewString
+= aClosingBrace
;
315 case IMP_SDXMLEXP_TRANSOBJ2D_SCALE
:
317 aNewString
+= "scale (";
318 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DScale
*>(pObj
)->maScale
.getX());
319 aNewString
+= aEmptySpace
;
320 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DScale
*>(pObj
)->maScale
.getY());
321 aNewString
+= aClosingBrace
;
324 case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE
:
326 aNewString
+= "translate (";
327 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DTranslate
*>(pObj
)->maTranslate
.getX(), true);
328 aNewString
+= aEmptySpace
;
329 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DTranslate
*>(pObj
)->maTranslate
.getY(), true);
330 aNewString
+= aClosingBrace
;
333 case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX
:
335 aNewString
+= "skewX (";
336 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DSkewX
*>(pObj
)->mfSkewX
);
337 aNewString
+= aClosingBrace
;
340 case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY
:
342 aNewString
+= "skewY (";
343 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DSkewY
*>(pObj
)->mfSkewY
);
344 aNewString
+= aClosingBrace
;
347 case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX
:
349 aNewString
+= "matrix (";
352 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
)->maMatrix
.get(0, 0));
353 aNewString
+= aEmptySpace
;
356 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
)->maMatrix
.get(1, 0));
357 aNewString
+= aEmptySpace
;
360 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
)->maMatrix
.get(0, 1));
361 aNewString
+= aEmptySpace
;
364 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
)->maMatrix
.get(1, 1));
365 aNewString
+= aEmptySpace
;
368 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
)->maMatrix
.get(0, 2), true);
369 aNewString
+= aEmptySpace
;
372 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
)->maMatrix
.get(1, 2), true);
374 aNewString
+= aClosingBrace
;
379 OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
384 // if not the last entry, add one space to next tag
385 if(a
+ 1UL != maList
.size())
387 aNewString
+= aEmptySpace
;
391 // fill string form OUString
392 msString
= aNewString
;
397 // sets new string, parses it and generates entries
398 void SdXMLImExTransform2D::SetString(const OUString
& rNew
, const SvXMLUnitConverter
& rConv
)
403 if(!msString
.isEmpty())
405 const OUString
aStr(msString
.getStr(), (sal_uInt16
)msString
.getLength());
406 const sal_Int32
nLen(aStr
.getLength());
408 const OUString
aString_rotate( "rotate" );
409 const OUString
aString_scale( "scale" );
410 const OUString
aString_translate( "translate" );
411 const OUString
aString_skewX( "skewX" );
412 const OUString
aString_skewY( "skewY" );
413 const OUString
aString_matrix( "matrix" );
420 Imp_SkipSpaces(aStr
, nPos
, nLen
);
425 if(nPos
== aStr
.indexOf(aString_rotate
, nPos
))
429 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
430 fValue
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, fValue
);
432 maList
.push_back(new ImpSdXMLExpTransObj2DRotate(fValue
));
434 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
436 else if(nPos
== aStr
.indexOf(aString_scale
, nPos
))
438 ::basegfx::B2DTuple
aValue(1.0, 1.0);
440 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
441 aValue
.setX(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getX()));
442 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
443 aValue
.setY(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getY()));
445 if(aValue
.getX() != 1.0 || aValue
.getY() != 1.0)
446 maList
.push_back(new ImpSdXMLExpTransObj2DScale(aValue
));
448 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
450 else if(nPos
== aStr
.indexOf(aString_translate
, nPos
))
452 ::basegfx::B2DTuple aValue
;
454 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
455 aValue
.setX(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getX(), true));
456 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
457 aValue
.setY(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getY(), true));
459 if(!aValue
.equalZero())
460 maList
.push_back(new ImpSdXMLExpTransObj2DTranslate(aValue
));
462 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
464 else if(nPos
== aStr
.indexOf(aString_skewX
, nPos
))
468 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
469 fValue
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, fValue
);
471 maList
.push_back(new ImpSdXMLExpTransObj2DSkewX(fValue
));
473 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
475 else if(nPos
== aStr
.indexOf(aString_skewY
, nPos
))
479 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
480 fValue
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, fValue
);
482 maList
.push_back(new ImpSdXMLExpTransObj2DSkewY(fValue
));
484 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
486 else if(nPos
== aStr
.indexOf(aString_matrix
, nPos
))
488 ::basegfx::B2DHomMatrix aValue
;
491 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
494 aValue
.set(0, 0, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(0, 0)));
495 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
498 aValue
.set(1, 0, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(1, 0)));
499 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
502 aValue
.set(0, 1, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(0, 1)));
503 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
506 aValue
.set(1, 1, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(1, 1)));
507 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
510 aValue
.set(0, 2, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(0, 2), true));
511 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
514 aValue
.set(1, 2, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(1, 2), true));
515 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
517 if(!aValue
.isIdentity())
518 maList
.push_back(new ImpSdXMLExpTransObj2DMatrix(aValue
));
520 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
531 void SdXMLImExTransform2D::GetFullTransform(::basegfx::B2DHomMatrix
& rFullTrans
)
533 rFullTrans
.identity();
535 const sal_uInt32 nCount
= maList
.size();
536 for(sal_uInt32
a(0L); a
< nCount
; a
++)
538 ImpSdXMLExpTransObj2DBase
* pObj
= maList
[a
];
541 case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE
:
544 // mfRotate is mathematically wrong oriented since we export/import the angle
545 // values mirrored. This error is fixed in the API, but not yet in the FileFormat.
546 // For the FileFormat there is a follow-up task (#i78698#) to fix this in the next
547 // ODF FileFormat version. For now - to emulate the old behaviour - it is necessary
548 // to mirror the value here
549 rFullTrans
.rotate(static_cast<ImpSdXMLExpTransObj2DRotate
*>(pObj
)->mfRotate
* -1.0);
552 case IMP_SDXMLEXP_TRANSOBJ2D_SCALE
:
554 const ::basegfx::B2DTuple
& rScale
= static_cast<ImpSdXMLExpTransObj2DScale
*>(pObj
)->maScale
;
555 rFullTrans
.scale(rScale
.getX(), rScale
.getY());
558 case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE
:
560 const ::basegfx::B2DTuple
& rTranslate
= static_cast<ImpSdXMLExpTransObj2DTranslate
*>(pObj
)->maTranslate
;
561 rFullTrans
.translate(rTranslate
.getX(), rTranslate
.getY());
564 case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX
:
566 rFullTrans
.shearX(tan(static_cast<ImpSdXMLExpTransObj2DSkewX
*>(pObj
)->mfSkewX
));
569 case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY
:
571 rFullTrans
.shearY(tan(static_cast<ImpSdXMLExpTransObj2DSkewY
*>(pObj
)->mfSkewY
));
574 case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX
:
576 rFullTrans
*= static_cast<ImpSdXMLExpTransObj2DMatrix
*>(pObj
)->maMatrix
;
581 OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
588 // base class of all 3D transform objects
590 struct ImpSdXMLExpTransObj3DBase
593 ImpSdXMLExpTransObj3DBase(sal_uInt16 nType
)
597 // possible object types for 3D
599 #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X 0x0000
600 #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y 0x0001
601 #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z 0x0002
602 #define IMP_SDXMLEXP_TRANSOBJ3D_SCALE 0x0003
603 #define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE 0x0004
604 #define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX 0x0005
606 // classes of objects, different sizes
608 struct ImpSdXMLExpTransObj3DRotateX
: public ImpSdXMLExpTransObj3DBase
611 ImpSdXMLExpTransObj3DRotateX(double fVal
)
612 : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X
), mfRotateX(fVal
) {}
614 struct ImpSdXMLExpTransObj3DRotateY
: public ImpSdXMLExpTransObj3DBase
617 ImpSdXMLExpTransObj3DRotateY(double fVal
)
618 : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y
), mfRotateY(fVal
) {}
620 struct ImpSdXMLExpTransObj3DRotateZ
: public ImpSdXMLExpTransObj3DBase
623 ImpSdXMLExpTransObj3DRotateZ(double fVal
)
624 : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z
), mfRotateZ(fVal
) {}
626 struct ImpSdXMLExpTransObj3DScale
: public ImpSdXMLExpTransObj3DBase
628 ::basegfx::B3DTuple maScale
;
629 ImpSdXMLExpTransObj3DScale(const ::basegfx::B3DTuple
& rNew
)
630 : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_SCALE
), maScale(rNew
) {}
632 struct ImpSdXMLExpTransObj3DTranslate
: public ImpSdXMLExpTransObj3DBase
634 ::basegfx::B3DTuple maTranslate
;
635 ImpSdXMLExpTransObj3DTranslate(const ::basegfx::B3DTuple
& rNew
)
636 : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE
), maTranslate(rNew
) {}
638 struct ImpSdXMLExpTransObj3DMatrix
: public ImpSdXMLExpTransObj3DBase
640 ::basegfx::B3DHomMatrix maMatrix
;
641 ImpSdXMLExpTransObj3DMatrix(const ::basegfx::B3DHomMatrix
& rNew
)
642 : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_MATRIX
), maMatrix(rNew
) {}
645 // delete all entries in list
647 void SdXMLImExTransform3D::EmptyList()
649 const sal_uInt32 nCount
= maList
.size();
650 for(sal_uInt32
a(0L); a
< nCount
; a
++)
652 ImpSdXMLExpTransObj3DBase
* pObj
= maList
[a
];
656 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X
:
658 delete static_cast<ImpSdXMLExpTransObj3DRotateX
*>(pObj
);
661 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y
:
663 delete static_cast<ImpSdXMLExpTransObj3DRotateY
*>(pObj
);
666 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z
:
668 delete static_cast<ImpSdXMLExpTransObj3DRotateZ
*>(pObj
);
671 case IMP_SDXMLEXP_TRANSOBJ3D_SCALE
:
673 delete static_cast<ImpSdXMLExpTransObj3DScale
*>(pObj
);
676 case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE
:
678 delete static_cast<ImpSdXMLExpTransObj3DTranslate
*>(pObj
);
681 case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX
:
683 delete static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
);
688 OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
699 void SdXMLImExTransform3D::AddMatrix(const ::basegfx::B3DHomMatrix
& rNew
)
701 if(!rNew
.isIdentity())
702 maList
.push_back(new ImpSdXMLExpTransObj3DMatrix(rNew
));
705 void SdXMLImExTransform3D::AddHomogenMatrix(const drawing::HomogenMatrix
& xHomMat
)
707 ::basegfx::B3DHomMatrix aExportMatrix
;
709 aExportMatrix
.set(0, 0, xHomMat
.Line1
.Column1
);
710 aExportMatrix
.set(0, 1, xHomMat
.Line1
.Column2
);
711 aExportMatrix
.set(0, 2, xHomMat
.Line1
.Column3
);
712 aExportMatrix
.set(0, 3, xHomMat
.Line1
.Column4
);
713 aExportMatrix
.set(1, 0, xHomMat
.Line2
.Column1
);
714 aExportMatrix
.set(1, 1, xHomMat
.Line2
.Column2
);
715 aExportMatrix
.set(1, 2, xHomMat
.Line2
.Column3
);
716 aExportMatrix
.set(1, 3, xHomMat
.Line2
.Column4
);
717 aExportMatrix
.set(2, 0, xHomMat
.Line3
.Column1
);
718 aExportMatrix
.set(2, 1, xHomMat
.Line3
.Column2
);
719 aExportMatrix
.set(2, 2, xHomMat
.Line3
.Column3
);
720 aExportMatrix
.set(2, 3, xHomMat
.Line3
.Column4
);
722 AddMatrix(aExportMatrix
);
725 // gen string for export
726 const OUString
& SdXMLImExTransform3D::GetExportString(const SvXMLUnitConverter
& rConv
)
729 OUString
aClosingBrace(")");
730 OUString
aEmptySpace(" ");
732 const sal_uInt32 nCount
= maList
.size();
733 for(sal_uInt32
a(0L); a
< nCount
; a
++)
735 ImpSdXMLExpTransObj3DBase
* pObj
= maList
[a
];
738 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X
:
740 aNewString
+= "rotatex (";
741 Imp_PutDoubleChar(aNewString
, rConv
, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateX
*>(pObj
)->mfRotateX
) );
742 aNewString
+= aClosingBrace
;
745 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y
:
747 aNewString
+= "rotatey (";
748 Imp_PutDoubleChar(aNewString
, rConv
, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateY
*>(pObj
)->mfRotateY
) );
749 aNewString
+= aClosingBrace
;
752 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z
:
754 aNewString
+= "rotatez (";
755 Imp_PutDoubleChar(aNewString
, rConv
, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateZ
*>(pObj
)->mfRotateZ
) );
756 aNewString
+= aClosingBrace
;
759 case IMP_SDXMLEXP_TRANSOBJ3D_SCALE
:
761 aNewString
+= "scale (";
762 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DScale
*>(pObj
)->maScale
.getX());
763 aNewString
+= aEmptySpace
;
764 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DScale
*>(pObj
)->maScale
.getY());
765 aNewString
+= aEmptySpace
;
766 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DScale
*>(pObj
)->maScale
.getZ());
767 aNewString
+= aClosingBrace
;
770 case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE
:
772 aNewString
+= "translate (";
773 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DTranslate
*>(pObj
)->maTranslate
.getX(), true);
774 aNewString
+= aEmptySpace
;
775 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DTranslate
*>(pObj
)->maTranslate
.getY(), true);
776 aNewString
+= aEmptySpace
;
777 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DTranslate
*>(pObj
)->maTranslate
.getZ(), true);
778 aNewString
+= aClosingBrace
;
781 case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX
:
783 aNewString
+= "matrix (";
786 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(0, 0));
787 aNewString
+= aEmptySpace
;
790 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(1, 0));
791 aNewString
+= aEmptySpace
;
794 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(2, 0));
795 aNewString
+= aEmptySpace
;
798 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(0, 1));
799 aNewString
+= aEmptySpace
;
802 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(1, 1));
803 aNewString
+= aEmptySpace
;
806 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(2, 1));
807 aNewString
+= aEmptySpace
;
810 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(0, 2));
811 aNewString
+= aEmptySpace
;
814 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(1, 2));
815 aNewString
+= aEmptySpace
;
818 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(2, 2));
819 aNewString
+= aEmptySpace
;
822 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(0, 3), true);
823 aNewString
+= aEmptySpace
;
826 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(1, 3), true);
827 aNewString
+= aEmptySpace
;
830 Imp_PutDoubleChar(aNewString
, rConv
, static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
.get(2, 3), true);
832 aNewString
+= aClosingBrace
;
837 OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
842 // if not the last entry, add one space to next tag
843 if(a
+ 1UL != maList
.size())
845 aNewString
+= aEmptySpace
;
849 // fill string form OUString
850 msString
= aNewString
;
855 // for Import: constructor with string, parses it and generates entries
856 SdXMLImExTransform3D::SdXMLImExTransform3D(const OUString
& rNew
, const SvXMLUnitConverter
& rConv
)
858 SetString(rNew
, rConv
);
861 // sets new string, parses it and generates entries
862 void SdXMLImExTransform3D::SetString(const OUString
& rNew
, const SvXMLUnitConverter
& rConv
)
867 if(!msString
.isEmpty())
869 const OUString
aStr(msString
.getStr(), (sal_uInt16
)msString
.getLength());
870 const sal_Int32
nLen(aStr
.getLength());
872 const OUString
aString_rotatex( "rotatex" );
873 const OUString
aString_rotatey( "rotatey" );
874 const OUString
aString_rotatez( "rotatez" );
875 const OUString
aString_scale( "scale" );
876 const OUString
aString_translate( "translate" );
877 const OUString
aString_matrix( "matrix" );
884 Imp_SkipSpaces(aStr
, nPos
, nLen
);
889 if(nPos
== aStr
.indexOf(aString_rotatex
, nPos
))
894 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
895 fValue
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, fValue
);
897 maList
.push_back(new ImpSdXMLExpTransObj3DRotateX(basegfx::deg2rad(fValue
)));
899 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
901 else if(nPos
== aStr
.indexOf(aString_rotatey
, nPos
))
906 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
907 fValue
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, fValue
);
909 maList
.push_back(new ImpSdXMLExpTransObj3DRotateY(basegfx::deg2rad(fValue
)));
911 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
913 else if(nPos
== aStr
.indexOf(aString_rotatez
, nPos
))
918 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
919 fValue
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, fValue
);
921 maList
.push_back(new ImpSdXMLExpTransObj3DRotateZ(basegfx::deg2rad(fValue
)));
923 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
925 else if(nPos
== aStr
.indexOf(aString_scale
, nPos
))
927 ::basegfx::B3DTuple
aValue(1.0, 1.0, 1.0);
930 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
931 aValue
.setX(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getX()));
932 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
933 aValue
.setY(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getY()));
934 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
935 aValue
.setZ(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getZ()));
937 if(1.0 != aValue
.getX() || 1.0 != aValue
.getY() || 1.0 != aValue
.getZ())
938 maList
.push_back(new ImpSdXMLExpTransObj3DScale(aValue
));
940 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
942 else if(nPos
== aStr
.indexOf(aString_translate
, nPos
))
944 ::basegfx::B3DTuple aValue
;
947 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
948 aValue
.setX(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getX(), true));
949 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
950 aValue
.setY(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getY(), true));
951 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
952 aValue
.setZ(Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.getZ(), true));
954 if(!aValue
.equalZero())
955 maList
.push_back(new ImpSdXMLExpTransObj3DTranslate(aValue
));
957 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
959 else if(nPos
== aStr
.indexOf(aString_matrix
, nPos
))
961 ::basegfx::B3DHomMatrix aValue
;
964 Imp_SkipSpacesAndOpeningBraces(aStr
, nPos
, nLen
);
967 aValue
.set(0, 0, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(0, 0)));
968 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
971 aValue
.set(1, 0, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(1, 0)));
972 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
975 aValue
.set(2, 0, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(2, 0)));
976 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
979 aValue
.set(0, 1, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(0, 1)));
980 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
983 aValue
.set(1, 1, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(1, 1)));
984 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
987 aValue
.set(2, 1, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(2, 1)));
988 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
991 aValue
.set(0, 2, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(0, 2)));
992 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
995 aValue
.set(1, 2, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(1, 2)));
996 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
999 aValue
.set(2, 2, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(2, 2)));
1000 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
1003 aValue
.set(0, 3, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(0, 3), true));
1004 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
1007 aValue
.set(1, 3, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(1, 3), true));
1008 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
1011 aValue
.set(2, 3, Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, aValue
.get(2, 3), true));
1012 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
1014 if(!aValue
.isIdentity())
1015 maList
.push_back(new ImpSdXMLExpTransObj3DMatrix(aValue
));
1017 Imp_SkipSpacesAndClosingBraces(aStr
, nPos
, nLen
);
1028 bool SdXMLImExTransform3D::GetFullHomogenTransform(com::sun::star::drawing::HomogenMatrix
& xHomMat
)
1030 ::basegfx::B3DHomMatrix aFullTransform
;
1031 GetFullTransform(aFullTransform
);
1033 if(!aFullTransform
.isIdentity())
1035 xHomMat
.Line1
.Column1
= aFullTransform
.get(0, 0);
1036 xHomMat
.Line1
.Column2
= aFullTransform
.get(0, 1);
1037 xHomMat
.Line1
.Column3
= aFullTransform
.get(0, 2);
1038 xHomMat
.Line1
.Column4
= aFullTransform
.get(0, 3);
1040 xHomMat
.Line2
.Column1
= aFullTransform
.get(1, 0);
1041 xHomMat
.Line2
.Column2
= aFullTransform
.get(1, 1);
1042 xHomMat
.Line2
.Column3
= aFullTransform
.get(1, 2);
1043 xHomMat
.Line2
.Column4
= aFullTransform
.get(1, 3);
1045 xHomMat
.Line3
.Column1
= aFullTransform
.get(2, 0);
1046 xHomMat
.Line3
.Column2
= aFullTransform
.get(2, 1);
1047 xHomMat
.Line3
.Column3
= aFullTransform
.get(2, 2);
1048 xHomMat
.Line3
.Column4
= aFullTransform
.get(2, 3);
1050 xHomMat
.Line4
.Column1
= aFullTransform
.get(3, 0);
1051 xHomMat
.Line4
.Column2
= aFullTransform
.get(3, 1);
1052 xHomMat
.Line4
.Column3
= aFullTransform
.get(3, 2);
1053 xHomMat
.Line4
.Column4
= aFullTransform
.get(3, 3);
1061 void SdXMLImExTransform3D::GetFullTransform(::basegfx::B3DHomMatrix
& rFullTrans
)
1063 rFullTrans
.identity();
1065 const sal_uInt32 nCount
= maList
.size();
1066 for(sal_uInt32
a(0L); a
< nCount
; a
++)
1068 ImpSdXMLExpTransObj3DBase
* pObj
= maList
[a
];
1069 switch(pObj
->mnType
)
1071 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X
:
1073 rFullTrans
.rotate(static_cast<ImpSdXMLExpTransObj3DRotateX
*>(pObj
)->mfRotateX
, 0.0, 0.0);
1076 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y
:
1078 rFullTrans
.rotate(0.0, static_cast<ImpSdXMLExpTransObj3DRotateY
*>(pObj
)->mfRotateY
, 0.0);
1081 case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z
:
1083 rFullTrans
.rotate(0.0, 0.0, static_cast<ImpSdXMLExpTransObj3DRotateZ
*>(pObj
)->mfRotateZ
);
1086 case IMP_SDXMLEXP_TRANSOBJ3D_SCALE
:
1088 const ::basegfx::B3DTuple
& rScale
= static_cast<ImpSdXMLExpTransObj3DScale
*>(pObj
)->maScale
;
1089 rFullTrans
.scale(rScale
.getX(), rScale
.getY(), rScale
.getZ());
1092 case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE
:
1094 const ::basegfx::B3DTuple
& rTranslate
= static_cast<ImpSdXMLExpTransObj3DTranslate
*>(pObj
)->maTranslate
;
1095 rFullTrans
.translate(rTranslate
.getX(), rTranslate
.getY(), rTranslate
.getZ());
1098 case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX
:
1100 rFullTrans
*= static_cast<ImpSdXMLExpTransObj3DMatrix
*>(pObj
)->maMatrix
;
1105 OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
1112 SdXMLImExViewBox::SdXMLImExViewBox(double fX
, double fY
, double fW
, double fH
)
1120 // #100617# Asked vincent hardy: svg:viewBox values may be double precision.
1121 SdXMLImExViewBox::SdXMLImExViewBox(const OUString
& rNew
, const SvXMLUnitConverter
& rConv
)
1128 if(!msString
.isEmpty())
1130 const OUString
aStr(msString
.getStr(), (sal_uInt16
)msString
.getLength());
1131 const sal_Int32
nLen(aStr
.getLength());
1134 // skip starting spaces
1135 Imp_SkipSpaces(aStr
, nPos
, nLen
);
1137 // get mX, #100617# be prepared for doubles
1138 mfX
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, mfX
);
1140 // skip spaces and commas
1141 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
1143 // get mY, #100617# be prepared for doubles
1144 mfY
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, mfY
);
1146 // skip spaces and commas
1147 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
1149 // get mW, #100617# be prepared for doubles
1150 mfW
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, mfW
);
1152 // skip spaces and commas
1153 Imp_SkipSpacesAndCommas(aStr
, nPos
, nLen
);
1155 // get mH, #100617# be prepared for doubles
1156 mfH
= Imp_GetDoubleChar(aStr
, nPos
, nLen
, rConv
, mfH
);
1160 const OUString
& SdXMLImExViewBox::GetExportString()
1162 OUString aNewString
;
1163 OUString
aEmptySpace(" ");
1165 Imp_PutDoubleChar(aNewString
, mfX
);
1166 aNewString
+= aEmptySpace
;
1168 Imp_PutDoubleChar(aNewString
, mfY
);
1169 aNewString
+= aEmptySpace
;
1171 Imp_PutDoubleChar(aNewString
, mfW
);
1172 aNewString
+= aEmptySpace
;
1174 Imp_PutDoubleChar(aNewString
, mfH
);
1177 msString
= aNewString
;
1182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */