xref: /AOO41X/main/xmloff/source/draw/xexptran.cxx (revision a8265799e2e445d3b608eb87bbb66016c11ee464)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "xexptran.hxx"
27 #include <tools/debug.hxx>
28 #include <rtl/ustrbuf.hxx>
29 #include <xmloff/xmluconv.hxx>
30 #include <tools/gen.hxx>
31 #include <basegfx/vector/b2dvector.hxx>
32 #include <basegfx/matrix/b2dhommatrix.hxx>
33 #include <basegfx/tuple/b3dtuple.hxx>
34 #include <basegfx/matrix/b3dhommatrix.hxx>
35 #include <basegfx/numeric/ftools.hxx>
36 #include <tools/string.hxx>
37 
38 using ::rtl::OUString;
39 using ::rtl::OUStringBuffer;
40 
41 using namespace ::com::sun::star;
42 
43 //////////////////////////////////////////////////////////////////////////////
44 // Defines
45 
46 #define BORDER_INTEGERS_ARE_EQUAL       (4)
47 
48 //////////////////////////////////////////////////////////////////////////////
49 // Predeclarations
50 
51 void Imp_SkipDouble(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen);
52 void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection);
53 
54 //////////////////////////////////////////////////////////////////////////////
55 //////////////////////////////////////////////////////////////////////////////
56 // parsing help functions for simple chars
Imp_SkipSpaces(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen)57 void Imp_SkipSpaces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
58 {
59     while(rPos < nLen
60         && sal_Unicode(' ') == rStr[rPos])
61         rPos++;
62 }
63 
Imp_SkipSpacesAndOpeningBraces(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen)64 void Imp_SkipSpacesAndOpeningBraces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
65 {
66     while(rPos < nLen
67         && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode('(') == rStr[rPos]))
68         rPos++;
69 }
70 
Imp_SkipSpacesAndCommas(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen)71 void Imp_SkipSpacesAndCommas(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
72 {
73     while(rPos < nLen
74         && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode(',') == rStr[rPos]))
75         rPos++;
76 }
77 
Imp_SkipSpacesAndClosingBraces(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen)78 void Imp_SkipSpacesAndClosingBraces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
79 {
80     while(rPos < nLen
81         && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode(')') == rStr[rPos]))
82         rPos++;
83 }
84 
85 //////////////////////////////////////////////////////////////////////////////
86 //////////////////////////////////////////////////////////////////////////////
87 // parsing help functions for integer numbers
88 
Imp_IsOnNumberChar(const OUString & rStr,const sal_Int32 nPos,bool bSignAllowed=true)89 bool Imp_IsOnNumberChar(const OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true)
90 {
91     sal_Unicode aChar(rStr[nPos]);
92 
93     if((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
94         || (bSignAllowed && sal_Unicode('+') == aChar)
95         || (bSignAllowed && sal_Unicode('-') == aChar)
96     )
97         return true;
98     return false;
99 }
100 
Imp_IsOnUnitChar(const OUString & rStr,const sal_Int32 nPos)101 bool Imp_IsOnUnitChar(const OUString& rStr, const sal_Int32 nPos)
102 {
103     sal_Unicode aChar(rStr[nPos]);
104 
105     if((sal_Unicode('a') <= aChar && sal_Unicode('z') >= aChar)
106         || (sal_Unicode('A') <= aChar && sal_Unicode('Z') >= aChar)
107         || sal_Unicode('%') == aChar
108     )
109         return true;
110     return false;
111 }
112 
Imp_SkipNumber(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen)113 void Imp_SkipNumber(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
114 {
115     bool bSignAllowed(true);
116 
117     while(rPos < nLen && Imp_IsOnNumberChar(rStr, rPos, bSignAllowed))
118     {
119         bSignAllowed = false;
120         rPos++;
121     }
122 }
123 
Imp_SkipNumberAndSpacesAndCommas(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen)124 void Imp_SkipNumberAndSpacesAndCommas(const OUString& rStr, sal_Int32& rPos,
125     const sal_Int32 nLen)
126 {
127     Imp_SkipNumber(rStr, rPos, nLen);
128     Imp_SkipSpacesAndCommas(rStr, rPos, nLen);
129 }
130 
131 // #100617# Allow to skip doubles, too.
Imp_SkipDoubleAndSpacesAndCommas(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen)132 void Imp_SkipDoubleAndSpacesAndCommas(const OUString& rStr, sal_Int32& rPos,
133     const sal_Int32 nLen)
134 {
135     Imp_SkipDouble(rStr, rPos, nLen);
136     Imp_SkipSpacesAndCommas(rStr, rPos, nLen);
137 }
138 
Imp_PutNumberChar(OUString & rStr,sal_Int32 nValue)139 void Imp_PutNumberChar(OUString& rStr, sal_Int32 nValue)
140 {
141     OUStringBuffer sStringBuffer;
142     SvXMLUnitConverter::convertNumber(sStringBuffer, nValue);
143     rStr += OUString(sStringBuffer.makeStringAndClear());
144 }
145 
Imp_PutNumberCharWithSpace(OUString & rStr,sal_Int32 nValue)146 void Imp_PutNumberCharWithSpace(OUString& rStr, sal_Int32 nValue)
147 {
148     const sal_Int32 aLen(rStr.getLength());
149     if(aLen)
150         if(Imp_IsOnNumberChar(rStr, aLen - 1, false) && nValue >= 0)
151             rStr += String(sal_Unicode(' '));
152     Imp_PutNumberChar(rStr, nValue);
153 }
154 
155 //////////////////////////////////////////////////////////////////////////////
156 //////////////////////////////////////////////////////////////////////////////
157 // parsing help functions for double numbers
158 
Imp_SkipDouble(const OUString & rStr,sal_Int32 & rPos,const sal_Int32)159 void Imp_SkipDouble(const OUString& rStr, sal_Int32& rPos, const sal_Int32)
160 {
161     sal_Unicode aChar(rStr[rPos]);
162 
163     if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
164         aChar = rStr[++rPos];
165 
166     while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
167         || sal_Unicode('.') == aChar)
168     {
169         aChar = rStr[++rPos];
170     }
171 
172     if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
173     {
174         aChar = rStr[++rPos];
175 
176         if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
177             aChar = rStr[++rPos];
178 
179         while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
180         {
181             aChar = rStr[++rPos];
182         }
183     }
184 }
185 
Imp_GetDoubleChar(const OUString & rStr,sal_Int32 & rPos,const sal_Int32 nLen,const SvXMLUnitConverter & rConv,double fRetval,bool bLookForUnits=false)186 double Imp_GetDoubleChar(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen,
187     const SvXMLUnitConverter& rConv, double fRetval, bool bLookForUnits = false)
188 {
189     sal_Unicode aChar(rStr[rPos]);
190     OUStringBuffer sNumberString;
191 
192     if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
193     {
194         sNumberString.append(rStr[rPos]);
195         aChar = rStr[++rPos];
196     }
197 
198     while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
199         || sal_Unicode('.') == aChar)
200     {
201         sNumberString.append(rStr[rPos]);
202         aChar = rStr[++rPos];
203     }
204 
205     if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
206     {
207         sNumberString.append(rStr[rPos]);
208         aChar = rStr[++rPos];
209 
210         if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
211         {
212             sNumberString.append(rStr[rPos]);
213             aChar = rStr[++rPos];
214         }
215 
216         while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
217         {
218             sNumberString.append(rStr[rPos]);
219             aChar = rStr[++rPos];
220         }
221     }
222 
223     if(bLookForUnits)
224     {
225         Imp_SkipSpaces(rStr, rPos, nLen);
226         while(rPos < nLen && Imp_IsOnUnitChar(rStr, rPos))
227             sNumberString.append(rStr[rPos++]);
228     }
229 
230     if(sNumberString.getLength())
231     {
232         if(bLookForUnits)
233             rConv.convertDouble(fRetval, sNumberString.makeStringAndClear(), true);
234         else
235             rConv.convertDouble(fRetval, sNumberString.makeStringAndClear());
236     }
237 
238     return fRetval;
239 }
240 
Imp_PutDoubleChar(OUString & rStr,double fValue)241 void Imp_PutDoubleChar(OUString& rStr, double fValue)
242 {
243     OUStringBuffer sStringBuffer;
244     SvXMLUnitConverter::convertDouble(sStringBuffer, fValue);
245     rStr += OUString(sStringBuffer.makeStringAndClear());
246 }
247 
Imp_PutDoubleChar(OUString & rStr,const SvXMLUnitConverter & rConv,double fValue,bool bConvertUnits=false)248 void Imp_PutDoubleChar(OUString& rStr, const SvXMLUnitConverter& rConv, double fValue,
249     bool bConvertUnits = false)
250 {
251     OUStringBuffer sStringBuffer;
252 
253     if(bConvertUnits)
254         rConv.convertDouble(sStringBuffer, fValue, true);
255     else
256         rConv.convertDouble(sStringBuffer, fValue);
257 
258     rStr += OUString(sStringBuffer.makeStringAndClear());
259 }
260 
261 //////////////////////////////////////////////////////////////////////////////
262 //////////////////////////////////////////////////////////////////////////////
263 // base class of all 2D transform objects
264 
265 struct ImpSdXMLExpTransObj2DBase
266 {
267     sal_uInt16                  mnType;
ImpSdXMLExpTransObj2DBaseImpSdXMLExpTransObj2DBase268     ImpSdXMLExpTransObj2DBase(sal_uInt16 nType)
269     :   mnType(nType) {}
270 };
271 
272 //////////////////////////////////////////////////////////////////////////////
273 // possible object types for 2D
274 
275 #define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE          0x0000
276 #define IMP_SDXMLEXP_TRANSOBJ2D_SCALE           0x0001
277 #define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE       0x0002
278 #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX           0x0003
279 #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY           0x0004
280 #define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX          0x0005
281 
282 //////////////////////////////////////////////////////////////////////////////
283 // classes of objects, different sizes
284 
285 struct ImpSdXMLExpTransObj2DRotate : public ImpSdXMLExpTransObj2DBase
286 {
287     double                      mfRotate;
ImpSdXMLExpTransObj2DRotateImpSdXMLExpTransObj2DRotate288     ImpSdXMLExpTransObj2DRotate(double fVal)
289     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_ROTATE), mfRotate(fVal) {}
290 };
291 struct ImpSdXMLExpTransObj2DScale : public ImpSdXMLExpTransObj2DBase
292 {
293     ::basegfx::B2DTuple         maScale;
ImpSdXMLExpTransObj2DScaleImpSdXMLExpTransObj2DScale294     ImpSdXMLExpTransObj2DScale(const ::basegfx::B2DTuple& rNew)
295     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SCALE), maScale(rNew) {}
296 };
297 struct ImpSdXMLExpTransObj2DTranslate : public ImpSdXMLExpTransObj2DBase
298 {
299     ::basegfx::B2DTuple         maTranslate;
ImpSdXMLExpTransObj2DTranslateImpSdXMLExpTransObj2DTranslate300     ImpSdXMLExpTransObj2DTranslate(const ::basegfx::B2DTuple& rNew)
301     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE), maTranslate(rNew) {}
302 };
303 struct ImpSdXMLExpTransObj2DSkewX : public ImpSdXMLExpTransObj2DBase
304 {
305     double                      mfSkewX;
ImpSdXMLExpTransObj2DSkewXImpSdXMLExpTransObj2DSkewX306     ImpSdXMLExpTransObj2DSkewX(double fVal)
307     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWX), mfSkewX(fVal) {}
308 };
309 struct ImpSdXMLExpTransObj2DSkewY : public ImpSdXMLExpTransObj2DBase
310 {
311     double                      mfSkewY;
ImpSdXMLExpTransObj2DSkewYImpSdXMLExpTransObj2DSkewY312     ImpSdXMLExpTransObj2DSkewY(double fVal)
313     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWY), mfSkewY(fVal) {}
314 };
315 struct ImpSdXMLExpTransObj2DMatrix : public ImpSdXMLExpTransObj2DBase
316 {
317     ::basegfx::B2DHomMatrix     maMatrix;
ImpSdXMLExpTransObj2DMatrixImpSdXMLExpTransObj2DMatrix318     ImpSdXMLExpTransObj2DMatrix(const ::basegfx::B2DHomMatrix& rNew)
319     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_MATRIX), maMatrix(rNew) {}
320 };
321 
322 //////////////////////////////////////////////////////////////////////////////
323 //////////////////////////////////////////////////////////////////////////////
324 // delete all entries in list
325 
EmptyList()326 void SdXMLImExTransform2D::EmptyList()
327 {
328     const sal_uInt32 nCount = maList.size();
329     for(sal_uInt32 a(0L); a < nCount; a++)
330     {
331         ImpSdXMLExpTransObj2DBase* pObj = maList[a];
332 
333         switch(pObj->mnType)
334         {
335             case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE     :
336             {
337                 delete (ImpSdXMLExpTransObj2DRotate*)pObj;
338                 break;
339             }
340             case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
341             {
342                 delete (ImpSdXMLExpTransObj2DScale*)pObj;
343                 break;
344             }
345             case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
346             {
347                 delete (ImpSdXMLExpTransObj2DTranslate*)pObj;
348                 break;
349             }
350             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
351             {
352                 delete (ImpSdXMLExpTransObj2DSkewX*)pObj;
353                 break;
354             }
355             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
356             {
357                 delete (ImpSdXMLExpTransObj2DSkewY*)pObj;
358                 break;
359             }
360             case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX     :
361             {
362                 delete (ImpSdXMLExpTransObj2DMatrix*)pObj;
363                 break;
364             }
365             default :
366             {
367                 DBG_ERROR("SdXMLImExTransform2D: impossible entry!");
368                 break;
369             }
370         }
371     }
372 
373     maList.clear();
374 }
375 
376 //////////////////////////////////////////////////////////////////////////////
377 // add members
378 
AddRotate(double fNew)379 void SdXMLImExTransform2D::AddRotate(double fNew)
380 {
381     if(fNew != 0.0)
382         maList.push_back(new ImpSdXMLExpTransObj2DRotate(fNew));
383 }
384 
AddScale(const::basegfx::B2DTuple & rNew)385 void SdXMLImExTransform2D::AddScale(const ::basegfx::B2DTuple& rNew)
386 {
387     if(1.0 != rNew.getX() || 1.0 != rNew.getY())
388         maList.push_back(new ImpSdXMLExpTransObj2DScale(rNew));
389 }
390 
AddTranslate(const::basegfx::B2DTuple & rNew)391 void SdXMLImExTransform2D::AddTranslate(const ::basegfx::B2DTuple& rNew)
392 {
393     if(!rNew.equalZero())
394         maList.push_back(new ImpSdXMLExpTransObj2DTranslate(rNew));
395 }
396 
AddSkewX(double fNew)397 void SdXMLImExTransform2D::AddSkewX(double fNew)
398 {
399     if(fNew != 0.0)
400         maList.push_back(new ImpSdXMLExpTransObj2DSkewX(fNew));
401 }
402 
AddSkewY(double fNew)403 void SdXMLImExTransform2D::AddSkewY(double fNew)
404 {
405     if(fNew != 0.0)
406         maList.push_back(new ImpSdXMLExpTransObj2DSkewY(fNew));
407 }
408 
AddMatrix(const::basegfx::B2DHomMatrix & rNew)409 void SdXMLImExTransform2D::AddMatrix(const ::basegfx::B2DHomMatrix& rNew)
410 {
411     if(!rNew.isIdentity())
412         maList.push_back(new ImpSdXMLExpTransObj2DMatrix(rNew));
413 }
414 
415 //////////////////////////////////////////////////////////////////////////////
416 // gen string for export
GetExportString(const SvXMLUnitConverter & rConv)417 const OUString& SdXMLImExTransform2D::GetExportString(const SvXMLUnitConverter& rConv)
418 {
419     OUString aNewString;
420     OUString aClosingBrace(sal_Unicode(')'));
421     OUString aEmptySpace(sal_Unicode(' '));
422 
423     const sal_uInt32 nCount = maList.size();
424     for(sal_uInt32 a(0L); a < nCount; a++)
425     {
426         ImpSdXMLExpTransObj2DBase* pObj = maList[a];
427         switch(pObj->mnType)
428         {
429             case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE :
430             {
431                 aNewString += OUString::createFromAscii("rotate (");
432                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DRotate*)pObj)->mfRotate);
433                 aNewString += aClosingBrace;
434                 break;
435             }
436             case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
437             {
438                 aNewString += OUString::createFromAscii("scale (");
439                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale.getX());
440                 aNewString += aEmptySpace;
441                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale.getY());
442                 aNewString += aClosingBrace;
443                 break;
444             }
445             case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
446             {
447                 aNewString += OUString::createFromAscii("translate (");
448                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate.getX(), true);
449                 aNewString += aEmptySpace;
450                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate.getY(), true);
451                 aNewString += aClosingBrace;
452                 break;
453             }
454             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
455             {
456                 aNewString += OUString::createFromAscii("skewX (");
457                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DSkewX*)pObj)->mfSkewX);
458                 aNewString += aClosingBrace;
459                 break;
460             }
461             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
462             {
463                 aNewString += OUString::createFromAscii("skewY (");
464                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DSkewY*)pObj)->mfSkewY);
465                 aNewString += aClosingBrace;
466                 break;
467             }
468             case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX :
469             {
470                 aNewString += OUString::createFromAscii("matrix (");
471 
472                 // a
473                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 0));
474                 aNewString += aEmptySpace;
475 
476                 // b
477                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 0));
478                 aNewString += aEmptySpace;
479 
480                 // c
481                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 1));
482                 aNewString += aEmptySpace;
483 
484                 // d
485                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 1));
486                 aNewString += aEmptySpace;
487 
488                 // e
489                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 2), true);
490                 aNewString += aEmptySpace;
491 
492                 // f
493                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 2), true);
494 
495                 aNewString += aClosingBrace;
496                 break;
497             }
498             default :
499             {
500                 DBG_ERROR("SdXMLImExTransform2D: impossible entry!");
501                 break;
502             }
503         }
504 
505         // if not the last entry, add one space to next tag
506         if(a + 1UL != maList.size())
507         {
508             aNewString += aEmptySpace;
509         }
510     }
511 
512     // fill string form OUString
513     msString = aNewString;
514 
515     return msString;
516 }
517 
518 //////////////////////////////////////////////////////////////////////////////
519 // for Import: constructor with string, parses it and generates entries
SdXMLImExTransform2D(const OUString & rNew,const SvXMLUnitConverter & rConv)520 SdXMLImExTransform2D::SdXMLImExTransform2D(const OUString& rNew, const SvXMLUnitConverter& rConv)
521 {
522     SetString(rNew, rConv);
523 }
524 
525 //////////////////////////////////////////////////////////////////////////////
526 // sets new string, parses it and generates entries
SetString(const OUString & rNew,const SvXMLUnitConverter & rConv)527 void SdXMLImExTransform2D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
528 {
529     msString = rNew;
530     EmptyList();
531 
532     if(msString.getLength())
533     {
534         const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength());
535         const sal_Int32 nLen(aStr.getLength());
536 
537         const OUString aString_rotate(OUString::createFromAscii("rotate"));
538         const OUString aString_scale(OUString::createFromAscii("scale"));
539         const OUString aString_translate(OUString::createFromAscii("translate"));
540         const OUString aString_skewX(OUString::createFromAscii("skewX"));
541         const OUString aString_skewY(OUString::createFromAscii("skewY"));
542         const OUString aString_matrix(OUString::createFromAscii("matrix"));
543 
544         sal_Int32 nPos(0);
545 
546         while(nPos < nLen)
547         {
548             // skip spaces
549             Imp_SkipSpaces(aStr, nPos, nLen);
550 
551             // look for tag
552             if(nPos < nLen)
553             {
554                 if(nPos == aStr.indexOf(aString_rotate, nPos))
555                 {
556                     double fValue(0.0);
557                     nPos += 6;
558                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
559                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
560                     if(fValue != 0.0)
561                         maList.push_back(new ImpSdXMLExpTransObj2DRotate(fValue));
562 
563                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
564                 }
565                 else if(nPos == aStr.indexOf(aString_scale, nPos))
566                 {
567                     ::basegfx::B2DTuple aValue(1.0, 1.0);
568                     nPos += 5;
569                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
570                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
571                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
572                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
573 
574                     if(aValue.getX() != 1.0 || aValue.getY() != 1.0)
575                         maList.push_back(new ImpSdXMLExpTransObj2DScale(aValue));
576 
577                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
578                 }
579                 else if(nPos == aStr.indexOf(aString_translate, nPos))
580                 {
581                     ::basegfx::B2DTuple aValue;
582                     nPos += 9;
583                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
584                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
585                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
586                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
587 
588                     if(!aValue.equalZero())
589                         maList.push_back(new ImpSdXMLExpTransObj2DTranslate(aValue));
590 
591                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
592                 }
593                 else if(nPos == aStr.indexOf(aString_skewX, nPos))
594                 {
595                     double fValue(0.0);
596                     nPos += 5;
597                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
598                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
599                     if(fValue != 0.0)
600                         maList.push_back(new ImpSdXMLExpTransObj2DSkewX(fValue));
601 
602                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
603                 }
604                 else if(nPos == aStr.indexOf(aString_skewY, nPos))
605                 {
606                     double fValue(0.0);
607                     nPos += 5;
608                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
609                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
610                     if(fValue != 0.0)
611                         maList.push_back(new ImpSdXMLExpTransObj2DSkewY(fValue));
612 
613                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
614                 }
615                 else if(nPos == aStr.indexOf(aString_matrix, nPos))
616                 {
617                     ::basegfx::B2DHomMatrix aValue;
618 
619                     nPos += 6;
620                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
621 
622                     // a
623                     aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
624                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
625 
626                     // b
627                     aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
628                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
629 
630                     // c
631                     aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
632                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
633 
634                     // d
635                     aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
636                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
637 
638                     // e
639                     aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2), true));
640                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
641 
642                     // f
643                     aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2), true));
644                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
645 
646                     if(!aValue.isIdentity())
647                         maList.push_back(new ImpSdXMLExpTransObj2DMatrix(aValue));
648 
649                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
650                 }
651                 else
652                 {
653                     nPos++;
654                 }
655             }
656         }
657     }
658 }
659 
GetFullTransform(::basegfx::B2DHomMatrix & rFullTrans)660 void SdXMLImExTransform2D::GetFullTransform(::basegfx::B2DHomMatrix& rFullTrans)
661 {
662     rFullTrans.identity();
663 
664     const sal_uInt32 nCount = maList.size();
665     for(sal_uInt32 a(0L); a < nCount; a++)
666     {
667         ImpSdXMLExpTransObj2DBase* pObj = maList[a];
668         switch(pObj->mnType)
669         {
670             case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE     :
671             {
672                 // #i78696#
673                 // mfRotate is mathematically wrong oriented since we export/import the angle
674                 // values mirrored. This error is fixed in the API, but not yet in the FileFormat.
675                 // For the FileFormat there is a follow-up task (#i78698#) to fix this in the next
676                 // ODF FileFormat version. For now - to emulate the old behaviour - it is necessary
677                 // to mirror the value here
678                 rFullTrans.rotate(((ImpSdXMLExpTransObj2DRotate*)pObj)->mfRotate * -1.0);
679                 break;
680             }
681             case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
682             {
683                 const ::basegfx::B2DTuple& rScale = ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale;
684                 rFullTrans.scale(rScale.getX(), rScale.getY());
685                 break;
686             }
687             case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
688             {
689                 const ::basegfx::B2DTuple& rTranslate = ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate;
690                 rFullTrans.translate(rTranslate.getX(), rTranslate.getY());
691                 break;
692             }
693             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
694             {
695                 rFullTrans.shearX(tan(((ImpSdXMLExpTransObj2DSkewX*)pObj)->mfSkewX));
696                 break;
697             }
698             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
699             {
700                 rFullTrans.shearY(tan(((ImpSdXMLExpTransObj2DSkewY*)pObj)->mfSkewY));
701                 break;
702             }
703             case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX     :
704             {
705                 rFullTrans *= ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix;
706                 break;
707             }
708             default :
709             {
710                 DBG_ERROR("SdXMLImExTransform2D: impossible entry!");
711                 break;
712             }
713         }
714     }
715 }
716 
717 //////////////////////////////////////////////////////////////////////////////
718 //////////////////////////////////////////////////////////////////////////////
719 // base class of all 3D transform objects
720 
721 struct ImpSdXMLExpTransObj3DBase
722 {
723     sal_uInt16                  mnType;
ImpSdXMLExpTransObj3DBaseImpSdXMLExpTransObj3DBase724     ImpSdXMLExpTransObj3DBase(sal_uInt16 nType)
725     :   mnType(nType) {}
726 };
727 
728 //////////////////////////////////////////////////////////////////////////////
729 // possible object types for 3D
730 
731 #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X        0x0000
732 #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y        0x0001
733 #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z        0x0002
734 #define IMP_SDXMLEXP_TRANSOBJ3D_SCALE           0x0003
735 #define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE       0x0004
736 #define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX          0x0005
737 
738 //////////////////////////////////////////////////////////////////////////////
739 // classes of objects, different sizes
740 
741 struct ImpSdXMLExpTransObj3DRotateX : public ImpSdXMLExpTransObj3DBase
742 {
743     double                      mfRotateX;
ImpSdXMLExpTransObj3DRotateXImpSdXMLExpTransObj3DRotateX744     ImpSdXMLExpTransObj3DRotateX(double fVal)
745     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X), mfRotateX(fVal) {}
746 };
747 struct ImpSdXMLExpTransObj3DRotateY : public ImpSdXMLExpTransObj3DBase
748 {
749     double                      mfRotateY;
ImpSdXMLExpTransObj3DRotateYImpSdXMLExpTransObj3DRotateY750     ImpSdXMLExpTransObj3DRotateY(double fVal)
751     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y), mfRotateY(fVal) {}
752 };
753 struct ImpSdXMLExpTransObj3DRotateZ : public ImpSdXMLExpTransObj3DBase
754 {
755     double                      mfRotateZ;
ImpSdXMLExpTransObj3DRotateZImpSdXMLExpTransObj3DRotateZ756     ImpSdXMLExpTransObj3DRotateZ(double fVal)
757     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z), mfRotateZ(fVal) {}
758 };
759 struct ImpSdXMLExpTransObj3DScale : public ImpSdXMLExpTransObj3DBase
760 {
761     ::basegfx::B3DTuple         maScale;
ImpSdXMLExpTransObj3DScaleImpSdXMLExpTransObj3DScale762     ImpSdXMLExpTransObj3DScale(const ::basegfx::B3DTuple& rNew)
763     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_SCALE), maScale(rNew) {}
764 };
765 struct ImpSdXMLExpTransObj3DTranslate : public ImpSdXMLExpTransObj3DBase
766 {
767     ::basegfx::B3DTuple         maTranslate;
ImpSdXMLExpTransObj3DTranslateImpSdXMLExpTransObj3DTranslate768     ImpSdXMLExpTransObj3DTranslate(const ::basegfx::B3DTuple& rNew)
769     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE), maTranslate(rNew) {}
770 };
771 struct ImpSdXMLExpTransObj3DMatrix : public ImpSdXMLExpTransObj3DBase
772 {
773     ::basegfx::B3DHomMatrix     maMatrix;
ImpSdXMLExpTransObj3DMatrixImpSdXMLExpTransObj3DMatrix774     ImpSdXMLExpTransObj3DMatrix(const ::basegfx::B3DHomMatrix& rNew)
775     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_MATRIX), maMatrix(rNew) {}
776 };
777 
778 //////////////////////////////////////////////////////////////////////////////
779 //////////////////////////////////////////////////////////////////////////////
780 // delete all entries in list
781 
EmptyList()782 void SdXMLImExTransform3D::EmptyList()
783 {
784     const sal_uInt32 nCount = maList.size();
785     for(sal_uInt32 a(0L); a < nCount; a++)
786     {
787         ImpSdXMLExpTransObj3DBase* pObj = maList[a];
788 
789         switch(pObj->mnType)
790         {
791             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
792             {
793                 delete (ImpSdXMLExpTransObj3DRotateX*)pObj;
794                 break;
795             }
796             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
797             {
798                 delete (ImpSdXMLExpTransObj3DRotateY*)pObj;
799                 break;
800             }
801             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
802             {
803                 delete (ImpSdXMLExpTransObj3DRotateZ*)pObj;
804                 break;
805             }
806             case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
807             {
808                 delete (ImpSdXMLExpTransObj3DScale*)pObj;
809                 break;
810             }
811             case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
812             {
813                 delete (ImpSdXMLExpTransObj3DTranslate*)pObj;
814                 break;
815             }
816             case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX     :
817             {
818                 delete (ImpSdXMLExpTransObj3DMatrix*)pObj;
819                 break;
820             }
821             default :
822             {
823                 DBG_ERROR("SdXMLImExTransform3D: impossible entry!");
824                 break;
825             }
826         }
827     }
828 
829     maList.clear();
830 }
831 
832 //////////////////////////////////////////////////////////////////////////////
833 // add members
834 
AddRotateX(double fNew)835 void SdXMLImExTransform3D::AddRotateX(double fNew)
836 {
837     if(fNew != 0.0)
838         maList.push_back(new ImpSdXMLExpTransObj3DRotateX(fNew));
839 }
840 
AddRotateY(double fNew)841 void SdXMLImExTransform3D::AddRotateY(double fNew)
842 {
843     if(fNew != 0.0)
844         maList.push_back(new ImpSdXMLExpTransObj3DRotateY(fNew));
845 }
846 
AddRotateZ(double fNew)847 void SdXMLImExTransform3D::AddRotateZ(double fNew)
848 {
849     if(fNew != 0.0)
850         maList.push_back(new ImpSdXMLExpTransObj3DRotateZ(fNew));
851 }
852 
AddScale(const::basegfx::B3DTuple & rNew)853 void SdXMLImExTransform3D::AddScale(const ::basegfx::B3DTuple& rNew)
854 {
855     if(1.0 != rNew.getX() || 1.0 != rNew.getY() || 1.0 != rNew.getZ())
856         maList.push_back(new ImpSdXMLExpTransObj3DScale(rNew));
857 }
858 
AddTranslate(const::basegfx::B3DTuple & rNew)859 void SdXMLImExTransform3D::AddTranslate(const ::basegfx::B3DTuple& rNew)
860 {
861     if(!rNew.equalZero())
862         maList.push_back(new ImpSdXMLExpTransObj3DTranslate(rNew));
863 }
864 
AddMatrix(const::basegfx::B3DHomMatrix & rNew)865 void SdXMLImExTransform3D::AddMatrix(const ::basegfx::B3DHomMatrix& rNew)
866 {
867     if(!rNew.isIdentity())
868         maList.push_back(new ImpSdXMLExpTransObj3DMatrix(rNew));
869 }
870 
AddHomogenMatrix(const drawing::HomogenMatrix & xHomMat)871 void SdXMLImExTransform3D::AddHomogenMatrix(const drawing::HomogenMatrix& xHomMat)
872 {
873     ::basegfx::B3DHomMatrix aExportMatrix;
874 
875     aExportMatrix.set(0, 0, xHomMat.Line1.Column1);
876     aExportMatrix.set(0, 1, xHomMat.Line1.Column2);
877     aExportMatrix.set(0, 2, xHomMat.Line1.Column3);
878     aExportMatrix.set(0, 3, xHomMat.Line1.Column4);
879     aExportMatrix.set(1, 0, xHomMat.Line2.Column1);
880     aExportMatrix.set(1, 1, xHomMat.Line2.Column2);
881     aExportMatrix.set(1, 2, xHomMat.Line2.Column3);
882     aExportMatrix.set(1, 3, xHomMat.Line2.Column4);
883     aExportMatrix.set(2, 0, xHomMat.Line3.Column1);
884     aExportMatrix.set(2, 1, xHomMat.Line3.Column2);
885     aExportMatrix.set(2, 2, xHomMat.Line3.Column3);
886     aExportMatrix.set(2, 3, xHomMat.Line3.Column4);
887 
888     AddMatrix(aExportMatrix);
889 }
890 
891 //////////////////////////////////////////////////////////////////////////////
892 // gen string for export
GetExportString(const SvXMLUnitConverter & rConv)893 const OUString& SdXMLImExTransform3D::GetExportString(const SvXMLUnitConverter& rConv)
894 {
895     OUString aNewString;
896     OUString aClosingBrace(sal_Unicode(')'));
897     OUString aEmptySpace(sal_Unicode(' '));
898 
899     const sal_uInt32 nCount = maList.size();
900     for(sal_uInt32 a(0L); a < nCount; a++)
901     {
902         ImpSdXMLExpTransObj3DBase* pObj = maList[a];
903         switch(pObj->mnType)
904         {
905             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
906             {
907                 aNewString += OUString::createFromAscii("rotatex (");
908                 Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( ((ImpSdXMLExpTransObj3DRotateX*)pObj)->mfRotateX) );
909                 aNewString += aClosingBrace;
910                 break;
911             }
912             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
913             {
914                 aNewString += OUString::createFromAscii("rotatey (");
915                 Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( ((ImpSdXMLExpTransObj3DRotateY*)pObj)->mfRotateY) );
916                 aNewString += aClosingBrace;
917                 break;
918             }
919             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
920             {
921                 aNewString += OUString::createFromAscii("rotatez (");
922                 Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( ((ImpSdXMLExpTransObj3DRotateZ*)pObj)->mfRotateZ) );
923                 aNewString += aClosingBrace;
924                 break;
925             }
926             case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
927             {
928                 aNewString += OUString::createFromAscii("scale (");
929                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getX());
930                 aNewString += aEmptySpace;
931                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getY());
932                 aNewString += aEmptySpace;
933                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getZ());
934                 aNewString += aClosingBrace;
935                 break;
936             }
937             case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
938             {
939                 aNewString += OUString::createFromAscii("translate (");
940                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getX(), true);
941                 aNewString += aEmptySpace;
942                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getY(), true);
943                 aNewString += aEmptySpace;
944                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getZ(), true);
945                 aNewString += aClosingBrace;
946                 break;
947             }
948             case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX :
949             {
950                 aNewString += OUString::createFromAscii("matrix (");
951 
952                 // a
953                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 0));
954                 aNewString += aEmptySpace;
955 
956                 // b
957                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 0));
958                 aNewString += aEmptySpace;
959 
960                 // c
961                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 0));
962                 aNewString += aEmptySpace;
963 
964                 // d
965                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 1));
966                 aNewString += aEmptySpace;
967 
968                 // e
969                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 1));
970                 aNewString += aEmptySpace;
971 
972                 // f
973                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 1));
974                 aNewString += aEmptySpace;
975 
976                 // g
977                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 2));
978                 aNewString += aEmptySpace;
979 
980                 // h
981                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 2));
982                 aNewString += aEmptySpace;
983 
984                 // i
985                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 2));
986                 aNewString += aEmptySpace;
987 
988                 // j
989                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 3), true);
990                 aNewString += aEmptySpace;
991 
992                 // k
993                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 3), true);
994                 aNewString += aEmptySpace;
995 
996                 // l
997                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 3), true);
998 
999                 aNewString += aClosingBrace;
1000                 break;
1001             }
1002             default :
1003             {
1004                 DBG_ERROR("SdXMLImExTransform3D: impossible entry!");
1005                 break;
1006             }
1007         }
1008 
1009         // if not the last entry, add one space to next tag
1010         if(a + 1UL != maList.size())
1011         {
1012             aNewString += aEmptySpace;
1013         }
1014     }
1015 
1016     // fill string form OUString
1017     msString = aNewString;
1018 
1019     return msString;
1020 }
1021 
1022 //////////////////////////////////////////////////////////////////////////////
1023 // for Import: constructor with string, parses it and generates entries
SdXMLImExTransform3D(const OUString & rNew,const SvXMLUnitConverter & rConv)1024 SdXMLImExTransform3D::SdXMLImExTransform3D(const OUString& rNew, const SvXMLUnitConverter& rConv)
1025 {
1026     SetString(rNew, rConv);
1027 }
1028 
1029 //////////////////////////////////////////////////////////////////////////////
1030 // sets new string, parses it and generates entries
SetString(const OUString & rNew,const SvXMLUnitConverter & rConv)1031 void SdXMLImExTransform3D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
1032 {
1033     msString = rNew;
1034     EmptyList();
1035 
1036     if(msString.getLength())
1037     {
1038         const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength());
1039         const sal_Int32 nLen(aStr.getLength());
1040 
1041         const OUString aString_rotatex(OUString::createFromAscii("rotatex"));
1042         const OUString aString_rotatey(OUString::createFromAscii("rotatey"));
1043         const OUString aString_rotatez(OUString::createFromAscii("rotatez"));
1044         const OUString aString_scale(OUString::createFromAscii("scale"));
1045         const OUString aString_translate(OUString::createFromAscii("translate"));
1046         const OUString aString_matrix(OUString::createFromAscii("matrix"));
1047 
1048         sal_Int32 nPos(0);
1049 
1050         while(nPos < nLen)
1051         {
1052             // skip spaces
1053             Imp_SkipSpaces(aStr, nPos, nLen);
1054 
1055             // look for tag
1056             if(nPos < nLen)
1057             {
1058                 if(nPos == aStr.indexOf(aString_rotatex, nPos))
1059                 {
1060                     double fValue(0.0);
1061 
1062                     nPos += 7;
1063                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1064                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
1065                     if(fValue != 0.0)
1066                         maList.push_back(new ImpSdXMLExpTransObj3DRotateX(basegfx::deg2rad(fValue)));
1067 
1068                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1069                 }
1070                 else if(nPos == aStr.indexOf(aString_rotatey, nPos))
1071                 {
1072                     double fValue(0.0);
1073 
1074                     nPos += 7;
1075                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1076                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
1077                     if(fValue != 0.0)
1078                         maList.push_back(new ImpSdXMLExpTransObj3DRotateY(basegfx::deg2rad(fValue)));
1079 
1080                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1081                 }
1082                 else if(nPos == aStr.indexOf(aString_rotatez, nPos))
1083                 {
1084                     double fValue(0.0);
1085 
1086                     nPos += 7;
1087                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1088                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
1089                     if(fValue != 0.0)
1090                         maList.push_back(new ImpSdXMLExpTransObj3DRotateZ(basegfx::deg2rad(fValue)));
1091 
1092                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1093                 }
1094                 else if(nPos == aStr.indexOf(aString_scale, nPos))
1095                 {
1096                     ::basegfx::B3DTuple aValue(1.0, 1.0, 1.0);
1097 
1098                     nPos += 5;
1099                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1100                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
1101                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1102                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
1103                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1104                     aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ()));
1105 
1106                     if(1.0 != aValue.getX() || 1.0 != aValue.getY() || 1.0 != aValue.getZ())
1107                         maList.push_back(new ImpSdXMLExpTransObj3DScale(aValue));
1108 
1109                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1110                 }
1111                 else if(nPos == aStr.indexOf(aString_translate, nPos))
1112                 {
1113                     ::basegfx::B3DTuple aValue;
1114 
1115                     nPos += 9;
1116                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1117                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
1118                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1119                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
1120                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1121                     aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ(), true));
1122 
1123                     if(!aValue.equalZero())
1124                         maList.push_back(new ImpSdXMLExpTransObj3DTranslate(aValue));
1125 
1126                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1127                 }
1128                 else if(nPos == aStr.indexOf(aString_matrix, nPos))
1129                 {
1130                     ::basegfx::B3DHomMatrix aValue;
1131 
1132                     nPos += 6;
1133                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1134 
1135                     // a
1136                     aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
1137                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1138 
1139                     // b
1140                     aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
1141                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1142 
1143                     // c
1144                     aValue.set(2, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 0)));
1145                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1146 
1147                     // d
1148                     aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
1149                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1150 
1151                     // e
1152                     aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
1153                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1154 
1155                     // f
1156                     aValue.set(2, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 1)));
1157                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1158 
1159                     // g
1160                     aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2)));
1161                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1162 
1163                     // h
1164                     aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2)));
1165                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1166 
1167                     // i
1168                     aValue.set(2, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 2)));
1169                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1170 
1171                     // j
1172                     aValue.set(0, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 3), true));
1173                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1174 
1175                     // k
1176                     aValue.set(1, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 3), true));
1177                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1178 
1179                     // l
1180                     aValue.set(2, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 3), true));
1181                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1182 
1183                     if(!aValue.isIdentity())
1184                         maList.push_back(new ImpSdXMLExpTransObj3DMatrix(aValue));
1185 
1186                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1187                 }
1188                 else
1189                 {
1190                     nPos++;
1191                 }
1192             }
1193         }
1194     }
1195 }
1196 
GetFullHomogenTransform(com::sun::star::drawing::HomogenMatrix & xHomMat)1197 bool SdXMLImExTransform3D::GetFullHomogenTransform(com::sun::star::drawing::HomogenMatrix& xHomMat)
1198 {
1199     ::basegfx::B3DHomMatrix aFullTransform;
1200     GetFullTransform(aFullTransform);
1201 
1202     if(!aFullTransform.isIdentity())
1203     {
1204         xHomMat.Line1.Column1 = aFullTransform.get(0, 0);
1205         xHomMat.Line1.Column2 = aFullTransform.get(0, 1);
1206         xHomMat.Line1.Column3 = aFullTransform.get(0, 2);
1207         xHomMat.Line1.Column4 = aFullTransform.get(0, 3);
1208 
1209         xHomMat.Line2.Column1 = aFullTransform.get(1, 0);
1210         xHomMat.Line2.Column2 = aFullTransform.get(1, 1);
1211         xHomMat.Line2.Column3 = aFullTransform.get(1, 2);
1212         xHomMat.Line2.Column4 = aFullTransform.get(1, 3);
1213 
1214         xHomMat.Line3.Column1 = aFullTransform.get(2, 0);
1215         xHomMat.Line3.Column2 = aFullTransform.get(2, 1);
1216         xHomMat.Line3.Column3 = aFullTransform.get(2, 2);
1217         xHomMat.Line3.Column4 = aFullTransform.get(2, 3);
1218 
1219         xHomMat.Line4.Column1 = aFullTransform.get(3, 0);
1220         xHomMat.Line4.Column2 = aFullTransform.get(3, 1);
1221         xHomMat.Line4.Column3 = aFullTransform.get(3, 2);
1222         xHomMat.Line4.Column4 = aFullTransform.get(3, 3);
1223 
1224         return true;
1225     }
1226 
1227     return false;
1228 }
1229 
GetFullTransform(::basegfx::B3DHomMatrix & rFullTrans)1230 void SdXMLImExTransform3D::GetFullTransform(::basegfx::B3DHomMatrix& rFullTrans)
1231 {
1232     rFullTrans.identity();
1233 
1234     const sal_uInt32 nCount = maList.size();
1235     for(sal_uInt32 a(0L); a < nCount; a++)
1236     {
1237         ImpSdXMLExpTransObj3DBase* pObj = maList[a];
1238         switch(pObj->mnType)
1239         {
1240             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
1241             {
1242                 rFullTrans.rotate(((ImpSdXMLExpTransObj3DRotateX*)pObj)->mfRotateX, 0.0, 0.0);
1243                 break;
1244             }
1245             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
1246             {
1247                 rFullTrans.rotate(0.0, ((ImpSdXMLExpTransObj3DRotateY*)pObj)->mfRotateY, 0.0);
1248                 break;
1249             }
1250             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
1251             {
1252                 rFullTrans.rotate(0.0, 0.0, ((ImpSdXMLExpTransObj3DRotateZ*)pObj)->mfRotateZ);
1253                 break;
1254             }
1255             case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
1256             {
1257                 const ::basegfx::B3DTuple& rScale = ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale;
1258                 rFullTrans.scale(rScale.getX(), rScale.getY(), rScale.getZ());
1259                 break;
1260             }
1261             case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
1262             {
1263                 const ::basegfx::B3DTuple& rTranslate = ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate;
1264                 rFullTrans.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
1265                 break;
1266             }
1267             case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX     :
1268             {
1269                 rFullTrans *= ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix;
1270                 break;
1271             }
1272             default :
1273             {
1274                 DBG_ERROR("SdXMLImExTransform3D: impossible entry!");
1275                 break;
1276             }
1277         }
1278     }
1279 }
1280 
1281 //////////////////////////////////////////////////////////////////////////////
1282 //////////////////////////////////////////////////////////////////////////////
1283 
SdXMLImExViewBox(double fX,double fY,double fW,double fH)1284 SdXMLImExViewBox::SdXMLImExViewBox(double fX, double fY, double fW, double fH)
1285 :   mfX( fX ),
1286     mfY( fY ),
1287     mfW( fW ),
1288     mfH( fH )
1289 {
1290 }
1291 
1292 // #100617# Asked vincent hardy: svg:viewBox values may be double precision.
SdXMLImExViewBox(const OUString & rNew,const SvXMLUnitConverter & rConv)1293 SdXMLImExViewBox::SdXMLImExViewBox(const OUString& rNew, const SvXMLUnitConverter& rConv)
1294 :   msString(rNew),
1295     mfX( 0.0 ),
1296     mfY( 0.0 ),
1297     mfW( 1000.0 ),
1298     mfH( 1000.0 )
1299 {
1300     if(msString.getLength())
1301     {
1302         const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength());
1303         const sal_Int32 nLen(aStr.getLength());
1304         sal_Int32 nPos(0);
1305 
1306         // skip starting spaces
1307         Imp_SkipSpaces(aStr, nPos, nLen);
1308 
1309         // get mX, #100617# be prepared for doubles
1310         mfX = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfX);
1311 
1312         // skip spaces and commas
1313         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1314 
1315         // get mY, #100617# be prepared for doubles
1316         mfY = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfY);
1317 
1318         // skip spaces and commas
1319         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1320 
1321         // get mW, #100617# be prepared for doubles
1322         mfW = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfW);
1323 
1324         // skip spaces and commas
1325         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1326 
1327         // get mH, #100617# be prepared for doubles
1328         mfH = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfH);
1329     }
1330 }
1331 
GetExportString()1332 const OUString& SdXMLImExViewBox::GetExportString()
1333 {
1334     OUString aNewString;
1335     OUString aEmptySpace(sal_Unicode(' '));
1336 
1337     Imp_PutDoubleChar(aNewString, mfX);
1338     aNewString += aEmptySpace;
1339 
1340     Imp_PutDoubleChar(aNewString, mfY);
1341     aNewString += aEmptySpace;
1342 
1343     Imp_PutDoubleChar(aNewString, mfW);
1344     aNewString += aEmptySpace;
1345 
1346     Imp_PutDoubleChar(aNewString, mfH);
1347 
1348     // set new string
1349     msString = aNewString;
1350 
1351     return msString;
1352 }
1353 
1354 // eof
1355