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