LibreOffice Module xmloff (master) 1
xexptran.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <string_view>
23
24#include <utility>
25#include <xexptran.hxx>
26#include <rtl/ustrbuf.hxx>
27#include <osl/diagnose.h>
29#include <xmloff/xmluconv.hxx>
36
37using namespace ::com::sun::star;
38
39using std::make_unique;
40
41// parsing help functions for simple chars
42static void Imp_SkipSpaces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
43{
44 while(rPos < nLen
45 && ' ' == rStr[rPos])
46 rPos++;
47}
48
49static void Imp_SkipSpacesAndOpeningBraces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
50{
51 while(rPos < nLen
52 && (' ' == rStr[rPos] || '(' == rStr[rPos]))
53 rPos++;
54}
55
56static void Imp_SkipSpacesAndCommas(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
57{
58 while(rPos < nLen
59 && (' ' == rStr[rPos] || ',' == rStr[rPos]))
60 rPos++;
61}
62
63static void Imp_SkipSpacesAndClosingBraces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
64{
65 while(rPos < nLen
66 && (' ' == rStr[rPos] || ')' == rStr[rPos]))
67 rPos++;
68}
69
70// parsing help functions for integer numbers
71
72static bool Imp_IsOnUnitChar(std::u16string_view rStr, const sal_Int32 nPos)
73{
74 sal_Unicode aChar(rStr[nPos]);
75
76 return ('a' <= aChar && 'z' >= aChar)
77 || ('A' <= aChar && 'Z' >= aChar)
78 || '%' == aChar;
79}
80
81static double Imp_GetDoubleChar(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen,
82 const SvXMLUnitConverter& rConv, double fRetval, bool bLookForUnits = false)
83{
84 sal_Unicode aChar(rStr[rPos]);
85 OUStringBuffer sNumberString(32);
86
87 if('+' == aChar || '-' == aChar)
88 {
89 sNumberString.append(rStr[rPos]);
90 ++rPos;
91 aChar = rPos >= nLen ? 0 : rStr[rPos];
92 }
93
94 while(('0' <= aChar && '9' >= aChar)
95 || '.' == aChar)
96 {
97 sNumberString.append(rStr[rPos]);
98 ++rPos;
99 aChar = rPos >= nLen ? 0 : rStr[rPos];
100 }
101
102 if('e' == aChar || 'E' == aChar)
103 {
104 sNumberString.append(rStr[rPos]);
105 ++rPos;
106 aChar = rPos >= nLen ? 0 : rStr[rPos];
107
108 if('+' == aChar || '-' == aChar)
109 {
110 sNumberString.append(rStr[rPos]);
111 ++rPos;
112 aChar = rPos >= nLen ? 0 : rStr[rPos];
113 }
114
115 while('0' <= aChar && '9' >= aChar)
116 {
117 sNumberString.append(rStr[rPos]);
118 ++rPos;
119 aChar = rPos >= nLen ? 0 : rStr[rPos];
120 }
121 }
122
123 if(bLookForUnits)
124 {
125 Imp_SkipSpaces(rStr, rPos, nLen);
126 while(rPos < nLen && Imp_IsOnUnitChar(rStr, rPos))
127 sNumberString.append(rStr[rPos++]);
128 }
129
130 if(!sNumberString.isEmpty())
131 {
132 if(bLookForUnits)
133 rConv.convertDouble(fRetval, sNumberString);
134 else
135 {
136 ::sax::Converter::convertDouble(fRetval, sNumberString);
137 }
138 }
139
140 return fRetval;
141}
142
143static void Imp_PutDoubleChar(OUString& rStr, double fValue)
144{
145 OUStringBuffer sStringBuffer;
146 ::sax::Converter::convertDouble(sStringBuffer, fValue);
147 rStr += sStringBuffer;
148}
149
150static void Imp_PutDoubleChar(OUStringBuffer& rStr, const SvXMLUnitConverter& rConv, double fValue,
151 bool bConvertUnits = false)
152{
153 OUStringBuffer sStringBuffer;
154
155 if(bConvertUnits)
156 rConv.convertDouble(sStringBuffer, fValue);
157 else
158 {
159 ::sax::Converter::convertDouble(sStringBuffer, fValue);
160 }
161
162 rStr.append(sStringBuffer);
163}
164
165// base class of all 2D transform objects
166
168{
169 sal_uInt16 mnType;
170 explicit ImpSdXMLExpTransObj2DBase(sal_uInt16 nType)
171 : mnType(nType) {}
172};
173
174// possible object types for 2D
175
176#define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE 0x0000
177#define IMP_SDXMLEXP_TRANSOBJ2D_SCALE 0x0001
178#define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE 0x0002
179#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX 0x0003
180#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY 0x0004
181#define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX 0x0005
182
183// classes of objects, different sizes
184
185namespace {
186
187struct ImpSdXMLExpTransObj2DRotate : public ImpSdXMLExpTransObj2DBase
188{
189 double mfRotate;
190 explicit ImpSdXMLExpTransObj2DRotate(double fVal)
192};
193struct ImpSdXMLExpTransObj2DScale : public ImpSdXMLExpTransObj2DBase
194{
195 ::basegfx::B2DTuple maScale;
196 explicit ImpSdXMLExpTransObj2DScale(const ::basegfx::B2DTuple& rNew)
198};
199struct ImpSdXMLExpTransObj2DTranslate : public ImpSdXMLExpTransObj2DBase
200{
201 ::basegfx::B2DTuple maTranslate;
202 explicit ImpSdXMLExpTransObj2DTranslate(const ::basegfx::B2DTuple& rNew)
204};
205struct ImpSdXMLExpTransObj2DSkewX : public ImpSdXMLExpTransObj2DBase
206{
207 double mfSkewX;
208 explicit ImpSdXMLExpTransObj2DSkewX(double fVal)
210};
211struct ImpSdXMLExpTransObj2DSkewY : public ImpSdXMLExpTransObj2DBase
212{
213 double mfSkewY;
214 explicit ImpSdXMLExpTransObj2DSkewY(double fVal)
216};
217struct ImpSdXMLExpTransObj2DMatrix : public ImpSdXMLExpTransObj2DBase
218{
220 explicit ImpSdXMLExpTransObj2DMatrix(::basegfx::B2DHomMatrix aNew)
222};
223
224}
225
226// add members
227
229{
230 if(fNew != 0.0)
231 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DRotate>(fNew));
232}
233
234void SdXMLImExTransform2D::AddTranslate(const ::basegfx::B2DTuple& rNew)
235{
236 if(!rNew.equalZero())
237 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DTranslate>(rNew));
238}
239
241{
242 if(fNew != 0.0)
243 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewX>(fNew));
244}
245
246// gen string for export
248{
249 OUStringBuffer aNewString;
250 OUString aClosingBrace(")");
251 OUString aEmptySpace(" ");
252
253 const sal_uInt32 nCount = maList.size();
254 for(sal_uInt32 a(0); a < nCount; a++)
255 {
256 ImpSdXMLExpTransObj2DBase* pObj = maList[a].get();
257 switch(pObj->mnType)
258 {
260 {
261 aNewString.append("rotate (");
262 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DRotate*>(pObj)->mfRotate);
263 aNewString.append(aClosingBrace);
264 break;
265 }
267 {
268 aNewString.append("scale (");
269 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale.getX());
270 aNewString.append(aEmptySpace);
271 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale.getY());
272 aNewString.append(aClosingBrace);
273 break;
274 }
276 {
277 aNewString.append("translate (");
278 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate.getX(), true);
279 aNewString.append(aEmptySpace);
280 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate.getY(), true);
281 aNewString.append(aClosingBrace);
282 break;
283 }
285 {
286 aNewString.append("skewX (");
287 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX);
288 aNewString.append(aClosingBrace);
289 break;
290 }
292 {
293 aNewString.append("skewY (");
294 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY);
295 aNewString.append(aClosingBrace);
296 break;
297 }
299 {
300 aNewString.append("matrix (");
301
302 // a
303 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 0));
304 aNewString.append(aEmptySpace);
305
306 // b
307 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 0));
308 aNewString.append(aEmptySpace);
309
310 // c
311 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 1));
312 aNewString.append(aEmptySpace);
313
314 // d
315 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 1));
316 aNewString.append(aEmptySpace);
317
318 // e
319 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 2), true);
320 aNewString.append(aEmptySpace);
321
322 // f
323 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 2), true);
324
325 aNewString.append(aClosingBrace);
326 break;
327 }
328 default :
329 {
330 OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
331 break;
332 }
333 }
334
335 // if not the last entry, add one space to next tag
336 if(a + 1 != maList.size())
337 {
338 aNewString.append(aEmptySpace);
339 }
340 }
341
342 // fill string form OUString
343 msString = aNewString.makeStringAndClear();
344
345 return msString;
346}
347
348// sets new string, parses it and generates entries
349void SdXMLImExTransform2D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
350{
351 msString = rNew;
352 maList.clear();
353
354 if(msString.isEmpty())
355 return;
356
357 const OUString aStr = msString;
358 const sal_Int32 nLen(aStr.getLength());
359
360 static const OUStringLiteral aString_rotate( u"rotate" );
361 static const OUStringLiteral aString_scale( u"scale" );
362 static const OUStringLiteral aString_translate( u"translate" );
363 static const OUStringLiteral aString_skewX( u"skewX" );
364 static const OUStringLiteral aString_skewY( u"skewY" );
365 static const OUStringLiteral aString_matrix( u"matrix" );
366
367 sal_Int32 nPos(0);
368
369 while(nPos < nLen)
370 {
371 // skip spaces
372 Imp_SkipSpaces(aStr, nPos, nLen);
373
374 // look for tag
375 if(nPos < nLen)
376 {
377 if(nPos == aStr.indexOf(aString_rotate, nPos))
378 {
379 double fValue(0.0);
380 nPos += 6;
382 fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
383 if(fValue != 0.0)
384 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DRotate>(fValue));
385
387 }
388 else if(nPos == aStr.indexOf(aString_scale, nPos))
389 {
390 ::basegfx::B2DTuple aValue(1.0, 1.0);
391 nPos += 5;
393 aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
395 aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
396
397 if(aValue.getX() != 1.0 || aValue.getY() != 1.0)
398 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DScale>(aValue));
399
401 }
402 else if(nPos == aStr.indexOf(aString_translate, nPos))
403 {
404 ::basegfx::B2DTuple aValue;
405 nPos += 9;
407 aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
409 aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
410
411 if(!aValue.equalZero())
412 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DTranslate>(aValue));
413
415 }
416 else if(nPos == aStr.indexOf(aString_skewX, nPos))
417 {
418 double fValue(0.0);
419 nPos += 5;
421 fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
422 if(fValue != 0.0)
423 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewX>(fValue));
424
426 }
427 else if(nPos == aStr.indexOf(aString_skewY, nPos))
428 {
429 double fValue(0.0);
430 nPos += 5;
432 fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
433 if(fValue != 0.0)
434 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewY>(fValue));
435
437 }
438 else if(nPos == aStr.indexOf(aString_matrix, nPos))
439 {
441
442 nPos += 6;
444
445 // a
446 aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
448
449 // b
450 aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
452
453 // c
454 aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
456
457 // d
458 aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
460
461 // e
462 aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2), true));
464
465 // f
466 aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2), true));
468
469 if(!aValue.isIdentity())
470 maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DMatrix>(aValue));
471
473 }
474 else
475 {
476 nPos++;
477 }
478 }
479 }
480}
481
483{
484 rFullTrans.identity();
485
486 const sal_uInt32 nCount = maList.size();
487 for(sal_uInt32 a(0); a < nCount; a++)
488 {
489 ImpSdXMLExpTransObj2DBase* pObj = maList[a].get();
490 switch(pObj->mnType)
491 {
493 {
494 // #i78696#
495 // mfRotate is mathematically wrong oriented since we export/import the angle
496 // values mirrored. This error is fixed in the API, but not yet in the FileFormat.
497 // For the FileFormat there is a follow-up task (#i78698#) to fix this in the next
498 // ODF FileFormat version. For now - to emulate the old behaviour - it is necessary
499 // to mirror the value here
500 rFullTrans.rotate(static_cast<ImpSdXMLExpTransObj2DRotate*>(pObj)->mfRotate * -1.0);
501 break;
502 }
504 {
505 const ::basegfx::B2DTuple& rScale = static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale;
506 rFullTrans.scale(rScale.getX(), rScale.getY());
507 break;
508 }
510 {
511 const ::basegfx::B2DTuple& rTranslate = static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate;
512 rFullTrans.translate(rTranslate.getX(), rTranslate.getY());
513 break;
514 }
516 {
517 // For to get a mathematical correct matrix from already existing documents,
518 // mirror the value here. ODF spec is unclear about direction.
519 rFullTrans.shearX(-tan(static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX));
520 break;
521 }
523 {
524 // LibreOffice does not write skewY, OOo neither. Such files are foreign documents
525 // or manually set transformations. OOo had used the value as -tan(value) before
526 // errors were introduced, Scribus 1.5.4 uses it as -tan(value) too, MS Office does
527 // not shear at all. ODF spec is unclear about direction.
528 rFullTrans.shearY(-tan(static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY));
529 break;
530 }
532 {
533 rFullTrans *= static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix;
534 break;
535 }
536 default :
537 {
538 OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
539 break;
540 }
541 }
542 }
543}
544
545// base class of all 3D transform objects
546
548{
549 sal_uInt16 mnType;
550 explicit ImpSdXMLExpTransObj3DBase(sal_uInt16 nType)
551 : mnType(nType) {}
552};
553
554// possible object types for 3D
555
556#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X 0x0000
557#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y 0x0001
558#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z 0x0002
559#define IMP_SDXMLEXP_TRANSOBJ3D_SCALE 0x0003
560#define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE 0x0004
561#define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX 0x0005
562
563// classes of objects, different sizes
564
565namespace {
566
567struct ImpSdXMLExpTransObj3DRotateX : public ImpSdXMLExpTransObj3DBase
568{
569 double mfRotateX;
570 explicit ImpSdXMLExpTransObj3DRotateX(double fVal)
572};
573struct ImpSdXMLExpTransObj3DRotateY : public ImpSdXMLExpTransObj3DBase
574{
575 double mfRotateY;
576 explicit ImpSdXMLExpTransObj3DRotateY(double fVal)
578};
579struct ImpSdXMLExpTransObj3DRotateZ : public ImpSdXMLExpTransObj3DBase
580{
581 double mfRotateZ;
582 explicit ImpSdXMLExpTransObj3DRotateZ(double fVal)
584};
585struct ImpSdXMLExpTransObj3DScale : public ImpSdXMLExpTransObj3DBase
586{
587 ::basegfx::B3DTuple maScale;
588 explicit ImpSdXMLExpTransObj3DScale(const ::basegfx::B3DTuple& rNew)
590};
591struct ImpSdXMLExpTransObj3DTranslate : public ImpSdXMLExpTransObj3DBase
592{
593 ::basegfx::B3DTuple maTranslate;
594 explicit ImpSdXMLExpTransObj3DTranslate(const ::basegfx::B3DTuple& rNew)
596};
597struct ImpSdXMLExpTransObj3DMatrix : public ImpSdXMLExpTransObj3DBase
598{
600 explicit ImpSdXMLExpTransObj3DMatrix(::basegfx::B3DHomMatrix aNew)
602};
603
604}
605
606// add members
607
608void SdXMLImExTransform3D::AddMatrix(const ::basegfx::B3DHomMatrix& rNew)
609{
610 if(!rNew.isIdentity())
611 maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DMatrix>(rNew));
612}
613
614void SdXMLImExTransform3D::AddHomogenMatrix(const drawing::HomogenMatrix& xHomMat)
615{
617}
618
619// gen string for export
621{
622 OUStringBuffer aNewString;
623 OUString aClosingBrace(")");
624 OUString aEmptySpace(" ");
625
626 const sal_uInt32 nCount = maList.size();
627 for(sal_uInt32 a(0); a < nCount; a++)
628 {
629 ImpSdXMLExpTransObj3DBase* pObj = maList[a].get();
630 switch(pObj->mnType)
631 {
633 {
634 aNewString.append("rotatex (");
635 Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateX*>(pObj)->mfRotateX) );
636 aNewString.append(aClosingBrace);
637 break;
638 }
640 {
641 aNewString.append("rotatey (");
642 Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateY*>(pObj)->mfRotateY) );
643 aNewString.append(aClosingBrace);
644 break;
645 }
647 {
648 aNewString.append("rotatez (");
649 Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateZ*>(pObj)->mfRotateZ) );
650 aNewString.append(aClosingBrace);
651 break;
652 }
654 {
655 aNewString.append("scale (");
656 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getX());
657 aNewString.append(aEmptySpace);
658 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getY());
659 aNewString.append(aEmptySpace);
660 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getZ());
661 aNewString.append(aClosingBrace);
662 break;
663 }
665 {
666 aNewString.append("translate (");
667 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getX(), true);
668 aNewString.append(aEmptySpace);
669 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getY(), true);
670 aNewString.append(aEmptySpace);
671 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getZ(), true);
672 aNewString.append(aClosingBrace);
673 break;
674 }
676 {
677 aNewString.append("matrix (");
678
679 // a
680 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 0));
681 aNewString.append(aEmptySpace);
682
683 // b
684 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 0));
685 aNewString.append(aEmptySpace);
686
687 // c
688 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 0));
689 aNewString.append(aEmptySpace);
690
691 // d
692 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 1));
693 aNewString.append(aEmptySpace);
694
695 // e
696 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 1));
697 aNewString.append(aEmptySpace);
698
699 // f
700 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 1));
701 aNewString.append(aEmptySpace);
702
703 // g
704 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 2));
705 aNewString.append(aEmptySpace);
706
707 // h
708 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 2));
709 aNewString.append(aEmptySpace);
710
711 // i
712 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 2));
713 aNewString.append(aEmptySpace);
714
715 // j
716 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 3), true);
717 aNewString.append(aEmptySpace);
718
719 // k
720 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 3), true);
721 aNewString.append(aEmptySpace);
722
723 // l
724 Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 3), true);
725
726 aNewString.append(aClosingBrace);
727 break;
728 }
729 default :
730 {
731 OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
732 break;
733 }
734 }
735
736 // if not the last entry, add one space to next tag
737 if(a + 1 != maList.size())
738 {
739 aNewString.append(aEmptySpace);
740 }
741 }
742
743 // fill string form OUString
744 msString = aNewString.makeStringAndClear();
745
746 return msString;
747}
748
749// for Import: constructor with string, parses it and generates entries
751{
752 SetString(rNew, rConv);
753}
754
755// sets new string, parses it and generates entries
756void SdXMLImExTransform3D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
757{
758 msString = rNew;
759 maList.clear();
760
761 if(msString.isEmpty())
762 return;
763
764 const OUString aStr = msString;
765 const sal_Int32 nLen(aStr.getLength());
766
767 static const OUStringLiteral aString_rotatex( u"rotatex" );
768 static const OUStringLiteral aString_rotatey( u"rotatey" );
769 static const OUStringLiteral aString_rotatez( u"rotatez" );
770 static const OUStringLiteral aString_scale( u"scale" );
771 static const OUStringLiteral aString_translate( u"translate" );
772 static const OUStringLiteral aString_matrix( u"matrix" );
773
774 sal_Int32 nPos(0);
775
776 while(nPos < nLen)
777 {
778 // skip spaces
779 Imp_SkipSpaces(aStr, nPos, nLen);
780
781 // look for tag
782 if(nPos < nLen)
783 {
784 if(nPos == aStr.indexOf(aString_rotatex, nPos))
785 {
786 double fValue(0.0);
787
788 nPos += 7;
790 fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
791 if(fValue != 0.0)
792 maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateX>(basegfx::deg2rad(fValue)));
793
795 }
796 else if(nPos == aStr.indexOf(aString_rotatey, nPos))
797 {
798 double fValue(0.0);
799
800 nPos += 7;
802 fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
803 if(fValue != 0.0)
804 maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateY>(basegfx::deg2rad(fValue)));
805
807 }
808 else if(nPos == aStr.indexOf(aString_rotatez, nPos))
809 {
810 double fValue(0.0);
811
812 nPos += 7;
814 fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
815 if(fValue != 0.0)
816 maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateZ>(basegfx::deg2rad(fValue)));
817
819 }
820 else if(nPos == aStr.indexOf(aString_scale, nPos))
821 {
822 ::basegfx::B3DTuple aValue(1.0, 1.0, 1.0);
823
824 nPos += 5;
826 aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
828 aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
830 aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ()));
831
832 if(1.0 != aValue.getX() || 1.0 != aValue.getY() || 1.0 != aValue.getZ())
833 maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DScale>(aValue));
834
836 }
837 else if(nPos == aStr.indexOf(aString_translate, nPos))
838 {
839 ::basegfx::B3DTuple aValue;
840
841 nPos += 9;
843 aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
845 aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
847 aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ(), true));
848
849 if(!aValue.equalZero())
850 maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DTranslate>(aValue));
851
853 }
854 else if(nPos == aStr.indexOf(aString_matrix, nPos))
855 {
857
858 nPos += 6;
860
861 // a
862 aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
864
865 // b
866 aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
868
869 // c
870 aValue.set(2, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 0)));
872
873 // d
874 aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
876
877 // e
878 aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
880
881 // f
882 aValue.set(2, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 1)));
884
885 // g
886 aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2)));
888
889 // h
890 aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2)));
892
893 // i
894 aValue.set(2, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 2)));
896
897 // j
898 aValue.set(0, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 3), true));
900
901 // k
902 aValue.set(1, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 3), true));
904
905 // l
906 aValue.set(2, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 3), true));
908
909 if(!aValue.isIdentity())
910 maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DMatrix>(aValue));
911
913 }
914 else
915 {
916 nPos++;
917 }
918 }
919 }
920}
921
922bool SdXMLImExTransform3D::GetFullHomogenTransform(css::drawing::HomogenMatrix& xHomMat)
923{
924 ::basegfx::B3DHomMatrix aFullTransform;
925 GetFullTransform(aFullTransform);
926
927 if(!aFullTransform.isIdentity())
928 {
929 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aFullTransform, xHomMat);
930 return true;
931 }
932
933 return false;
934}
935
937{
938 rFullTrans.identity();
939
940 const sal_uInt32 nCount = maList.size();
941 for(sal_uInt32 a(0); a < nCount; a++)
942 {
943 ImpSdXMLExpTransObj3DBase* pObj = maList[a].get();
944 switch(pObj->mnType)
945 {
947 {
948 rFullTrans.rotate(static_cast<ImpSdXMLExpTransObj3DRotateX*>(pObj)->mfRotateX, 0.0, 0.0);
949 break;
950 }
952 {
953 rFullTrans.rotate(0.0, static_cast<ImpSdXMLExpTransObj3DRotateY*>(pObj)->mfRotateY, 0.0);
954 break;
955 }
957 {
958 rFullTrans.rotate(0.0, 0.0, static_cast<ImpSdXMLExpTransObj3DRotateZ*>(pObj)->mfRotateZ);
959 break;
960 }
962 {
963 const ::basegfx::B3DTuple& rScale = static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale;
964 rFullTrans.scale(rScale.getX(), rScale.getY(), rScale.getZ());
965 break;
966 }
968 {
969 const ::basegfx::B3DTuple& rTranslate = static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate;
970 rFullTrans.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
971 break;
972 }
974 {
975 rFullTrans *= static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix;
976 break;
977 }
978 default :
979 {
980 OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
981 break;
982 }
983 }
984 }
985}
986
987SdXMLImExViewBox::SdXMLImExViewBox(double fX, double fY, double fW, double fH)
988: mfX( fX ),
989 mfY( fY ),
990 mfW( fW ),
991 mfH( fH )
992{
993}
994
995// #100617# Asked vincent hardy: svg:viewBox values may be double precision.
997: msString(std::move(aNew)),
998 mfX( 0.0 ),
999 mfY( 0.0 ),
1000 mfW( 1000.0 ),
1001 mfH( 1000.0 )
1002{
1003 if(msString.isEmpty())
1004 return;
1005
1006 const OUString aStr = msString;
1007 const sal_Int32 nLen(aStr.getLength());
1008 sal_Int32 nPos(0);
1009
1010 // skip starting spaces
1011 Imp_SkipSpaces(aStr, nPos, nLen);
1012
1013 // get mX, #100617# be prepared for doubles
1014 mfX = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfX);
1015
1016 // skip spaces and commas
1018
1019 // get mY, #100617# be prepared for doubles
1020 mfY = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfY);
1021
1022 // skip spaces and commas
1024
1025 // get mW, #100617# be prepared for doubles
1026 mfW = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfW);
1027
1028 // skip spaces and commas
1030
1031 // get mH, #100617# be prepared for doubles
1032 mfH = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfH);
1033
1034}
1035
1037{
1038 OUString aNewString;
1039 OUString aEmptySpace(" ");
1040
1041 Imp_PutDoubleChar(aNewString, mfX);
1042 aNewString += aEmptySpace;
1043
1044 Imp_PutDoubleChar(aNewString, mfY);
1045 aNewString += aEmptySpace;
1046
1047 Imp_PutDoubleChar(aNewString, mfW);
1048 aNewString += aEmptySpace;
1049
1050 Imp_PutDoubleChar(aNewString, mfH);
1051
1052 // set new string
1053 msString = aNewString;
1054
1055 return msString;
1056}
1057
1058/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::basegfx::B2DHomMatrix maMatrix
void AddTranslate(const ::basegfx::B2DTuple &rNew)
Definition: xexptran.cxx:234
std::vector< std::shared_ptr< ImpSdXMLExpTransObj2DBase > > maList
Definition: xexptran.hxx:45
void AddSkewX(double fNew)
Definition: xexptran.cxx:240
void AddRotate(double fNew)
Definition: xexptran.cxx:228
const OUString & GetExportString(const SvXMLUnitConverter &rConv)
Definition: xexptran.cxx:247
void SetString(const OUString &rNew, const SvXMLUnitConverter &rConv)
Definition: xexptran.cxx:349
void GetFullTransform(::basegfx::B2DHomMatrix &rFullTrans)
Definition: xexptran.cxx:482
void SetString(const OUString &rNew, const SvXMLUnitConverter &rConv)
Definition: xexptran.cxx:756
void GetFullTransform(::basegfx::B3DHomMatrix &rFullTrans)
Definition: xexptran.cxx:936
bool GetFullHomogenTransform(css::drawing::HomogenMatrix &xHomMat)
Definition: xexptran.cxx:922
const OUString & GetExportString(const SvXMLUnitConverter &rConv)
Definition: xexptran.cxx:620
std::vector< std::shared_ptr< ImpSdXMLExpTransObj3DBase > > maList
Definition: xexptran.hxx:65
void AddMatrix(const ::basegfx::B3DHomMatrix &rNew)
Definition: xexptran.cxx:608
void AddHomogenMatrix(const css::drawing::HomogenMatrix &xHomMat)
Definition: xexptran.cxx:614
OUString msString
Definition: xexptran.hxx:84
const OUString & GetExportString()
Definition: xexptran.cxx:1036
SdXMLImExViewBox(double fX, double fY, double fW, double fH)
Definition: xexptran.cxx:987
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
Definition: xmluconv.hxx:83
void convertDouble(OUStringBuffer &rBuffer, double fNumber) const
convert double number to string (using ::rtl::math) and DO convert to export MapUnit using meCoreMeas...
Definition: xmluconv.cxx:334
void shearX(double fSx)
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
void rotate(double fRadiant)
void translate(double fX, double fY)
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
void scale(double fX, double fY)
void shearY(double fSy)
bool isIdentity() const
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
bool isIdentity() const
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
void rotate(double fAngleX, double fAngleY, double fAngleZ)
void translate(double fX, double fY, double fZ)
void scale(double fX, double fY, double fZ)
bool equalZero() const
bool equalZero() const
TYPE getX() const
void setY(TYPE fY)
TYPE getY() const
void setX(TYPE fX)
void setX(TYPE fX)
TYPE getX() const
TYPE getZ() const
TYPE getY() const
void setY(TYPE fY)
void setZ(TYPE fZ)
static void convertDouble(OUStringBuffer &rBuffer, double fNumber, bool bWriteUnits, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
int nCount
float u
uno_Any a
sal_uInt16 nPos
aStr
void B3DHomMatrixToUnoHomogenMatrix(const B3DHomMatrix &rMatrixIn, com::sun::star::drawing::HomogenMatrix &rMatrixOut)
B3DHomMatrix UnoHomogenMatrixToB3DHomMatrix(const com::sun::star::drawing::HomogenMatrix &rMatrixIn)
constexpr double rad2deg(double v)
constexpr double deg2rad(double v)
double mfY
double mfX
QPRO_FUNC_TYPE nType
ImpSdXMLExpTransObj2DBase(sal_uInt16 nType)
Definition: xexptran.cxx:170
ImpSdXMLExpTransObj3DBase(sal_uInt16 nType)
Definition: xexptran.cxx:550
sal_uInt16 sal_Unicode
static void Imp_PutDoubleChar(OUString &rStr, double fValue)
Definition: xexptran.cxx:143
static double Imp_GetDoubleChar(std::u16string_view rStr, sal_Int32 &rPos, const sal_Int32 nLen, const SvXMLUnitConverter &rConv, double fRetval, bool bLookForUnits=false)
Definition: xexptran.cxx:81
#define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE
Definition: xexptran.cxx:176
static bool Imp_IsOnUnitChar(std::u16string_view rStr, const sal_Int32 nPos)
Definition: xexptran.cxx:72
#define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX
Definition: xexptran.cxx:181
#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY
Definition: xexptran.cxx:180
static void Imp_SkipSpacesAndOpeningBraces(std::u16string_view rStr, sal_Int32 &rPos, const sal_Int32 nLen)
Definition: xexptran.cxx:49
static void Imp_SkipSpacesAndClosingBraces(std::u16string_view rStr, sal_Int32 &rPos, const sal_Int32 nLen)
Definition: xexptran.cxx:63
#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX
Definition: xexptran.cxx:179
#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z
Definition: xexptran.cxx:558
#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X
Definition: xexptran.cxx:556
#define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE
Definition: xexptran.cxx:178
static void Imp_SkipSpacesAndCommas(std::u16string_view rStr, sal_Int32 &rPos, const sal_Int32 nLen)
Definition: xexptran.cxx:56
static void Imp_SkipSpaces(std::u16string_view rStr, sal_Int32 &rPos, const sal_Int32 nLen)
Definition: xexptran.cxx:42
#define IMP_SDXMLEXP_TRANSOBJ2D_SCALE
Definition: xexptran.cxx:177
#define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX
Definition: xexptran.cxx:561
#define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE
Definition: xexptran.cxx:560
#define IMP_SDXMLEXP_TRANSOBJ3D_SCALE
Definition: xexptran.cxx:559
#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y
Definition: xexptran.cxx:557