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