xref: /trunk/main/xmloff/source/draw/xexptran.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_xmloff.hxx"
30*cdf0e10cSrcweir #include "xexptran.hxx"
31*cdf0e10cSrcweir #include <tools/debug.hxx>
32*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
33*cdf0e10cSrcweir #include <xmloff/xmluconv.hxx>
34*cdf0e10cSrcweir #include <tools/gen.hxx>
35*cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx>
36*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
37*cdf0e10cSrcweir #include <basegfx/tuple/b3dtuple.hxx>
38*cdf0e10cSrcweir #include <basegfx/matrix/b3dhommatrix.hxx>
39*cdf0e10cSrcweir #include <tools/string.hxx>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir using ::rtl::OUString;
42*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir using namespace ::com::sun::star;
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
47*cdf0e10cSrcweir // Defines
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #define BORDER_INTEGERS_ARE_EQUAL       (4)
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
52*cdf0e10cSrcweir // Predeclarations
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir void Imp_SkipDouble(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen);
55*cdf0e10cSrcweir void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection);
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
58*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
59*cdf0e10cSrcweir // parsing help functions for simple chars
60*cdf0e10cSrcweir void Imp_SkipSpaces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
61*cdf0e10cSrcweir {
62*cdf0e10cSrcweir     while(rPos < nLen
63*cdf0e10cSrcweir         && sal_Unicode(' ') == rStr[rPos])
64*cdf0e10cSrcweir         rPos++;
65*cdf0e10cSrcweir }
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir void Imp_SkipSpacesAndOpeningBraces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
68*cdf0e10cSrcweir {
69*cdf0e10cSrcweir     while(rPos < nLen
70*cdf0e10cSrcweir         && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode('(') == rStr[rPos]))
71*cdf0e10cSrcweir         rPos++;
72*cdf0e10cSrcweir }
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir void Imp_SkipSpacesAndCommas(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
75*cdf0e10cSrcweir {
76*cdf0e10cSrcweir     while(rPos < nLen
77*cdf0e10cSrcweir         && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode(',') == rStr[rPos]))
78*cdf0e10cSrcweir         rPos++;
79*cdf0e10cSrcweir }
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir void Imp_SkipSpacesAndClosingBraces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
82*cdf0e10cSrcweir {
83*cdf0e10cSrcweir     while(rPos < nLen
84*cdf0e10cSrcweir         && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode(')') == rStr[rPos]))
85*cdf0e10cSrcweir         rPos++;
86*cdf0e10cSrcweir }
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
89*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
90*cdf0e10cSrcweir // parsing help functions for integer numbers
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir bool Imp_IsOnNumberChar(const OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true)
93*cdf0e10cSrcweir {
94*cdf0e10cSrcweir     sal_Unicode aChar(rStr[nPos]);
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir     if((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
97*cdf0e10cSrcweir         || (bSignAllowed && sal_Unicode('+') == aChar)
98*cdf0e10cSrcweir         || (bSignAllowed && sal_Unicode('-') == aChar)
99*cdf0e10cSrcweir     )
100*cdf0e10cSrcweir         return true;
101*cdf0e10cSrcweir     return false;
102*cdf0e10cSrcweir }
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir bool Imp_IsOnUnitChar(const OUString& rStr, const sal_Int32 nPos)
105*cdf0e10cSrcweir {
106*cdf0e10cSrcweir     sal_Unicode aChar(rStr[nPos]);
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir     if((sal_Unicode('a') <= aChar && sal_Unicode('z') >= aChar)
109*cdf0e10cSrcweir         || (sal_Unicode('A') <= aChar && sal_Unicode('Z') >= aChar)
110*cdf0e10cSrcweir         || sal_Unicode('%') == aChar
111*cdf0e10cSrcweir     )
112*cdf0e10cSrcweir         return true;
113*cdf0e10cSrcweir     return false;
114*cdf0e10cSrcweir }
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir void Imp_SkipNumber(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen)
117*cdf0e10cSrcweir {
118*cdf0e10cSrcweir     bool bSignAllowed(true);
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir     while(rPos < nLen && Imp_IsOnNumberChar(rStr, rPos, bSignAllowed))
121*cdf0e10cSrcweir     {
122*cdf0e10cSrcweir         bSignAllowed = false;
123*cdf0e10cSrcweir         rPos++;
124*cdf0e10cSrcweir     }
125*cdf0e10cSrcweir }
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir void Imp_SkipNumberAndSpacesAndCommas(const OUString& rStr, sal_Int32& rPos,
128*cdf0e10cSrcweir     const sal_Int32 nLen)
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     Imp_SkipNumber(rStr, rPos, nLen);
131*cdf0e10cSrcweir     Imp_SkipSpacesAndCommas(rStr, rPos, nLen);
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir // #100617# Allow to skip doubles, too.
135*cdf0e10cSrcweir void Imp_SkipDoubleAndSpacesAndCommas(const OUString& rStr, sal_Int32& rPos,
136*cdf0e10cSrcweir     const sal_Int32 nLen)
137*cdf0e10cSrcweir {
138*cdf0e10cSrcweir     Imp_SkipDouble(rStr, rPos, nLen);
139*cdf0e10cSrcweir     Imp_SkipSpacesAndCommas(rStr, rPos, nLen);
140*cdf0e10cSrcweir }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir void Imp_PutNumberChar(OUString& rStr, sal_Int32 nValue)
143*cdf0e10cSrcweir {
144*cdf0e10cSrcweir     OUStringBuffer sStringBuffer;
145*cdf0e10cSrcweir     SvXMLUnitConverter::convertNumber(sStringBuffer, nValue);
146*cdf0e10cSrcweir     rStr += OUString(sStringBuffer.makeStringAndClear());
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir void Imp_PutNumberCharWithSpace(OUString& rStr, sal_Int32 nValue)
150*cdf0e10cSrcweir {
151*cdf0e10cSrcweir     const sal_Int32 aLen(rStr.getLength());
152*cdf0e10cSrcweir     if(aLen)
153*cdf0e10cSrcweir         if(Imp_IsOnNumberChar(rStr, aLen - 1, false) && nValue >= 0)
154*cdf0e10cSrcweir             rStr += String(sal_Unicode(' '));
155*cdf0e10cSrcweir     Imp_PutNumberChar(rStr, nValue);
156*cdf0e10cSrcweir }
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
159*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
160*cdf0e10cSrcweir // parsing help functions for double numbers
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir void Imp_SkipDouble(const OUString& rStr, sal_Int32& rPos, const sal_Int32)
163*cdf0e10cSrcweir {
164*cdf0e10cSrcweir     sal_Unicode aChar(rStr[rPos]);
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
167*cdf0e10cSrcweir         aChar = rStr[++rPos];
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir     while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
170*cdf0e10cSrcweir         || sal_Unicode('.') == aChar)
171*cdf0e10cSrcweir     {
172*cdf0e10cSrcweir         aChar = rStr[++rPos];
173*cdf0e10cSrcweir     }
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir     if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
176*cdf0e10cSrcweir     {
177*cdf0e10cSrcweir         aChar = rStr[++rPos];
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir         if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
180*cdf0e10cSrcweir             aChar = rStr[++rPos];
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir         while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
183*cdf0e10cSrcweir         {
184*cdf0e10cSrcweir             aChar = rStr[++rPos];
185*cdf0e10cSrcweir         }
186*cdf0e10cSrcweir     }
187*cdf0e10cSrcweir }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir double Imp_GetDoubleChar(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen,
190*cdf0e10cSrcweir     const SvXMLUnitConverter& rConv, double fRetval, bool bLookForUnits = false)
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir     sal_Unicode aChar(rStr[rPos]);
193*cdf0e10cSrcweir     OUStringBuffer sNumberString;
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir     if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
196*cdf0e10cSrcweir     {
197*cdf0e10cSrcweir         sNumberString.append(rStr[rPos]);
198*cdf0e10cSrcweir         aChar = rStr[++rPos];
199*cdf0e10cSrcweir     }
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir     while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
202*cdf0e10cSrcweir         || sal_Unicode('.') == aChar)
203*cdf0e10cSrcweir     {
204*cdf0e10cSrcweir         sNumberString.append(rStr[rPos]);
205*cdf0e10cSrcweir         aChar = rStr[++rPos];
206*cdf0e10cSrcweir     }
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir     if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
209*cdf0e10cSrcweir     {
210*cdf0e10cSrcweir         sNumberString.append(rStr[rPos]);
211*cdf0e10cSrcweir         aChar = rStr[++rPos];
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir         if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
214*cdf0e10cSrcweir         {
215*cdf0e10cSrcweir             sNumberString.append(rStr[rPos]);
216*cdf0e10cSrcweir             aChar = rStr[++rPos];
217*cdf0e10cSrcweir         }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir         while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
220*cdf0e10cSrcweir         {
221*cdf0e10cSrcweir             sNumberString.append(rStr[rPos]);
222*cdf0e10cSrcweir             aChar = rStr[++rPos];
223*cdf0e10cSrcweir         }
224*cdf0e10cSrcweir     }
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir     if(bLookForUnits)
227*cdf0e10cSrcweir     {
228*cdf0e10cSrcweir         Imp_SkipSpaces(rStr, rPos, nLen);
229*cdf0e10cSrcweir         while(rPos < nLen && Imp_IsOnUnitChar(rStr, rPos))
230*cdf0e10cSrcweir             sNumberString.append(rStr[rPos++]);
231*cdf0e10cSrcweir     }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir     if(sNumberString.getLength())
234*cdf0e10cSrcweir     {
235*cdf0e10cSrcweir         if(bLookForUnits)
236*cdf0e10cSrcweir             rConv.convertDouble(fRetval, sNumberString.makeStringAndClear(), true);
237*cdf0e10cSrcweir         else
238*cdf0e10cSrcweir             rConv.convertDouble(fRetval, sNumberString.makeStringAndClear());
239*cdf0e10cSrcweir     }
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir     return fRetval;
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir void Imp_PutDoubleChar(OUString& rStr, const SvXMLUnitConverter& rConv, double fValue,
245*cdf0e10cSrcweir     bool bConvertUnits = false)
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir     OUStringBuffer sStringBuffer;
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir     if(bConvertUnits)
250*cdf0e10cSrcweir         rConv.convertDouble(sStringBuffer, fValue, true);
251*cdf0e10cSrcweir     else
252*cdf0e10cSrcweir         rConv.convertDouble(sStringBuffer, fValue);
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir     rStr += OUString(sStringBuffer.makeStringAndClear());
255*cdf0e10cSrcweir }
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
258*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
259*cdf0e10cSrcweir // base class of all 2D transform objects
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DBase
262*cdf0e10cSrcweir {
263*cdf0e10cSrcweir     sal_uInt16                  mnType;
264*cdf0e10cSrcweir     ImpSdXMLExpTransObj2DBase(sal_uInt16 nType)
265*cdf0e10cSrcweir     :   mnType(nType) {}
266*cdf0e10cSrcweir };
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
269*cdf0e10cSrcweir // possible object types for 2D
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE          0x0000
272*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_SCALE           0x0001
273*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE       0x0002
274*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX           0x0003
275*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY           0x0004
276*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX          0x0005
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
279*cdf0e10cSrcweir // classes of objects, different sizes
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DRotate : public ImpSdXMLExpTransObj2DBase
282*cdf0e10cSrcweir {
283*cdf0e10cSrcweir     double                      mfRotate;
284*cdf0e10cSrcweir     ImpSdXMLExpTransObj2DRotate(double fVal)
285*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_ROTATE), mfRotate(fVal) {}
286*cdf0e10cSrcweir };
287*cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DScale : public ImpSdXMLExpTransObj2DBase
288*cdf0e10cSrcweir {
289*cdf0e10cSrcweir     ::basegfx::B2DTuple         maScale;
290*cdf0e10cSrcweir     ImpSdXMLExpTransObj2DScale(const ::basegfx::B2DTuple& rNew)
291*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SCALE), maScale(rNew) {}
292*cdf0e10cSrcweir };
293*cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DTranslate : public ImpSdXMLExpTransObj2DBase
294*cdf0e10cSrcweir {
295*cdf0e10cSrcweir     ::basegfx::B2DTuple         maTranslate;
296*cdf0e10cSrcweir     ImpSdXMLExpTransObj2DTranslate(const ::basegfx::B2DTuple& rNew)
297*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE), maTranslate(rNew) {}
298*cdf0e10cSrcweir };
299*cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DSkewX : public ImpSdXMLExpTransObj2DBase
300*cdf0e10cSrcweir {
301*cdf0e10cSrcweir     double                      mfSkewX;
302*cdf0e10cSrcweir     ImpSdXMLExpTransObj2DSkewX(double fVal)
303*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWX), mfSkewX(fVal) {}
304*cdf0e10cSrcweir };
305*cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DSkewY : public ImpSdXMLExpTransObj2DBase
306*cdf0e10cSrcweir {
307*cdf0e10cSrcweir     double                      mfSkewY;
308*cdf0e10cSrcweir     ImpSdXMLExpTransObj2DSkewY(double fVal)
309*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWY), mfSkewY(fVal) {}
310*cdf0e10cSrcweir };
311*cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DMatrix : public ImpSdXMLExpTransObj2DBase
312*cdf0e10cSrcweir {
313*cdf0e10cSrcweir     ::basegfx::B2DHomMatrix     maMatrix;
314*cdf0e10cSrcweir     ImpSdXMLExpTransObj2DMatrix(const ::basegfx::B2DHomMatrix& rNew)
315*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_MATRIX), maMatrix(rNew) {}
316*cdf0e10cSrcweir };
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
319*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
320*cdf0e10cSrcweir // delete all entries in list
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir void SdXMLImExTransform2D::EmptyList()
323*cdf0e10cSrcweir {
324*cdf0e10cSrcweir     const sal_uInt32 nCount = maList.size();
325*cdf0e10cSrcweir     for(sal_uInt32 a(0L); a < nCount; a++)
326*cdf0e10cSrcweir     {
327*cdf0e10cSrcweir         ImpSdXMLExpTransObj2DBase* pObj = maList[a];
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir         switch(pObj->mnType)
330*cdf0e10cSrcweir         {
331*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE     :
332*cdf0e10cSrcweir             {
333*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj2DRotate*)pObj;
334*cdf0e10cSrcweir                 break;
335*cdf0e10cSrcweir             }
336*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
337*cdf0e10cSrcweir             {
338*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj2DScale*)pObj;
339*cdf0e10cSrcweir                 break;
340*cdf0e10cSrcweir             }
341*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
342*cdf0e10cSrcweir             {
343*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj2DTranslate*)pObj;
344*cdf0e10cSrcweir                 break;
345*cdf0e10cSrcweir             }
346*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
347*cdf0e10cSrcweir             {
348*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj2DSkewX*)pObj;
349*cdf0e10cSrcweir                 break;
350*cdf0e10cSrcweir             }
351*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
352*cdf0e10cSrcweir             {
353*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj2DSkewY*)pObj;
354*cdf0e10cSrcweir                 break;
355*cdf0e10cSrcweir             }
356*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX     :
357*cdf0e10cSrcweir             {
358*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj2DMatrix*)pObj;
359*cdf0e10cSrcweir                 break;
360*cdf0e10cSrcweir             }
361*cdf0e10cSrcweir             default :
362*cdf0e10cSrcweir             {
363*cdf0e10cSrcweir                 DBG_ERROR("SdXMLImExTransform2D: impossible entry!");
364*cdf0e10cSrcweir                 break;
365*cdf0e10cSrcweir             }
366*cdf0e10cSrcweir         }
367*cdf0e10cSrcweir     }
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir     maList.clear();
370*cdf0e10cSrcweir }
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
373*cdf0e10cSrcweir // add members
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir void SdXMLImExTransform2D::AddRotate(double fNew)
376*cdf0e10cSrcweir {
377*cdf0e10cSrcweir     if(fNew != 0.0)
378*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj2DRotate(fNew));
379*cdf0e10cSrcweir }
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir void SdXMLImExTransform2D::AddScale(const ::basegfx::B2DTuple& rNew)
382*cdf0e10cSrcweir {
383*cdf0e10cSrcweir     if(1.0 != rNew.getX() || 1.0 != rNew.getY())
384*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj2DScale(rNew));
385*cdf0e10cSrcweir }
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir void SdXMLImExTransform2D::AddTranslate(const ::basegfx::B2DTuple& rNew)
388*cdf0e10cSrcweir {
389*cdf0e10cSrcweir     if(!rNew.equalZero())
390*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj2DTranslate(rNew));
391*cdf0e10cSrcweir }
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir void SdXMLImExTransform2D::AddSkewX(double fNew)
394*cdf0e10cSrcweir {
395*cdf0e10cSrcweir     if(fNew != 0.0)
396*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj2DSkewX(fNew));
397*cdf0e10cSrcweir }
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir void SdXMLImExTransform2D::AddSkewY(double fNew)
400*cdf0e10cSrcweir {
401*cdf0e10cSrcweir     if(fNew != 0.0)
402*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj2DSkewY(fNew));
403*cdf0e10cSrcweir }
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir void SdXMLImExTransform2D::AddMatrix(const ::basegfx::B2DHomMatrix& rNew)
406*cdf0e10cSrcweir {
407*cdf0e10cSrcweir     if(!rNew.isIdentity())
408*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj2DMatrix(rNew));
409*cdf0e10cSrcweir }
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
412*cdf0e10cSrcweir // gen string for export
413*cdf0e10cSrcweir const OUString& SdXMLImExTransform2D::GetExportString(const SvXMLUnitConverter& rConv)
414*cdf0e10cSrcweir {
415*cdf0e10cSrcweir     OUString aNewString;
416*cdf0e10cSrcweir     OUString aClosingBrace(sal_Unicode(')'));
417*cdf0e10cSrcweir     OUString aEmptySpace(sal_Unicode(' '));
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir     const sal_uInt32 nCount = maList.size();
420*cdf0e10cSrcweir     for(sal_uInt32 a(0L); a < nCount; a++)
421*cdf0e10cSrcweir     {
422*cdf0e10cSrcweir         ImpSdXMLExpTransObj2DBase* pObj = maList[a];
423*cdf0e10cSrcweir         switch(pObj->mnType)
424*cdf0e10cSrcweir         {
425*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE :
426*cdf0e10cSrcweir             {
427*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("rotate (");
428*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DRotate*)pObj)->mfRotate);
429*cdf0e10cSrcweir                 aNewString += aClosingBrace;
430*cdf0e10cSrcweir                 break;
431*cdf0e10cSrcweir             }
432*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
433*cdf0e10cSrcweir             {
434*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("scale (");
435*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale.getX());
436*cdf0e10cSrcweir                 aNewString += aEmptySpace;
437*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale.getY());
438*cdf0e10cSrcweir                 aNewString += aClosingBrace;
439*cdf0e10cSrcweir                 break;
440*cdf0e10cSrcweir             }
441*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
442*cdf0e10cSrcweir             {
443*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("translate (");
444*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate.getX(), true);
445*cdf0e10cSrcweir                 aNewString += aEmptySpace;
446*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate.getY(), true);
447*cdf0e10cSrcweir                 aNewString += aClosingBrace;
448*cdf0e10cSrcweir                 break;
449*cdf0e10cSrcweir             }
450*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
451*cdf0e10cSrcweir             {
452*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("skewX (");
453*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DSkewX*)pObj)->mfSkewX);
454*cdf0e10cSrcweir                 aNewString += aClosingBrace;
455*cdf0e10cSrcweir                 break;
456*cdf0e10cSrcweir             }
457*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
458*cdf0e10cSrcweir             {
459*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("skewY (");
460*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DSkewY*)pObj)->mfSkewY);
461*cdf0e10cSrcweir                 aNewString += aClosingBrace;
462*cdf0e10cSrcweir                 break;
463*cdf0e10cSrcweir             }
464*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX :
465*cdf0e10cSrcweir             {
466*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("matrix (");
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir                 // a
469*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 0));
470*cdf0e10cSrcweir                 aNewString += aEmptySpace;
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir                 // b
473*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 0));
474*cdf0e10cSrcweir                 aNewString += aEmptySpace;
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir                 // c
477*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 1));
478*cdf0e10cSrcweir                 aNewString += aEmptySpace;
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir                 // d
481*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 1));
482*cdf0e10cSrcweir                 aNewString += aEmptySpace;
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir                 // e
485*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 2), true);
486*cdf0e10cSrcweir                 aNewString += aEmptySpace;
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir                 // f
489*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 2), true);
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir                 aNewString += aClosingBrace;
492*cdf0e10cSrcweir                 break;
493*cdf0e10cSrcweir             }
494*cdf0e10cSrcweir             default :
495*cdf0e10cSrcweir             {
496*cdf0e10cSrcweir                 DBG_ERROR("SdXMLImExTransform2D: impossible entry!");
497*cdf0e10cSrcweir                 break;
498*cdf0e10cSrcweir             }
499*cdf0e10cSrcweir         }
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir         // if not the last entry, add one space to next tag
502*cdf0e10cSrcweir         if(a + 1UL != maList.size())
503*cdf0e10cSrcweir         {
504*cdf0e10cSrcweir             aNewString += aEmptySpace;
505*cdf0e10cSrcweir         }
506*cdf0e10cSrcweir     }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir     // fill string form OUString
509*cdf0e10cSrcweir     msString = aNewString;
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir     return msString;
512*cdf0e10cSrcweir }
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
515*cdf0e10cSrcweir // for Import: constructor with string, parses it and generates entries
516*cdf0e10cSrcweir SdXMLImExTransform2D::SdXMLImExTransform2D(const OUString& rNew, const SvXMLUnitConverter& rConv)
517*cdf0e10cSrcweir {
518*cdf0e10cSrcweir     SetString(rNew, rConv);
519*cdf0e10cSrcweir }
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
522*cdf0e10cSrcweir // sets new string, parses it and generates entries
523*cdf0e10cSrcweir void SdXMLImExTransform2D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
524*cdf0e10cSrcweir {
525*cdf0e10cSrcweir     msString = rNew;
526*cdf0e10cSrcweir     EmptyList();
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir     if(msString.getLength())
529*cdf0e10cSrcweir     {
530*cdf0e10cSrcweir         const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength());
531*cdf0e10cSrcweir         const sal_Int32 nLen(aStr.getLength());
532*cdf0e10cSrcweir 
533*cdf0e10cSrcweir         const OUString aString_rotate(OUString::createFromAscii("rotate"));
534*cdf0e10cSrcweir         const OUString aString_scale(OUString::createFromAscii("scale"));
535*cdf0e10cSrcweir         const OUString aString_translate(OUString::createFromAscii("translate"));
536*cdf0e10cSrcweir         const OUString aString_skewX(OUString::createFromAscii("skewX"));
537*cdf0e10cSrcweir         const OUString aString_skewY(OUString::createFromAscii("skewY"));
538*cdf0e10cSrcweir         const OUString aString_matrix(OUString::createFromAscii("matrix"));
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir         sal_Int32 nPos(0);
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir         while(nPos < nLen)
543*cdf0e10cSrcweir         {
544*cdf0e10cSrcweir             // skip spaces
545*cdf0e10cSrcweir             Imp_SkipSpaces(aStr, nPos, nLen);
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir             // look for tag
548*cdf0e10cSrcweir             if(nPos < nLen)
549*cdf0e10cSrcweir             {
550*cdf0e10cSrcweir                 if(nPos == aStr.indexOf(aString_rotate, nPos))
551*cdf0e10cSrcweir                 {
552*cdf0e10cSrcweir                     double fValue(0.0);
553*cdf0e10cSrcweir                     nPos += 6;
554*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
555*cdf0e10cSrcweir                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
556*cdf0e10cSrcweir                     if(fValue != 0.0)
557*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj2DRotate(fValue));
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
560*cdf0e10cSrcweir                 }
561*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_scale, nPos))
562*cdf0e10cSrcweir                 {
563*cdf0e10cSrcweir                     ::basegfx::B2DTuple aValue(1.0, 1.0);
564*cdf0e10cSrcweir                     nPos += 5;
565*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
566*cdf0e10cSrcweir                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
567*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
568*cdf0e10cSrcweir                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
569*cdf0e10cSrcweir 
570*cdf0e10cSrcweir                     if(aValue.getX() != 1.0 || aValue.getY() != 1.0)
571*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj2DScale(aValue));
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
574*cdf0e10cSrcweir                 }
575*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_translate, nPos))
576*cdf0e10cSrcweir                 {
577*cdf0e10cSrcweir                     ::basegfx::B2DTuple aValue;
578*cdf0e10cSrcweir                     nPos += 9;
579*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
580*cdf0e10cSrcweir                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
581*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
582*cdf0e10cSrcweir                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir                     if(!aValue.equalZero())
585*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj2DTranslate(aValue));
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
588*cdf0e10cSrcweir                 }
589*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_skewX, nPos))
590*cdf0e10cSrcweir                 {
591*cdf0e10cSrcweir                     double fValue(0.0);
592*cdf0e10cSrcweir                     nPos += 5;
593*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
594*cdf0e10cSrcweir                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
595*cdf0e10cSrcweir                     if(fValue != 0.0)
596*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj2DSkewX(fValue));
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
599*cdf0e10cSrcweir                 }
600*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_skewY, nPos))
601*cdf0e10cSrcweir                 {
602*cdf0e10cSrcweir                     double fValue(0.0);
603*cdf0e10cSrcweir                     nPos += 5;
604*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
605*cdf0e10cSrcweir                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
606*cdf0e10cSrcweir                     if(fValue != 0.0)
607*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj2DSkewY(fValue));
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
610*cdf0e10cSrcweir                 }
611*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_matrix, nPos))
612*cdf0e10cSrcweir                 {
613*cdf0e10cSrcweir                     ::basegfx::B2DHomMatrix aValue;
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir                     nPos += 6;
616*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir                     // a
619*cdf0e10cSrcweir                     aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
620*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir                     // b
623*cdf0e10cSrcweir                     aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
624*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir                     // c
627*cdf0e10cSrcweir                     aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
628*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
629*cdf0e10cSrcweir 
630*cdf0e10cSrcweir                     // d
631*cdf0e10cSrcweir                     aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
632*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
633*cdf0e10cSrcweir 
634*cdf0e10cSrcweir                     // e
635*cdf0e10cSrcweir                     aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2), true));
636*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir                     // f
639*cdf0e10cSrcweir                     aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2), true));
640*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir                     if(!aValue.isIdentity())
643*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj2DMatrix(aValue));
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
646*cdf0e10cSrcweir                 }
647*cdf0e10cSrcweir                 else
648*cdf0e10cSrcweir                 {
649*cdf0e10cSrcweir                     nPos++;
650*cdf0e10cSrcweir                 }
651*cdf0e10cSrcweir             }
652*cdf0e10cSrcweir         }
653*cdf0e10cSrcweir     }
654*cdf0e10cSrcweir }
655*cdf0e10cSrcweir 
656*cdf0e10cSrcweir void SdXMLImExTransform2D::GetFullTransform(::basegfx::B2DHomMatrix& rFullTrans)
657*cdf0e10cSrcweir {
658*cdf0e10cSrcweir     rFullTrans.identity();
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir     const sal_uInt32 nCount = maList.size();
661*cdf0e10cSrcweir     for(sal_uInt32 a(0L); a < nCount; a++)
662*cdf0e10cSrcweir     {
663*cdf0e10cSrcweir         ImpSdXMLExpTransObj2DBase* pObj = maList[a];
664*cdf0e10cSrcweir         switch(pObj->mnType)
665*cdf0e10cSrcweir         {
666*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE     :
667*cdf0e10cSrcweir             {
668*cdf0e10cSrcweir                 // #i78696#
669*cdf0e10cSrcweir                 // mfRotate is mathematically wrong oriented since we export/import the angle
670*cdf0e10cSrcweir                 // values mirrored. This error is fixed in the API, but not yet in the FileFormat.
671*cdf0e10cSrcweir                 // For the FileFormat there is a follow-up task (#i78698#) to fix this in the next
672*cdf0e10cSrcweir                 // ODF FileFormat version. For now - to emulate the old behaviour - it is necessary
673*cdf0e10cSrcweir                 // to mirror the value here
674*cdf0e10cSrcweir                 rFullTrans.rotate(((ImpSdXMLExpTransObj2DRotate*)pObj)->mfRotate * -1.0);
675*cdf0e10cSrcweir                 break;
676*cdf0e10cSrcweir             }
677*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
678*cdf0e10cSrcweir             {
679*cdf0e10cSrcweir                 const ::basegfx::B2DTuple& rScale = ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale;
680*cdf0e10cSrcweir                 rFullTrans.scale(rScale.getX(), rScale.getY());
681*cdf0e10cSrcweir                 break;
682*cdf0e10cSrcweir             }
683*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
684*cdf0e10cSrcweir             {
685*cdf0e10cSrcweir                 const ::basegfx::B2DTuple& rTranslate = ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate;
686*cdf0e10cSrcweir                 rFullTrans.translate(rTranslate.getX(), rTranslate.getY());
687*cdf0e10cSrcweir                 break;
688*cdf0e10cSrcweir             }
689*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
690*cdf0e10cSrcweir             {
691*cdf0e10cSrcweir                 rFullTrans.shearX(tan(((ImpSdXMLExpTransObj2DSkewX*)pObj)->mfSkewX));
692*cdf0e10cSrcweir                 break;
693*cdf0e10cSrcweir             }
694*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
695*cdf0e10cSrcweir             {
696*cdf0e10cSrcweir                 rFullTrans.shearY(tan(((ImpSdXMLExpTransObj2DSkewY*)pObj)->mfSkewY));
697*cdf0e10cSrcweir                 break;
698*cdf0e10cSrcweir             }
699*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX     :
700*cdf0e10cSrcweir             {
701*cdf0e10cSrcweir                 rFullTrans *= ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix;
702*cdf0e10cSrcweir                 break;
703*cdf0e10cSrcweir             }
704*cdf0e10cSrcweir             default :
705*cdf0e10cSrcweir             {
706*cdf0e10cSrcweir                 DBG_ERROR("SdXMLImExTransform2D: impossible entry!");
707*cdf0e10cSrcweir                 break;
708*cdf0e10cSrcweir             }
709*cdf0e10cSrcweir         }
710*cdf0e10cSrcweir     }
711*cdf0e10cSrcweir }
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
714*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
715*cdf0e10cSrcweir // base class of all 3D transform objects
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DBase
718*cdf0e10cSrcweir {
719*cdf0e10cSrcweir     sal_uInt16                  mnType;
720*cdf0e10cSrcweir     ImpSdXMLExpTransObj3DBase(sal_uInt16 nType)
721*cdf0e10cSrcweir     :   mnType(nType) {}
722*cdf0e10cSrcweir };
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
725*cdf0e10cSrcweir // possible object types for 3D
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X        0x0000
728*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y        0x0001
729*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z        0x0002
730*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_SCALE           0x0003
731*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE       0x0004
732*cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX          0x0005
733*cdf0e10cSrcweir 
734*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
735*cdf0e10cSrcweir // classes of objects, different sizes
736*cdf0e10cSrcweir 
737*cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DRotateX : public ImpSdXMLExpTransObj3DBase
738*cdf0e10cSrcweir {
739*cdf0e10cSrcweir     double                      mfRotateX;
740*cdf0e10cSrcweir     ImpSdXMLExpTransObj3DRotateX(double fVal)
741*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X), mfRotateX(fVal) {}
742*cdf0e10cSrcweir };
743*cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DRotateY : public ImpSdXMLExpTransObj3DBase
744*cdf0e10cSrcweir {
745*cdf0e10cSrcweir     double                      mfRotateY;
746*cdf0e10cSrcweir     ImpSdXMLExpTransObj3DRotateY(double fVal)
747*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y), mfRotateY(fVal) {}
748*cdf0e10cSrcweir };
749*cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DRotateZ : public ImpSdXMLExpTransObj3DBase
750*cdf0e10cSrcweir {
751*cdf0e10cSrcweir     double                      mfRotateZ;
752*cdf0e10cSrcweir     ImpSdXMLExpTransObj3DRotateZ(double fVal)
753*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z), mfRotateZ(fVal) {}
754*cdf0e10cSrcweir };
755*cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DScale : public ImpSdXMLExpTransObj3DBase
756*cdf0e10cSrcweir {
757*cdf0e10cSrcweir     ::basegfx::B3DTuple         maScale;
758*cdf0e10cSrcweir     ImpSdXMLExpTransObj3DScale(const ::basegfx::B3DTuple& rNew)
759*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_SCALE), maScale(rNew) {}
760*cdf0e10cSrcweir };
761*cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DTranslate : public ImpSdXMLExpTransObj3DBase
762*cdf0e10cSrcweir {
763*cdf0e10cSrcweir     ::basegfx::B3DTuple         maTranslate;
764*cdf0e10cSrcweir     ImpSdXMLExpTransObj3DTranslate(const ::basegfx::B3DTuple& rNew)
765*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE), maTranslate(rNew) {}
766*cdf0e10cSrcweir };
767*cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DMatrix : public ImpSdXMLExpTransObj3DBase
768*cdf0e10cSrcweir {
769*cdf0e10cSrcweir     ::basegfx::B3DHomMatrix     maMatrix;
770*cdf0e10cSrcweir     ImpSdXMLExpTransObj3DMatrix(const ::basegfx::B3DHomMatrix& rNew)
771*cdf0e10cSrcweir     :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_MATRIX), maMatrix(rNew) {}
772*cdf0e10cSrcweir };
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
775*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
776*cdf0e10cSrcweir // delete all entries in list
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir void SdXMLImExTransform3D::EmptyList()
779*cdf0e10cSrcweir {
780*cdf0e10cSrcweir     const sal_uInt32 nCount = maList.size();
781*cdf0e10cSrcweir     for(sal_uInt32 a(0L); a < nCount; a++)
782*cdf0e10cSrcweir     {
783*cdf0e10cSrcweir         ImpSdXMLExpTransObj3DBase* pObj = maList[a];
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir         switch(pObj->mnType)
786*cdf0e10cSrcweir         {
787*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
788*cdf0e10cSrcweir             {
789*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj3DRotateX*)pObj;
790*cdf0e10cSrcweir                 break;
791*cdf0e10cSrcweir             }
792*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
793*cdf0e10cSrcweir             {
794*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj3DRotateY*)pObj;
795*cdf0e10cSrcweir                 break;
796*cdf0e10cSrcweir             }
797*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
798*cdf0e10cSrcweir             {
799*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj3DRotateZ*)pObj;
800*cdf0e10cSrcweir                 break;
801*cdf0e10cSrcweir             }
802*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
803*cdf0e10cSrcweir             {
804*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj3DScale*)pObj;
805*cdf0e10cSrcweir                 break;
806*cdf0e10cSrcweir             }
807*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
808*cdf0e10cSrcweir             {
809*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj3DTranslate*)pObj;
810*cdf0e10cSrcweir                 break;
811*cdf0e10cSrcweir             }
812*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX     :
813*cdf0e10cSrcweir             {
814*cdf0e10cSrcweir                 delete (ImpSdXMLExpTransObj3DMatrix*)pObj;
815*cdf0e10cSrcweir                 break;
816*cdf0e10cSrcweir             }
817*cdf0e10cSrcweir             default :
818*cdf0e10cSrcweir             {
819*cdf0e10cSrcweir                 DBG_ERROR("SdXMLImExTransform3D: impossible entry!");
820*cdf0e10cSrcweir                 break;
821*cdf0e10cSrcweir             }
822*cdf0e10cSrcweir         }
823*cdf0e10cSrcweir     }
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir     maList.clear();
826*cdf0e10cSrcweir }
827*cdf0e10cSrcweir 
828*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
829*cdf0e10cSrcweir // add members
830*cdf0e10cSrcweir 
831*cdf0e10cSrcweir void SdXMLImExTransform3D::AddRotateX(double fNew)
832*cdf0e10cSrcweir {
833*cdf0e10cSrcweir     if(fNew != 0.0)
834*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj3DRotateX(fNew));
835*cdf0e10cSrcweir }
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir void SdXMLImExTransform3D::AddRotateY(double fNew)
838*cdf0e10cSrcweir {
839*cdf0e10cSrcweir     if(fNew != 0.0)
840*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj3DRotateY(fNew));
841*cdf0e10cSrcweir }
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir void SdXMLImExTransform3D::AddRotateZ(double fNew)
844*cdf0e10cSrcweir {
845*cdf0e10cSrcweir     if(fNew != 0.0)
846*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj3DRotateZ(fNew));
847*cdf0e10cSrcweir }
848*cdf0e10cSrcweir 
849*cdf0e10cSrcweir void SdXMLImExTransform3D::AddScale(const ::basegfx::B3DTuple& rNew)
850*cdf0e10cSrcweir {
851*cdf0e10cSrcweir     if(1.0 != rNew.getX() || 1.0 != rNew.getY() || 1.0 != rNew.getZ())
852*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj3DScale(rNew));
853*cdf0e10cSrcweir }
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir void SdXMLImExTransform3D::AddTranslate(const ::basegfx::B3DTuple& rNew)
856*cdf0e10cSrcweir {
857*cdf0e10cSrcweir     if(!rNew.equalZero())
858*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj3DTranslate(rNew));
859*cdf0e10cSrcweir }
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir void SdXMLImExTransform3D::AddMatrix(const ::basegfx::B3DHomMatrix& rNew)
862*cdf0e10cSrcweir {
863*cdf0e10cSrcweir     if(!rNew.isIdentity())
864*cdf0e10cSrcweir         maList.push_back(new ImpSdXMLExpTransObj3DMatrix(rNew));
865*cdf0e10cSrcweir }
866*cdf0e10cSrcweir 
867*cdf0e10cSrcweir void SdXMLImExTransform3D::AddHomogenMatrix(const drawing::HomogenMatrix& xHomMat)
868*cdf0e10cSrcweir {
869*cdf0e10cSrcweir     ::basegfx::B3DHomMatrix aExportMatrix;
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir     aExportMatrix.set(0, 0, xHomMat.Line1.Column1);
872*cdf0e10cSrcweir     aExportMatrix.set(0, 1, xHomMat.Line1.Column2);
873*cdf0e10cSrcweir     aExportMatrix.set(0, 2, xHomMat.Line1.Column3);
874*cdf0e10cSrcweir     aExportMatrix.set(0, 3, xHomMat.Line1.Column4);
875*cdf0e10cSrcweir     aExportMatrix.set(1, 0, xHomMat.Line2.Column1);
876*cdf0e10cSrcweir     aExportMatrix.set(1, 1, xHomMat.Line2.Column2);
877*cdf0e10cSrcweir     aExportMatrix.set(1, 2, xHomMat.Line2.Column3);
878*cdf0e10cSrcweir     aExportMatrix.set(1, 3, xHomMat.Line2.Column4);
879*cdf0e10cSrcweir     aExportMatrix.set(2, 0, xHomMat.Line3.Column1);
880*cdf0e10cSrcweir     aExportMatrix.set(2, 1, xHomMat.Line3.Column2);
881*cdf0e10cSrcweir     aExportMatrix.set(2, 2, xHomMat.Line3.Column3);
882*cdf0e10cSrcweir     aExportMatrix.set(2, 3, xHomMat.Line3.Column4);
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir     AddMatrix(aExportMatrix);
885*cdf0e10cSrcweir }
886*cdf0e10cSrcweir 
887*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
888*cdf0e10cSrcweir // gen string for export
889*cdf0e10cSrcweir const OUString& SdXMLImExTransform3D::GetExportString(const SvXMLUnitConverter& rConv)
890*cdf0e10cSrcweir {
891*cdf0e10cSrcweir     OUString aNewString;
892*cdf0e10cSrcweir     OUString aClosingBrace(sal_Unicode(')'));
893*cdf0e10cSrcweir     OUString aEmptySpace(sal_Unicode(' '));
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir     const sal_uInt32 nCount = maList.size();
896*cdf0e10cSrcweir     for(sal_uInt32 a(0L); a < nCount; a++)
897*cdf0e10cSrcweir     {
898*cdf0e10cSrcweir         ImpSdXMLExpTransObj3DBase* pObj = maList[a];
899*cdf0e10cSrcweir         switch(pObj->mnType)
900*cdf0e10cSrcweir         {
901*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
902*cdf0e10cSrcweir             {
903*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("rotatex (");
904*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DRotateX*)pObj)->mfRotateX);
905*cdf0e10cSrcweir                 aNewString += aClosingBrace;
906*cdf0e10cSrcweir                 break;
907*cdf0e10cSrcweir             }
908*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
909*cdf0e10cSrcweir             {
910*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("rotatey (");
911*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DRotateY*)pObj)->mfRotateY);
912*cdf0e10cSrcweir                 aNewString += aClosingBrace;
913*cdf0e10cSrcweir                 break;
914*cdf0e10cSrcweir             }
915*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
916*cdf0e10cSrcweir             {
917*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("rotatez (");
918*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DRotateZ*)pObj)->mfRotateZ);
919*cdf0e10cSrcweir                 aNewString += aClosingBrace;
920*cdf0e10cSrcweir                 break;
921*cdf0e10cSrcweir             }
922*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
923*cdf0e10cSrcweir             {
924*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("scale (");
925*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getX());
926*cdf0e10cSrcweir                 aNewString += aEmptySpace;
927*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getY());
928*cdf0e10cSrcweir                 aNewString += aEmptySpace;
929*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getZ());
930*cdf0e10cSrcweir                 aNewString += aClosingBrace;
931*cdf0e10cSrcweir                 break;
932*cdf0e10cSrcweir             }
933*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
934*cdf0e10cSrcweir             {
935*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("translate (");
936*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getX(), true);
937*cdf0e10cSrcweir                 aNewString += aEmptySpace;
938*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getY(), true);
939*cdf0e10cSrcweir                 aNewString += aEmptySpace;
940*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getZ(), true);
941*cdf0e10cSrcweir                 aNewString += aClosingBrace;
942*cdf0e10cSrcweir                 break;
943*cdf0e10cSrcweir             }
944*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX :
945*cdf0e10cSrcweir             {
946*cdf0e10cSrcweir                 aNewString += OUString::createFromAscii("matrix (");
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir                 // a
949*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 0));
950*cdf0e10cSrcweir                 aNewString += aEmptySpace;
951*cdf0e10cSrcweir 
952*cdf0e10cSrcweir                 // b
953*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 0));
954*cdf0e10cSrcweir                 aNewString += aEmptySpace;
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir                 // c
957*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 0));
958*cdf0e10cSrcweir                 aNewString += aEmptySpace;
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir                 // d
961*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 1));
962*cdf0e10cSrcweir                 aNewString += aEmptySpace;
963*cdf0e10cSrcweir 
964*cdf0e10cSrcweir                 // e
965*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 1));
966*cdf0e10cSrcweir                 aNewString += aEmptySpace;
967*cdf0e10cSrcweir 
968*cdf0e10cSrcweir                 // f
969*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 1));
970*cdf0e10cSrcweir                 aNewString += aEmptySpace;
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir                 // g
973*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 2));
974*cdf0e10cSrcweir                 aNewString += aEmptySpace;
975*cdf0e10cSrcweir 
976*cdf0e10cSrcweir                 // h
977*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 2));
978*cdf0e10cSrcweir                 aNewString += aEmptySpace;
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir                 // i
981*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 2));
982*cdf0e10cSrcweir                 aNewString += aEmptySpace;
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir                 // j
985*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 3), true);
986*cdf0e10cSrcweir                 aNewString += aEmptySpace;
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir                 // k
989*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 3), true);
990*cdf0e10cSrcweir                 aNewString += aEmptySpace;
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir                 // l
993*cdf0e10cSrcweir                 Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 3), true);
994*cdf0e10cSrcweir 
995*cdf0e10cSrcweir                 aNewString += aClosingBrace;
996*cdf0e10cSrcweir                 break;
997*cdf0e10cSrcweir             }
998*cdf0e10cSrcweir             default :
999*cdf0e10cSrcweir             {
1000*cdf0e10cSrcweir                 DBG_ERROR("SdXMLImExTransform3D: impossible entry!");
1001*cdf0e10cSrcweir                 break;
1002*cdf0e10cSrcweir             }
1003*cdf0e10cSrcweir         }
1004*cdf0e10cSrcweir 
1005*cdf0e10cSrcweir         // if not the last entry, add one space to next tag
1006*cdf0e10cSrcweir         if(a + 1UL != maList.size())
1007*cdf0e10cSrcweir         {
1008*cdf0e10cSrcweir             aNewString += aEmptySpace;
1009*cdf0e10cSrcweir         }
1010*cdf0e10cSrcweir     }
1011*cdf0e10cSrcweir 
1012*cdf0e10cSrcweir     // fill string form OUString
1013*cdf0e10cSrcweir     msString = aNewString;
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir     return msString;
1016*cdf0e10cSrcweir }
1017*cdf0e10cSrcweir 
1018*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1019*cdf0e10cSrcweir // for Import: constructor with string, parses it and generates entries
1020*cdf0e10cSrcweir SdXMLImExTransform3D::SdXMLImExTransform3D(const OUString& rNew, const SvXMLUnitConverter& rConv)
1021*cdf0e10cSrcweir {
1022*cdf0e10cSrcweir     SetString(rNew, rConv);
1023*cdf0e10cSrcweir }
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1026*cdf0e10cSrcweir // sets new string, parses it and generates entries
1027*cdf0e10cSrcweir void SdXMLImExTransform3D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
1028*cdf0e10cSrcweir {
1029*cdf0e10cSrcweir     msString = rNew;
1030*cdf0e10cSrcweir     EmptyList();
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir     if(msString.getLength())
1033*cdf0e10cSrcweir     {
1034*cdf0e10cSrcweir         const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength());
1035*cdf0e10cSrcweir         const sal_Int32 nLen(aStr.getLength());
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir         const OUString aString_rotatex(OUString::createFromAscii("rotatex"));
1038*cdf0e10cSrcweir         const OUString aString_rotatey(OUString::createFromAscii("rotatey"));
1039*cdf0e10cSrcweir         const OUString aString_rotatez(OUString::createFromAscii("rotatez"));
1040*cdf0e10cSrcweir         const OUString aString_scale(OUString::createFromAscii("scale"));
1041*cdf0e10cSrcweir         const OUString aString_translate(OUString::createFromAscii("translate"));
1042*cdf0e10cSrcweir         const OUString aString_matrix(OUString::createFromAscii("matrix"));
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir         sal_Int32 nPos(0);
1045*cdf0e10cSrcweir 
1046*cdf0e10cSrcweir         while(nPos < nLen)
1047*cdf0e10cSrcweir         {
1048*cdf0e10cSrcweir             // skip spaces
1049*cdf0e10cSrcweir             Imp_SkipSpaces(aStr, nPos, nLen);
1050*cdf0e10cSrcweir 
1051*cdf0e10cSrcweir             // look for tag
1052*cdf0e10cSrcweir             if(nPos < nLen)
1053*cdf0e10cSrcweir             {
1054*cdf0e10cSrcweir                 if(nPos == aStr.indexOf(aString_rotatex, nPos))
1055*cdf0e10cSrcweir                 {
1056*cdf0e10cSrcweir                     double fValue(0.0);
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir                     nPos += 7;
1059*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1060*cdf0e10cSrcweir                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
1061*cdf0e10cSrcweir                     if(fValue != 0.0)
1062*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj3DRotateX(fValue));
1063*cdf0e10cSrcweir 
1064*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1065*cdf0e10cSrcweir                 }
1066*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_rotatey, nPos))
1067*cdf0e10cSrcweir                 {
1068*cdf0e10cSrcweir                     double fValue(0.0);
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir                     nPos += 7;
1071*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1072*cdf0e10cSrcweir                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
1073*cdf0e10cSrcweir                     if(fValue != 0.0)
1074*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj3DRotateY(fValue));
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1077*cdf0e10cSrcweir                 }
1078*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_rotatez, nPos))
1079*cdf0e10cSrcweir                 {
1080*cdf0e10cSrcweir                     double fValue(0.0);
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir                     nPos += 7;
1083*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1084*cdf0e10cSrcweir                     fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
1085*cdf0e10cSrcweir                     if(fValue != 0.0)
1086*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj3DRotateZ(fValue));
1087*cdf0e10cSrcweir 
1088*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1089*cdf0e10cSrcweir                 }
1090*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_scale, nPos))
1091*cdf0e10cSrcweir                 {
1092*cdf0e10cSrcweir                     ::basegfx::B3DTuple aValue(1.0, 1.0, 1.0);
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir                     nPos += 5;
1095*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1096*cdf0e10cSrcweir                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
1097*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1098*cdf0e10cSrcweir                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
1099*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1100*cdf0e10cSrcweir                     aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ()));
1101*cdf0e10cSrcweir 
1102*cdf0e10cSrcweir                     if(1.0 != aValue.getX() || 1.0 != aValue.getY() || 1.0 != aValue.getZ())
1103*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj3DScale(aValue));
1104*cdf0e10cSrcweir 
1105*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1106*cdf0e10cSrcweir                 }
1107*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_translate, nPos))
1108*cdf0e10cSrcweir                 {
1109*cdf0e10cSrcweir                     ::basegfx::B3DTuple aValue;
1110*cdf0e10cSrcweir 
1111*cdf0e10cSrcweir                     nPos += 9;
1112*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1113*cdf0e10cSrcweir                     aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
1114*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1115*cdf0e10cSrcweir                     aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
1116*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1117*cdf0e10cSrcweir                     aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ(), true));
1118*cdf0e10cSrcweir 
1119*cdf0e10cSrcweir                     if(!aValue.equalZero())
1120*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj3DTranslate(aValue));
1121*cdf0e10cSrcweir 
1122*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1123*cdf0e10cSrcweir                 }
1124*cdf0e10cSrcweir                 else if(nPos == aStr.indexOf(aString_matrix, nPos))
1125*cdf0e10cSrcweir                 {
1126*cdf0e10cSrcweir                     ::basegfx::B3DHomMatrix aValue;
1127*cdf0e10cSrcweir 
1128*cdf0e10cSrcweir                     nPos += 6;
1129*cdf0e10cSrcweir                     Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
1130*cdf0e10cSrcweir 
1131*cdf0e10cSrcweir                     // a
1132*cdf0e10cSrcweir                     aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
1133*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1134*cdf0e10cSrcweir 
1135*cdf0e10cSrcweir                     // b
1136*cdf0e10cSrcweir                     aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
1137*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir                     // c
1140*cdf0e10cSrcweir                     aValue.set(2, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 0)));
1141*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1142*cdf0e10cSrcweir 
1143*cdf0e10cSrcweir                     // d
1144*cdf0e10cSrcweir                     aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
1145*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir                     // e
1148*cdf0e10cSrcweir                     aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
1149*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1150*cdf0e10cSrcweir 
1151*cdf0e10cSrcweir                     // f
1152*cdf0e10cSrcweir                     aValue.set(2, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 1)));
1153*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1154*cdf0e10cSrcweir 
1155*cdf0e10cSrcweir                     // g
1156*cdf0e10cSrcweir                     aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2)));
1157*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir                     // h
1160*cdf0e10cSrcweir                     aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2)));
1161*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1162*cdf0e10cSrcweir 
1163*cdf0e10cSrcweir                     // i
1164*cdf0e10cSrcweir                     aValue.set(2, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 2)));
1165*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1166*cdf0e10cSrcweir 
1167*cdf0e10cSrcweir                     // j
1168*cdf0e10cSrcweir                     aValue.set(0, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 3), true));
1169*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1170*cdf0e10cSrcweir 
1171*cdf0e10cSrcweir                     // k
1172*cdf0e10cSrcweir                     aValue.set(1, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 3), true));
1173*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1174*cdf0e10cSrcweir 
1175*cdf0e10cSrcweir                     // l
1176*cdf0e10cSrcweir                     aValue.set(2, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 3), true));
1177*cdf0e10cSrcweir                     Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1178*cdf0e10cSrcweir 
1179*cdf0e10cSrcweir                     if(!aValue.isIdentity())
1180*cdf0e10cSrcweir                         maList.push_back(new ImpSdXMLExpTransObj3DMatrix(aValue));
1181*cdf0e10cSrcweir 
1182*cdf0e10cSrcweir                     Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
1183*cdf0e10cSrcweir                 }
1184*cdf0e10cSrcweir                 else
1185*cdf0e10cSrcweir                 {
1186*cdf0e10cSrcweir                     nPos++;
1187*cdf0e10cSrcweir                 }
1188*cdf0e10cSrcweir             }
1189*cdf0e10cSrcweir         }
1190*cdf0e10cSrcweir     }
1191*cdf0e10cSrcweir }
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir bool SdXMLImExTransform3D::GetFullHomogenTransform(com::sun::star::drawing::HomogenMatrix& xHomMat)
1194*cdf0e10cSrcweir {
1195*cdf0e10cSrcweir     ::basegfx::B3DHomMatrix aFullTransform;
1196*cdf0e10cSrcweir     GetFullTransform(aFullTransform);
1197*cdf0e10cSrcweir 
1198*cdf0e10cSrcweir     if(!aFullTransform.isIdentity())
1199*cdf0e10cSrcweir     {
1200*cdf0e10cSrcweir         xHomMat.Line1.Column1 = aFullTransform.get(0, 0);
1201*cdf0e10cSrcweir         xHomMat.Line1.Column2 = aFullTransform.get(0, 1);
1202*cdf0e10cSrcweir         xHomMat.Line1.Column3 = aFullTransform.get(0, 2);
1203*cdf0e10cSrcweir         xHomMat.Line1.Column4 = aFullTransform.get(0, 3);
1204*cdf0e10cSrcweir 
1205*cdf0e10cSrcweir         xHomMat.Line2.Column1 = aFullTransform.get(1, 0);
1206*cdf0e10cSrcweir         xHomMat.Line2.Column2 = aFullTransform.get(1, 1);
1207*cdf0e10cSrcweir         xHomMat.Line2.Column3 = aFullTransform.get(1, 2);
1208*cdf0e10cSrcweir         xHomMat.Line2.Column4 = aFullTransform.get(1, 3);
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir         xHomMat.Line3.Column1 = aFullTransform.get(2, 0);
1211*cdf0e10cSrcweir         xHomMat.Line3.Column2 = aFullTransform.get(2, 1);
1212*cdf0e10cSrcweir         xHomMat.Line3.Column3 = aFullTransform.get(2, 2);
1213*cdf0e10cSrcweir         xHomMat.Line3.Column4 = aFullTransform.get(2, 3);
1214*cdf0e10cSrcweir 
1215*cdf0e10cSrcweir         xHomMat.Line4.Column1 = aFullTransform.get(3, 0);
1216*cdf0e10cSrcweir         xHomMat.Line4.Column2 = aFullTransform.get(3, 1);
1217*cdf0e10cSrcweir         xHomMat.Line4.Column3 = aFullTransform.get(3, 2);
1218*cdf0e10cSrcweir         xHomMat.Line4.Column4 = aFullTransform.get(3, 3);
1219*cdf0e10cSrcweir 
1220*cdf0e10cSrcweir         return true;
1221*cdf0e10cSrcweir     }
1222*cdf0e10cSrcweir 
1223*cdf0e10cSrcweir     return false;
1224*cdf0e10cSrcweir }
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir void SdXMLImExTransform3D::GetFullTransform(::basegfx::B3DHomMatrix& rFullTrans)
1227*cdf0e10cSrcweir {
1228*cdf0e10cSrcweir     rFullTrans.identity();
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir     const sal_uInt32 nCount = maList.size();
1231*cdf0e10cSrcweir     for(sal_uInt32 a(0L); a < nCount; a++)
1232*cdf0e10cSrcweir     {
1233*cdf0e10cSrcweir         ImpSdXMLExpTransObj3DBase* pObj = maList[a];
1234*cdf0e10cSrcweir         switch(pObj->mnType)
1235*cdf0e10cSrcweir         {
1236*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
1237*cdf0e10cSrcweir             {
1238*cdf0e10cSrcweir                 rFullTrans.rotate(((ImpSdXMLExpTransObj3DRotateX*)pObj)->mfRotateX, 0.0, 0.0);
1239*cdf0e10cSrcweir                 break;
1240*cdf0e10cSrcweir             }
1241*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
1242*cdf0e10cSrcweir             {
1243*cdf0e10cSrcweir                 rFullTrans.rotate(0.0, ((ImpSdXMLExpTransObj3DRotateY*)pObj)->mfRotateY, 0.0);
1244*cdf0e10cSrcweir                 break;
1245*cdf0e10cSrcweir             }
1246*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
1247*cdf0e10cSrcweir             {
1248*cdf0e10cSrcweir                 rFullTrans.rotate(0.0, 0.0, ((ImpSdXMLExpTransObj3DRotateZ*)pObj)->mfRotateZ);
1249*cdf0e10cSrcweir                 break;
1250*cdf0e10cSrcweir             }
1251*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
1252*cdf0e10cSrcweir             {
1253*cdf0e10cSrcweir                 const ::basegfx::B3DTuple& rScale = ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale;
1254*cdf0e10cSrcweir                 rFullTrans.scale(rScale.getX(), rScale.getY(), rScale.getZ());
1255*cdf0e10cSrcweir                 break;
1256*cdf0e10cSrcweir             }
1257*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
1258*cdf0e10cSrcweir             {
1259*cdf0e10cSrcweir                 const ::basegfx::B3DTuple& rTranslate = ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate;
1260*cdf0e10cSrcweir                 rFullTrans.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
1261*cdf0e10cSrcweir                 break;
1262*cdf0e10cSrcweir             }
1263*cdf0e10cSrcweir             case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX     :
1264*cdf0e10cSrcweir             {
1265*cdf0e10cSrcweir                 rFullTrans *= ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix;
1266*cdf0e10cSrcweir                 break;
1267*cdf0e10cSrcweir             }
1268*cdf0e10cSrcweir             default :
1269*cdf0e10cSrcweir             {
1270*cdf0e10cSrcweir                 DBG_ERROR("SdXMLImExTransform3D: impossible entry!");
1271*cdf0e10cSrcweir                 break;
1272*cdf0e10cSrcweir             }
1273*cdf0e10cSrcweir         }
1274*cdf0e10cSrcweir     }
1275*cdf0e10cSrcweir }
1276*cdf0e10cSrcweir 
1277*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1278*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1279*cdf0e10cSrcweir 
1280*cdf0e10cSrcweir SdXMLImExViewBox::SdXMLImExViewBox(sal_Int32 nX, sal_Int32 nY, sal_Int32 nW, sal_Int32 nH)
1281*cdf0e10cSrcweir :   mnX( nX ),
1282*cdf0e10cSrcweir     mnY( nY ),
1283*cdf0e10cSrcweir     mnW( nW ),
1284*cdf0e10cSrcweir     mnH( nH )
1285*cdf0e10cSrcweir {
1286*cdf0e10cSrcweir }
1287*cdf0e10cSrcweir 
1288*cdf0e10cSrcweir // #100617# Asked vincent hardy: svg:viewBox values may be double precision.
1289*cdf0e10cSrcweir SdXMLImExViewBox::SdXMLImExViewBox(const OUString& rNew, const SvXMLUnitConverter& rConv)
1290*cdf0e10cSrcweir :   msString(rNew),
1291*cdf0e10cSrcweir     mnX( 0L ),
1292*cdf0e10cSrcweir     mnY( 0L ),
1293*cdf0e10cSrcweir     mnW( 1000L ),
1294*cdf0e10cSrcweir     mnH( 1000L )
1295*cdf0e10cSrcweir {
1296*cdf0e10cSrcweir     if(msString.getLength())
1297*cdf0e10cSrcweir     {
1298*cdf0e10cSrcweir         const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength());
1299*cdf0e10cSrcweir         const sal_Int32 nLen(aStr.getLength());
1300*cdf0e10cSrcweir         sal_Int32 nPos(0);
1301*cdf0e10cSrcweir 
1302*cdf0e10cSrcweir         // skip starting spaces
1303*cdf0e10cSrcweir         Imp_SkipSpaces(aStr, nPos, nLen);
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir         // get mX, #100617# be prepared for doubles
1306*cdf0e10cSrcweir         mnX = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnX));
1307*cdf0e10cSrcweir 
1308*cdf0e10cSrcweir         // skip spaces and commas
1309*cdf0e10cSrcweir         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1310*cdf0e10cSrcweir 
1311*cdf0e10cSrcweir         // get mY, #100617# be prepared for doubles
1312*cdf0e10cSrcweir         mnY = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnY));
1313*cdf0e10cSrcweir 
1314*cdf0e10cSrcweir         // skip spaces and commas
1315*cdf0e10cSrcweir         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1316*cdf0e10cSrcweir 
1317*cdf0e10cSrcweir         // get mW, #100617# be prepared for doubles
1318*cdf0e10cSrcweir         mnW = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnW));
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir         // skip spaces and commas
1321*cdf0e10cSrcweir         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1322*cdf0e10cSrcweir 
1323*cdf0e10cSrcweir         // get mH, #100617# be prepared for doubles
1324*cdf0e10cSrcweir         mnH = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnH));
1325*cdf0e10cSrcweir     }
1326*cdf0e10cSrcweir }
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir const OUString& SdXMLImExViewBox::GetExportString()
1329*cdf0e10cSrcweir {
1330*cdf0e10cSrcweir     OUString aNewString;
1331*cdf0e10cSrcweir     OUString aEmptySpace(sal_Unicode(' '));
1332*cdf0e10cSrcweir 
1333*cdf0e10cSrcweir     Imp_PutNumberChar(aNewString, mnX);
1334*cdf0e10cSrcweir     aNewString += aEmptySpace;
1335*cdf0e10cSrcweir 
1336*cdf0e10cSrcweir     Imp_PutNumberChar(aNewString, mnY);
1337*cdf0e10cSrcweir     aNewString += aEmptySpace;
1338*cdf0e10cSrcweir 
1339*cdf0e10cSrcweir     Imp_PutNumberChar(aNewString, mnW);
1340*cdf0e10cSrcweir     aNewString += aEmptySpace;
1341*cdf0e10cSrcweir 
1342*cdf0e10cSrcweir     Imp_PutNumberChar(aNewString, mnH);
1343*cdf0e10cSrcweir 
1344*cdf0e10cSrcweir     // set new string
1345*cdf0e10cSrcweir     msString = aNewString;
1346*cdf0e10cSrcweir 
1347*cdf0e10cSrcweir     return msString;
1348*cdf0e10cSrcweir }
1349*cdf0e10cSrcweir 
1350*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1351*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1352*cdf0e10cSrcweir 
1353*cdf0e10cSrcweir SdXMLImExPointsElement::SdXMLImExPointsElement(drawing::PointSequence* pPoints,
1354*cdf0e10cSrcweir     const SdXMLImExViewBox& rViewBox,
1355*cdf0e10cSrcweir     const awt::Point& rObjectPos,
1356*cdf0e10cSrcweir     const awt::Size& rObjectSize,
1357*cdf0e10cSrcweir     // #96328#
1358*cdf0e10cSrcweir     const bool bClosed)
1359*cdf0e10cSrcweir :   maPoly( 0L )
1360*cdf0e10cSrcweir {
1361*cdf0e10cSrcweir     DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExPointsElement(!)");
1362*cdf0e10cSrcweir 
1363*cdf0e10cSrcweir     // add polygon to string
1364*cdf0e10cSrcweir     sal_Int32 nCnt(pPoints->getLength());
1365*cdf0e10cSrcweir 
1366*cdf0e10cSrcweir     // #104076# Convert to string only when at last one point included
1367*cdf0e10cSrcweir     if(nCnt > 0)
1368*cdf0e10cSrcweir     {
1369*cdf0e10cSrcweir         OUString aNewString;
1370*cdf0e10cSrcweir         awt::Point* pArray = pPoints->getArray();
1371*cdf0e10cSrcweir 
1372*cdf0e10cSrcweir         // last point same? Ignore it.
1373*cdf0e10cSrcweir         // #96328# ...but only when polygon is CLOSED
1374*cdf0e10cSrcweir         if(bClosed && (pArray->X == (pArray + (nCnt - 1))->X) && (pArray->Y == (pArray + (nCnt - 1))->Y))
1375*cdf0e10cSrcweir             nCnt--;
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir         // object size and ViewBox size different?
1378*cdf0e10cSrcweir         bool bScale(rObjectSize.Width != rViewBox.GetWidth()
1379*cdf0e10cSrcweir             || rObjectSize.Height != rViewBox.GetHeight());
1380*cdf0e10cSrcweir         bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L);
1381*cdf0e10cSrcweir 
1382*cdf0e10cSrcweir         for(sal_Int32 a(0L); a < nCnt; a++)
1383*cdf0e10cSrcweir         {
1384*cdf0e10cSrcweir             // prepare coordinates
1385*cdf0e10cSrcweir             sal_Int32 nX( pArray->X - rObjectPos.X );
1386*cdf0e10cSrcweir             sal_Int32 nY( pArray->Y - rObjectPos.Y );
1387*cdf0e10cSrcweir 
1388*cdf0e10cSrcweir             if(bScale && rObjectSize.Width && rObjectSize.Height)
1389*cdf0e10cSrcweir             {
1390*cdf0e10cSrcweir                 nX = (nX * rViewBox.GetWidth()) / rObjectSize.Width;
1391*cdf0e10cSrcweir                 nY = (nY * rViewBox.GetHeight()) / rObjectSize.Height;
1392*cdf0e10cSrcweir             }
1393*cdf0e10cSrcweir 
1394*cdf0e10cSrcweir             if(bTranslate)
1395*cdf0e10cSrcweir             {
1396*cdf0e10cSrcweir                 nX += rViewBox.GetX();
1397*cdf0e10cSrcweir                 nY += rViewBox.GetY();
1398*cdf0e10cSrcweir             }
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir             // X and comma
1401*cdf0e10cSrcweir             Imp_PutNumberChar(aNewString, nX);
1402*cdf0e10cSrcweir             aNewString += String(sal_Unicode(','));
1403*cdf0e10cSrcweir 
1404*cdf0e10cSrcweir             // Y and space (not for last)
1405*cdf0e10cSrcweir             Imp_PutNumberChar(aNewString, nY);
1406*cdf0e10cSrcweir             if(a + 1 != nCnt)
1407*cdf0e10cSrcweir                 aNewString += String(sal_Unicode(' '));
1408*cdf0e10cSrcweir 
1409*cdf0e10cSrcweir             // next point
1410*cdf0e10cSrcweir             pArray++;
1411*cdf0e10cSrcweir         }
1412*cdf0e10cSrcweir 
1413*cdf0e10cSrcweir         // set new string
1414*cdf0e10cSrcweir         msString = aNewString;
1415*cdf0e10cSrcweir     }
1416*cdf0e10cSrcweir }
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir // #100617# svg:polyline or svg:polygon values may be double precision.
1419*cdf0e10cSrcweir SdXMLImExPointsElement::SdXMLImExPointsElement(const OUString& rNew,
1420*cdf0e10cSrcweir     const SdXMLImExViewBox& rViewBox,
1421*cdf0e10cSrcweir     const awt::Point& rObjectPos,
1422*cdf0e10cSrcweir     const awt::Size& rObjectSize,
1423*cdf0e10cSrcweir     const SvXMLUnitConverter& rConv)
1424*cdf0e10cSrcweir :   msString( rNew ),
1425*cdf0e10cSrcweir     maPoly( 0L )
1426*cdf0e10cSrcweir {
1427*cdf0e10cSrcweir     // convert string to polygon
1428*cdf0e10cSrcweir     const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength());
1429*cdf0e10cSrcweir     const sal_Int32 nLen(aStr.getLength());
1430*cdf0e10cSrcweir     sal_Int32 nPos(0);
1431*cdf0e10cSrcweir     sal_Int32 nNumPoints(0L);
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir     // skip starting spaces
1434*cdf0e10cSrcweir     Imp_SkipSpaces(aStr, nPos, nLen);
1435*cdf0e10cSrcweir 
1436*cdf0e10cSrcweir     // count points in first loop
1437*cdf0e10cSrcweir     while(nPos < nLen)
1438*cdf0e10cSrcweir     {
1439*cdf0e10cSrcweir         // skip number, #100617# be prepared for doubles
1440*cdf0e10cSrcweir         Imp_SkipDouble(aStr, nPos, nLen);
1441*cdf0e10cSrcweir 
1442*cdf0e10cSrcweir         // skip spaces and commas
1443*cdf0e10cSrcweir         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1444*cdf0e10cSrcweir 
1445*cdf0e10cSrcweir         // skip number, #100617# be prepared for doubles
1446*cdf0e10cSrcweir         Imp_SkipDouble(aStr, nPos, nLen);
1447*cdf0e10cSrcweir 
1448*cdf0e10cSrcweir         // skip spaces and commas
1449*cdf0e10cSrcweir         Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1450*cdf0e10cSrcweir 
1451*cdf0e10cSrcweir         // one more point
1452*cdf0e10cSrcweir         nNumPoints++;
1453*cdf0e10cSrcweir     }
1454*cdf0e10cSrcweir 
1455*cdf0e10cSrcweir     // second loop
1456*cdf0e10cSrcweir     if(nNumPoints)
1457*cdf0e10cSrcweir     {
1458*cdf0e10cSrcweir         nPos = 0;
1459*cdf0e10cSrcweir         maPoly.realloc(1);
1460*cdf0e10cSrcweir         drawing::PointSequence* pOuterSequence = maPoly.getArray();
1461*cdf0e10cSrcweir         pOuterSequence->realloc(nNumPoints);
1462*cdf0e10cSrcweir         awt::Point* pInnerSequence = pOuterSequence->getArray();
1463*cdf0e10cSrcweir 
1464*cdf0e10cSrcweir         // object size and ViewBox size different?
1465*cdf0e10cSrcweir         bool bScale(rObjectSize.Width != rViewBox.GetWidth()
1466*cdf0e10cSrcweir             || rObjectSize.Height != rViewBox.GetHeight());
1467*cdf0e10cSrcweir         bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L);
1468*cdf0e10cSrcweir 
1469*cdf0e10cSrcweir         // skip starting spaces
1470*cdf0e10cSrcweir         Imp_SkipSpaces(aStr, nPos, nLen);
1471*cdf0e10cSrcweir 
1472*cdf0e10cSrcweir         while(nPos < nLen)
1473*cdf0e10cSrcweir         {
1474*cdf0e10cSrcweir             // prepare new parameter pair
1475*cdf0e10cSrcweir             sal_Int32 nX(0L);
1476*cdf0e10cSrcweir             sal_Int32 nY(0L);
1477*cdf0e10cSrcweir 
1478*cdf0e10cSrcweir             // get mX, #100617# be prepared for doubles
1479*cdf0e10cSrcweir             nX = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nX));
1480*cdf0e10cSrcweir 
1481*cdf0e10cSrcweir             // skip spaces and commas
1482*cdf0e10cSrcweir             Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1483*cdf0e10cSrcweir 
1484*cdf0e10cSrcweir             // get mY, #100617# be prepared for doubles
1485*cdf0e10cSrcweir             nY = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nY));
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir             // skip spaces and commas
1488*cdf0e10cSrcweir             Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1489*cdf0e10cSrcweir 
1490*cdf0e10cSrcweir             // prepare parameters
1491*cdf0e10cSrcweir             if(bTranslate)
1492*cdf0e10cSrcweir             {
1493*cdf0e10cSrcweir                 nX -= rViewBox.GetX();
1494*cdf0e10cSrcweir                 nY -= rViewBox.GetY();
1495*cdf0e10cSrcweir             }
1496*cdf0e10cSrcweir 
1497*cdf0e10cSrcweir             if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight() )
1498*cdf0e10cSrcweir             {
1499*cdf0e10cSrcweir                 nX = (nX * rObjectSize.Width) / rViewBox.GetWidth();
1500*cdf0e10cSrcweir                 nY = (nY * rObjectSize.Height) / rViewBox.GetHeight();
1501*cdf0e10cSrcweir             }
1502*cdf0e10cSrcweir 
1503*cdf0e10cSrcweir             nX += rObjectPos.X;
1504*cdf0e10cSrcweir             nY += rObjectPos.Y;
1505*cdf0e10cSrcweir 
1506*cdf0e10cSrcweir             // add new point
1507*cdf0e10cSrcweir             *pInnerSequence = awt::Point( nX, nY );
1508*cdf0e10cSrcweir             pInnerSequence++;
1509*cdf0e10cSrcweir         }
1510*cdf0e10cSrcweir     }
1511*cdf0e10cSrcweir }
1512*cdf0e10cSrcweir 
1513*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1514*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1515*cdf0e10cSrcweir 
1516*cdf0e10cSrcweir SdXMLImExSvgDElement::SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox)
1517*cdf0e10cSrcweir :   mrViewBox( rViewBox ),
1518*cdf0e10cSrcweir     mbIsClosed( false ),
1519*cdf0e10cSrcweir     mbIsCurve( false ),
1520*cdf0e10cSrcweir     mnLastX( 0L ),
1521*cdf0e10cSrcweir     mnLastY( 0L ),
1522*cdf0e10cSrcweir     maPoly( 0L ),
1523*cdf0e10cSrcweir     maFlag( 0L )
1524*cdf0e10cSrcweir {
1525*cdf0e10cSrcweir }
1526*cdf0e10cSrcweir 
1527*cdf0e10cSrcweir void Imp_GetPrevPos(awt::Point*& pPrevPos1,
1528*cdf0e10cSrcweir     drawing::PolygonFlags& aPrevFlag1,
1529*cdf0e10cSrcweir     const bool bClosed, awt::Point* pPoints,
1530*cdf0e10cSrcweir     drawing::PolygonFlags* pFlags, const sal_Int32 nPos,
1531*cdf0e10cSrcweir     const sal_Int32 nCnt, const sal_Int32 nAdd)
1532*cdf0e10cSrcweir {
1533*cdf0e10cSrcweir     if(bClosed)
1534*cdf0e10cSrcweir     {
1535*cdf0e10cSrcweir         pPrevPos1 = pPoints + ((nPos + nCnt - nAdd) % nCnt);
1536*cdf0e10cSrcweir         aPrevFlag1 = *(pFlags + ((nPos + nCnt - nAdd) % nCnt));
1537*cdf0e10cSrcweir     }
1538*cdf0e10cSrcweir     else if(nPos > (nAdd - 1))
1539*cdf0e10cSrcweir     {
1540*cdf0e10cSrcweir         pPrevPos1 = pPoints + (nPos - nAdd);
1541*cdf0e10cSrcweir         aPrevFlag1 = *(pFlags + (nPos - nAdd));
1542*cdf0e10cSrcweir     }
1543*cdf0e10cSrcweir     else
1544*cdf0e10cSrcweir         pPrevPos1 = 0L;
1545*cdf0e10cSrcweir }
1546*cdf0e10cSrcweir 
1547*cdf0e10cSrcweir void Imp_PrepareCoorExport(sal_Int32& nX, sal_Int32& nY,
1548*cdf0e10cSrcweir     const awt::Point* pPointArray, const awt::Point& rObjectPos,
1549*cdf0e10cSrcweir     const awt::Size& rObjectSize, const SdXMLImExViewBox& mrViewBox,
1550*cdf0e10cSrcweir     const bool bScale, const bool bTranslate)
1551*cdf0e10cSrcweir {
1552*cdf0e10cSrcweir     nX = pPointArray->X - rObjectPos.X;
1553*cdf0e10cSrcweir     nY = pPointArray->Y - rObjectPos.Y;
1554*cdf0e10cSrcweir 
1555*cdf0e10cSrcweir     if(bScale && rObjectSize.Width && rObjectSize.Height )
1556*cdf0e10cSrcweir     {
1557*cdf0e10cSrcweir         nX = (nX * mrViewBox.GetWidth()) / rObjectSize.Width;
1558*cdf0e10cSrcweir         nY = (nY * mrViewBox.GetHeight()) / rObjectSize.Height;
1559*cdf0e10cSrcweir     }
1560*cdf0e10cSrcweir 
1561*cdf0e10cSrcweir     if(bTranslate)
1562*cdf0e10cSrcweir     {
1563*cdf0e10cSrcweir         nX += mrViewBox.GetX();
1564*cdf0e10cSrcweir         nY += mrViewBox.GetY();
1565*cdf0e10cSrcweir     }
1566*cdf0e10cSrcweir }
1567*cdf0e10cSrcweir 
1568*cdf0e10cSrcweir //#define TEST_QUADRATIC_CURVES
1569*cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES
1570*cdf0e10cSrcweir // To be able to test quadratic curve code: The code concerning to
1571*cdf0e10cSrcweir // bDoTestHere can be used (see below). Construct shapes which have their control
1572*cdf0e10cSrcweir // points on equal coordinates. When these are written, they can be
1573*cdf0e10cSrcweir // forced to create correct 'Q' and 'T' statements using this flag.
1574*cdf0e10cSrcweir // These may then be tested for import/exporting.
1575*cdf0e10cSrcweir static bool bDoTestHere(true);
1576*cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES
1577*cdf0e10cSrcweir 
1578*cdf0e10cSrcweir void SdXMLImExSvgDElement::AddPolygon(
1579*cdf0e10cSrcweir     drawing::PointSequence* pPoints,
1580*cdf0e10cSrcweir     drawing::FlagSequence* pFlags,
1581*cdf0e10cSrcweir     const awt::Point& rObjectPos,
1582*cdf0e10cSrcweir     const awt::Size& rObjectSize,
1583*cdf0e10cSrcweir     bool bClosed, bool bRelative)
1584*cdf0e10cSrcweir {
1585*cdf0e10cSrcweir     DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExSvgDElement(!)");
1586*cdf0e10cSrcweir 
1587*cdf0e10cSrcweir     sal_Int32 nCnt(pPoints->getLength());
1588*cdf0e10cSrcweir 
1589*cdf0e10cSrcweir     // #104076# Convert to string only when at last one point included
1590*cdf0e10cSrcweir     if(nCnt > 0)
1591*cdf0e10cSrcweir     {
1592*cdf0e10cSrcweir         // append polygon to string
1593*cdf0e10cSrcweir         OUString aNewString;
1594*cdf0e10cSrcweir         sal_Unicode aLastCommand = ' ';
1595*cdf0e10cSrcweir         awt::Point* pPointArray = pPoints->getArray();
1596*cdf0e10cSrcweir 
1597*cdf0e10cSrcweir         // are the flags used at all? If not forget about them
1598*cdf0e10cSrcweir         if(pFlags)
1599*cdf0e10cSrcweir         {
1600*cdf0e10cSrcweir             sal_Int32 nFlagCnt(pFlags->getLength());
1601*cdf0e10cSrcweir 
1602*cdf0e10cSrcweir             if(nFlagCnt)
1603*cdf0e10cSrcweir             {
1604*cdf0e10cSrcweir                 bool bFlagsUsed(false);
1605*cdf0e10cSrcweir                 drawing::PolygonFlags* pFlagArray = pFlags->getArray();
1606*cdf0e10cSrcweir 
1607*cdf0e10cSrcweir                 for(sal_Int32 a(0); !bFlagsUsed && a < nFlagCnt; a++)
1608*cdf0e10cSrcweir                     if(drawing::PolygonFlags_NORMAL != *pFlagArray++)
1609*cdf0e10cSrcweir                         bFlagsUsed = true;
1610*cdf0e10cSrcweir 
1611*cdf0e10cSrcweir                 if(!bFlagsUsed)
1612*cdf0e10cSrcweir                     pFlags = 0L;
1613*cdf0e10cSrcweir             }
1614*cdf0e10cSrcweir             else
1615*cdf0e10cSrcweir             {
1616*cdf0e10cSrcweir                 pFlags = 0L;
1617*cdf0e10cSrcweir             }
1618*cdf0e10cSrcweir         }
1619*cdf0e10cSrcweir 
1620*cdf0e10cSrcweir         // object size and ViewBox size different?
1621*cdf0e10cSrcweir         bool bScale(rObjectSize.Width != mrViewBox.GetWidth()
1622*cdf0e10cSrcweir             || rObjectSize.Height != mrViewBox.GetHeight());
1623*cdf0e10cSrcweir         bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L);
1624*cdf0e10cSrcweir 
1625*cdf0e10cSrcweir         // #87202# rework of point reduction:
1626*cdf0e10cSrcweir         // Test for Last point same -> closed, ignore last point. Take
1627*cdf0e10cSrcweir         // some more circumstances in account when looking at curve segments.
1628*cdf0e10cSrcweir         drawing::PolygonFlags* pFlagArray = (pFlags) ? pFlags->getArray() : 0L;
1629*cdf0e10cSrcweir         if((pPointArray->X == (pPointArray + (nCnt - 1))->X) && (pPointArray->Y == (pPointArray + (nCnt - 1))->Y))
1630*cdf0e10cSrcweir         {
1631*cdf0e10cSrcweir             if(pFlags)
1632*cdf0e10cSrcweir             {
1633*cdf0e10cSrcweir                 // point needs to be ignored if point before it is
1634*cdf0e10cSrcweir                 // NO control point. Else the last point is needed
1635*cdf0e10cSrcweir                 // for exporting the last segment of the curve. That means
1636*cdf0e10cSrcweir                 // that the last and the first point will be saved double,
1637*cdf0e10cSrcweir                 // but SVG does not support a better solution here.
1638*cdf0e10cSrcweir                 if(nCnt >= 2 && drawing::PolygonFlags_CONTROL != *(pFlagArray + (nCnt - 2)))
1639*cdf0e10cSrcweir                 {
1640*cdf0e10cSrcweir                     nCnt--;
1641*cdf0e10cSrcweir                 }
1642*cdf0e10cSrcweir             }
1643*cdf0e10cSrcweir             else
1644*cdf0e10cSrcweir             {
1645*cdf0e10cSrcweir                 // no curve, ignore last point
1646*cdf0e10cSrcweir                 nCnt--;
1647*cdf0e10cSrcweir             }
1648*cdf0e10cSrcweir         }
1649*cdf0e10cSrcweir 
1650*cdf0e10cSrcweir         // bezier poly, handle curves
1651*cdf0e10cSrcweir         bool  bDidWriteStart(false);
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir         for(sal_Int32 a(0L); a < nCnt; a++)
1654*cdf0e10cSrcweir         {
1655*cdf0e10cSrcweir             if(!pFlags || drawing::PolygonFlags_CONTROL != *pFlagArray)
1656*cdf0e10cSrcweir             {
1657*cdf0e10cSrcweir                 bool bDidWriteAsCurve(false);
1658*cdf0e10cSrcweir 
1659*cdf0e10cSrcweir                 if(bDidWriteStart)
1660*cdf0e10cSrcweir                 {
1661*cdf0e10cSrcweir                     if(pFlags)
1662*cdf0e10cSrcweir                     {
1663*cdf0e10cSrcweir                         // real curve point, get previous to see if it's a control point
1664*cdf0e10cSrcweir                         awt::Point* pPrevPos1;
1665*cdf0e10cSrcweir                         drawing::PolygonFlags aPrevFlag1;
1666*cdf0e10cSrcweir 
1667*cdf0e10cSrcweir                         Imp_GetPrevPos(pPrevPos1, aPrevFlag1, bClosed, pPoints->getArray(),
1668*cdf0e10cSrcweir                             pFlags->getArray(), a, nCnt, 1);
1669*cdf0e10cSrcweir 
1670*cdf0e10cSrcweir                         if(pPrevPos1 && drawing::PolygonFlags_CONTROL == aPrevFlag1)
1671*cdf0e10cSrcweir                         {
1672*cdf0e10cSrcweir                             // get previous2 to see if it's a control point, too
1673*cdf0e10cSrcweir                             awt::Point* pPrevPos2;
1674*cdf0e10cSrcweir                             drawing::PolygonFlags aPrevFlag2;
1675*cdf0e10cSrcweir 
1676*cdf0e10cSrcweir                             Imp_GetPrevPos(pPrevPos2, aPrevFlag2, bClosed, pPoints->getArray(),
1677*cdf0e10cSrcweir                                 pFlags->getArray(), a, nCnt, 2);
1678*cdf0e10cSrcweir 
1679*cdf0e10cSrcweir                             if(pPrevPos2 && drawing::PolygonFlags_CONTROL == aPrevFlag2)
1680*cdf0e10cSrcweir                             {
1681*cdf0e10cSrcweir                                 // get previous3 to see if it's a curve point and if,
1682*cdf0e10cSrcweir                                 // if it is fully symmetric or not
1683*cdf0e10cSrcweir                                 awt::Point* pPrevPos3;
1684*cdf0e10cSrcweir                                 drawing::PolygonFlags aPrevFlag3;
1685*cdf0e10cSrcweir 
1686*cdf0e10cSrcweir                                 Imp_GetPrevPos(pPrevPos3, aPrevFlag3, bClosed, pPoints->getArray(),
1687*cdf0e10cSrcweir                                     pFlags->getArray(), a, nCnt, 3);
1688*cdf0e10cSrcweir 
1689*cdf0e10cSrcweir                                 if(pPrevPos3)
1690*cdf0e10cSrcweir                                 {
1691*cdf0e10cSrcweir                                     // prepare coordinates
1692*cdf0e10cSrcweir                                     sal_Int32 nX, nY;
1693*cdf0e10cSrcweir 
1694*cdf0e10cSrcweir                                     Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize,
1695*cdf0e10cSrcweir                                         mrViewBox, bScale, bTranslate);
1696*cdf0e10cSrcweir 
1697*cdf0e10cSrcweir                                     // #100617# test if this curve segment may be written as
1698*cdf0e10cSrcweir                                     // a quadratic bezier
1699*cdf0e10cSrcweir                                     // That's the case if both control points are in the same place
1700*cdf0e10cSrcweir                                     // when they are prolonged to the common quadratic control point
1701*cdf0e10cSrcweir                                     // Left:  P = (3P1 - P0) / 2
1702*cdf0e10cSrcweir                                     // Right: P = (3P2 - P3) / 2
1703*cdf0e10cSrcweir                                     bool bIsQuadratic(false);
1704*cdf0e10cSrcweir                                     const bool bEnableSaveQuadratic(false);
1705*cdf0e10cSrcweir 
1706*cdf0e10cSrcweir                                     sal_Int32 nPX_L(FRound((double)((3 * pPrevPos2->X) - pPrevPos3->X) / 2.0));
1707*cdf0e10cSrcweir                                     sal_Int32 nPY_L(FRound((double)((3 * pPrevPos2->Y) - pPrevPos3->Y) / 2.0));
1708*cdf0e10cSrcweir                                     sal_Int32 nPX_R(FRound((double)((3 * pPrevPos1->X) - pPointArray->X) / 2.0));
1709*cdf0e10cSrcweir                                     sal_Int32 nPY_R(FRound((double)((3 * pPrevPos1->Y) - pPointArray->Y) / 2.0));
1710*cdf0e10cSrcweir                                     sal_Int32 nDist(0);
1711*cdf0e10cSrcweir 
1712*cdf0e10cSrcweir                                     if(nPX_L != nPX_R)
1713*cdf0e10cSrcweir                                     {
1714*cdf0e10cSrcweir                                         nDist += abs(nPX_L - nPX_R);
1715*cdf0e10cSrcweir                                     }
1716*cdf0e10cSrcweir 
1717*cdf0e10cSrcweir                                     if(nPY_L != nPY_R)
1718*cdf0e10cSrcweir                                     {
1719*cdf0e10cSrcweir                                         nDist += abs(nPY_L - nPY_R);
1720*cdf0e10cSrcweir                                     }
1721*cdf0e10cSrcweir 
1722*cdf0e10cSrcweir                                     if(nDist <= BORDER_INTEGERS_ARE_EQUAL)
1723*cdf0e10cSrcweir                                     {
1724*cdf0e10cSrcweir                                         if(bEnableSaveQuadratic)
1725*cdf0e10cSrcweir                                         {
1726*cdf0e10cSrcweir                                             bIsQuadratic = true;
1727*cdf0e10cSrcweir                                         }
1728*cdf0e10cSrcweir                                     }
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES
1731*cdf0e10cSrcweir                                     if(bDoTestHere)
1732*cdf0e10cSrcweir                                     {
1733*cdf0e10cSrcweir                                         bIsQuadratic = false;
1734*cdf0e10cSrcweir 
1735*cdf0e10cSrcweir                                         if(pPrevPos1->X == pPrevPos2->X && pPrevPos1->Y == pPrevPos2->Y)
1736*cdf0e10cSrcweir                                             bIsQuadratic = true;
1737*cdf0e10cSrcweir                                     }
1738*cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES
1739*cdf0e10cSrcweir 
1740*cdf0e10cSrcweir                                     if(bIsQuadratic)
1741*cdf0e10cSrcweir                                     {
1742*cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES
1743*cdf0e10cSrcweir                                         if(bDoTestHere)
1744*cdf0e10cSrcweir                                         {
1745*cdf0e10cSrcweir                                             bool bPrevPointIsSymmetric(false);
1746*cdf0e10cSrcweir 
1747*cdf0e10cSrcweir                                             if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3)
1748*cdf0e10cSrcweir                                             {
1749*cdf0e10cSrcweir                                                 // get previous4 to see if it's a control point
1750*cdf0e10cSrcweir                                                 awt::Point* pPrevPos4;
1751*cdf0e10cSrcweir                                                 drawing::PolygonFlags aPrevFlag4;
1752*cdf0e10cSrcweir 
1753*cdf0e10cSrcweir                                                 Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(),
1754*cdf0e10cSrcweir                                                     pFlags->getArray(), a, nCnt, 4);
1755*cdf0e10cSrcweir 
1756*cdf0e10cSrcweir                                                 if(drawing::PolygonFlags_CONTROL == aPrevFlag4)
1757*cdf0e10cSrcweir                                                 {
1758*cdf0e10cSrcweir                                                     // okay, prevPos3 is symmetric (c2) and prevPos4
1759*cdf0e10cSrcweir                                                     // is existing control point, the 's' statement can be used
1760*cdf0e10cSrcweir                                                     bPrevPointIsSymmetric = true;
1761*cdf0e10cSrcweir                                                 }
1762*cdf0e10cSrcweir                                             }
1763*cdf0e10cSrcweir 
1764*cdf0e10cSrcweir                                             if(bPrevPointIsSymmetric)
1765*cdf0e10cSrcweir                                             {
1766*cdf0e10cSrcweir                                                 // write a shorthand/smooth quadratic curveto entry (T)
1767*cdf0e10cSrcweir                                                 if(bRelative)
1768*cdf0e10cSrcweir                                                 {
1769*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('t'))
1770*cdf0e10cSrcweir                                                         aNewString += OUString(sal_Unicode('t'));
1771*cdf0e10cSrcweir 
1772*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
1773*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
1774*cdf0e10cSrcweir 
1775*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('t');
1776*cdf0e10cSrcweir                                                 }
1777*cdf0e10cSrcweir                                                 else
1778*cdf0e10cSrcweir                                                 {
1779*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('T'))
1780*cdf0e10cSrcweir                                                         aNewString += OUString(sal_Unicode('T'));
1781*cdf0e10cSrcweir 
1782*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX);
1783*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY);
1784*cdf0e10cSrcweir 
1785*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('T');
1786*cdf0e10cSrcweir                                                 }
1787*cdf0e10cSrcweir                                             }
1788*cdf0e10cSrcweir                                             else
1789*cdf0e10cSrcweir                                             {
1790*cdf0e10cSrcweir                                                 // prepare coordinates
1791*cdf0e10cSrcweir                                                 sal_Int32 nX1, nY1;
1792*cdf0e10cSrcweir 
1793*cdf0e10cSrcweir                                                 Imp_PrepareCoorExport(nX1, nY1, pPrevPos1, rObjectPos, rObjectSize,
1794*cdf0e10cSrcweir                                                     mrViewBox, bScale, bTranslate);
1795*cdf0e10cSrcweir 
1796*cdf0e10cSrcweir                                                 // write a quadratic curveto entry (Q)
1797*cdf0e10cSrcweir                                                 if(bRelative)
1798*cdf0e10cSrcweir                                                 {
1799*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('q'))
1800*cdf0e10cSrcweir                                                         aNewString += OUString(sal_Unicode('q'));
1801*cdf0e10cSrcweir 
1802*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX);
1803*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY);
1804*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
1805*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
1806*cdf0e10cSrcweir 
1807*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('q');
1808*cdf0e10cSrcweir                                                 }
1809*cdf0e10cSrcweir                                                 else
1810*cdf0e10cSrcweir                                                 {
1811*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('Q'))
1812*cdf0e10cSrcweir                                                         aNewString += OUString(sal_Unicode('Q'));
1813*cdf0e10cSrcweir 
1814*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX1);
1815*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY1);
1816*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX);
1817*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY);
1818*cdf0e10cSrcweir 
1819*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('Q');
1820*cdf0e10cSrcweir                                                 }
1821*cdf0e10cSrcweir                                             }
1822*cdf0e10cSrcweir                                         }
1823*cdf0e10cSrcweir                                         else
1824*cdf0e10cSrcweir                                         {
1825*cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES
1826*cdf0e10cSrcweir                                             awt::Point aNewPoint(nPX_L, nPY_L);
1827*cdf0e10cSrcweir                                             bool bPrevPointIsSmooth(false);
1828*cdf0e10cSrcweir 
1829*cdf0e10cSrcweir                                             if(drawing::PolygonFlags_SMOOTH == aPrevFlag3)
1830*cdf0e10cSrcweir                                             {
1831*cdf0e10cSrcweir                                                 // get previous4 to see if it's a control point
1832*cdf0e10cSrcweir                                                 awt::Point* pPrevPos4;
1833*cdf0e10cSrcweir                                                 drawing::PolygonFlags aPrevFlag4;
1834*cdf0e10cSrcweir 
1835*cdf0e10cSrcweir                                                 Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(),
1836*cdf0e10cSrcweir                                                     pFlags->getArray(), a, nCnt, 4);
1837*cdf0e10cSrcweir 
1838*cdf0e10cSrcweir                                                 if(drawing::PolygonFlags_CONTROL == aPrevFlag4)
1839*cdf0e10cSrcweir                                                 {
1840*cdf0e10cSrcweir                                                     // okay, prevPos3 is smooth (c1) and prevPos4
1841*cdf0e10cSrcweir                                                     // is existing control point. Test if it's even symmetric
1842*cdf0e10cSrcweir                                                     // and thus the 'T' statement may be used.
1843*cdf0e10cSrcweir                                                     ::basegfx::B2DVector aVec1(pPrevPos4->X - pPrevPos3->X, pPrevPos4->Y - pPrevPos3->Y);
1844*cdf0e10cSrcweir                                                     ::basegfx::B2DVector aVec2(aNewPoint.X - pPrevPos3->X, aNewPoint.Y - pPrevPos3->Y);
1845*cdf0e10cSrcweir                                                     bool bSameLength(false);
1846*cdf0e10cSrcweir                                                     bool bSameDirection(false);
1847*cdf0e10cSrcweir 
1848*cdf0e10cSrcweir                                                     // get vector values
1849*cdf0e10cSrcweir                                                     Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection);
1850*cdf0e10cSrcweir 
1851*cdf0e10cSrcweir                                                     if(bSameLength && bSameDirection)
1852*cdf0e10cSrcweir                                                         bPrevPointIsSmooth = true;
1853*cdf0e10cSrcweir                                                 }
1854*cdf0e10cSrcweir                                             }
1855*cdf0e10cSrcweir 
1856*cdf0e10cSrcweir                                             if(bPrevPointIsSmooth)
1857*cdf0e10cSrcweir                                             {
1858*cdf0e10cSrcweir                                                 // write a shorthand/smooth quadratic curveto entry (T)
1859*cdf0e10cSrcweir                                                 if(bRelative)
1860*cdf0e10cSrcweir                                                 {
1861*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('t'))
1862*cdf0e10cSrcweir                                                         aNewString += String(sal_Unicode('t'));
1863*cdf0e10cSrcweir 
1864*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
1865*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
1866*cdf0e10cSrcweir 
1867*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('t');
1868*cdf0e10cSrcweir                                                 }
1869*cdf0e10cSrcweir                                                 else
1870*cdf0e10cSrcweir                                                 {
1871*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('T'))
1872*cdf0e10cSrcweir                                                         aNewString += String(sal_Unicode('T'));
1873*cdf0e10cSrcweir 
1874*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX);
1875*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY);
1876*cdf0e10cSrcweir 
1877*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('T');
1878*cdf0e10cSrcweir                                                 }
1879*cdf0e10cSrcweir                                             }
1880*cdf0e10cSrcweir                                             else
1881*cdf0e10cSrcweir                                             {
1882*cdf0e10cSrcweir                                                 // prepare coordinates
1883*cdf0e10cSrcweir                                                 sal_Int32 nX1, nY1;
1884*cdf0e10cSrcweir 
1885*cdf0e10cSrcweir                                                 Imp_PrepareCoorExport(nX1, nY1, &aNewPoint, rObjectPos, rObjectSize,
1886*cdf0e10cSrcweir                                                     mrViewBox, bScale, bTranslate);
1887*cdf0e10cSrcweir 
1888*cdf0e10cSrcweir                                                 // write a quadratic curveto entry (Q)
1889*cdf0e10cSrcweir                                                 if(bRelative)
1890*cdf0e10cSrcweir                                                 {
1891*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('q'))
1892*cdf0e10cSrcweir                                                         aNewString += String(sal_Unicode('q'));
1893*cdf0e10cSrcweir 
1894*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX);
1895*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY);
1896*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
1897*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
1898*cdf0e10cSrcweir 
1899*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('q');
1900*cdf0e10cSrcweir                                                 }
1901*cdf0e10cSrcweir                                                 else
1902*cdf0e10cSrcweir                                                 {
1903*cdf0e10cSrcweir                                                     if(aLastCommand != sal_Unicode('Q'))
1904*cdf0e10cSrcweir                                                         aNewString += String(sal_Unicode('Q'));
1905*cdf0e10cSrcweir 
1906*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX1);
1907*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY1);
1908*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nX);
1909*cdf0e10cSrcweir                                                     Imp_PutNumberCharWithSpace(aNewString, nY);
1910*cdf0e10cSrcweir 
1911*cdf0e10cSrcweir                                                     aLastCommand = sal_Unicode('Q');
1912*cdf0e10cSrcweir                                                 }
1913*cdf0e10cSrcweir                                             }
1914*cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES
1915*cdf0e10cSrcweir                                         }
1916*cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES
1917*cdf0e10cSrcweir                                     }
1918*cdf0e10cSrcweir                                     else
1919*cdf0e10cSrcweir                                     {
1920*cdf0e10cSrcweir                                         bool bPrevPointIsSymmetric(false);
1921*cdf0e10cSrcweir 
1922*cdf0e10cSrcweir                                         if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3)
1923*cdf0e10cSrcweir                                         {
1924*cdf0e10cSrcweir                                             // get previous4 to see if it's a control point
1925*cdf0e10cSrcweir                                             awt::Point* pPrevPos4;
1926*cdf0e10cSrcweir                                             drawing::PolygonFlags aPrevFlag4;
1927*cdf0e10cSrcweir 
1928*cdf0e10cSrcweir                                             Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(),
1929*cdf0e10cSrcweir                                                 pFlags->getArray(), a, nCnt, 4);
1930*cdf0e10cSrcweir 
1931*cdf0e10cSrcweir                                             if(drawing::PolygonFlags_CONTROL == aPrevFlag4)
1932*cdf0e10cSrcweir                                             {
1933*cdf0e10cSrcweir                                                 // okay, prevPos3 is symmetric (c2) and prevPos4
1934*cdf0e10cSrcweir                                                 // is existing control point, the 's' statement can be used
1935*cdf0e10cSrcweir                                                 bPrevPointIsSymmetric = true;
1936*cdf0e10cSrcweir                                             }
1937*cdf0e10cSrcweir                                         }
1938*cdf0e10cSrcweir 
1939*cdf0e10cSrcweir                                         // prepare coordinates
1940*cdf0e10cSrcweir                                         sal_Int32 nX2, nY2;
1941*cdf0e10cSrcweir 
1942*cdf0e10cSrcweir                                         Imp_PrepareCoorExport(nX2, nY2, pPrevPos1, rObjectPos, rObjectSize,
1943*cdf0e10cSrcweir                                             mrViewBox, bScale, bTranslate);
1944*cdf0e10cSrcweir 
1945*cdf0e10cSrcweir                                         if(bPrevPointIsSymmetric)
1946*cdf0e10cSrcweir                                         {
1947*cdf0e10cSrcweir                                             // write a shorthand/smooth curveto entry (S)
1948*cdf0e10cSrcweir                                             if(bRelative)
1949*cdf0e10cSrcweir                                             {
1950*cdf0e10cSrcweir                                                 if(aLastCommand != sal_Unicode('s'))
1951*cdf0e10cSrcweir                                                     aNewString += String(sal_Unicode('s'));
1952*cdf0e10cSrcweir 
1953*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX);
1954*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY);
1955*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
1956*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
1957*cdf0e10cSrcweir 
1958*cdf0e10cSrcweir                                                 aLastCommand = sal_Unicode('s');
1959*cdf0e10cSrcweir                                             }
1960*cdf0e10cSrcweir                                             else
1961*cdf0e10cSrcweir                                             {
1962*cdf0e10cSrcweir                                                 if(aLastCommand != sal_Unicode('S'))
1963*cdf0e10cSrcweir                                                     aNewString += String(sal_Unicode('S'));
1964*cdf0e10cSrcweir 
1965*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX2);
1966*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY2);
1967*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX);
1968*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY);
1969*cdf0e10cSrcweir 
1970*cdf0e10cSrcweir                                                 aLastCommand = sal_Unicode('S');
1971*cdf0e10cSrcweir                                             }
1972*cdf0e10cSrcweir                                         }
1973*cdf0e10cSrcweir                                         else
1974*cdf0e10cSrcweir                                         {
1975*cdf0e10cSrcweir                                             // prepare coordinates
1976*cdf0e10cSrcweir                                             sal_Int32 nX1, nY1;
1977*cdf0e10cSrcweir 
1978*cdf0e10cSrcweir                                             Imp_PrepareCoorExport(nX1, nY1, pPrevPos2, rObjectPos, rObjectSize,
1979*cdf0e10cSrcweir                                                 mrViewBox, bScale, bTranslate);
1980*cdf0e10cSrcweir 
1981*cdf0e10cSrcweir                                             // write a curveto entry (C)
1982*cdf0e10cSrcweir                                             if(bRelative)
1983*cdf0e10cSrcweir                                             {
1984*cdf0e10cSrcweir                                                 if(aLastCommand != sal_Unicode('c'))
1985*cdf0e10cSrcweir                                                     aNewString += String(sal_Unicode('c'));
1986*cdf0e10cSrcweir 
1987*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX);
1988*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY);
1989*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX);
1990*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY);
1991*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
1992*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
1993*cdf0e10cSrcweir 
1994*cdf0e10cSrcweir                                                 aLastCommand = sal_Unicode('c');
1995*cdf0e10cSrcweir                                             }
1996*cdf0e10cSrcweir                                             else
1997*cdf0e10cSrcweir                                             {
1998*cdf0e10cSrcweir                                                 if(aLastCommand != sal_Unicode('C'))
1999*cdf0e10cSrcweir                                                     aNewString += String(sal_Unicode('C'));
2000*cdf0e10cSrcweir 
2001*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX1);
2002*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY1);
2003*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX2);
2004*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY2);
2005*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nX);
2006*cdf0e10cSrcweir                                                 Imp_PutNumberCharWithSpace(aNewString, nY);
2007*cdf0e10cSrcweir 
2008*cdf0e10cSrcweir                                                 aLastCommand = sal_Unicode('C');
2009*cdf0e10cSrcweir                                             }
2010*cdf0e10cSrcweir                                         }
2011*cdf0e10cSrcweir                                     }
2012*cdf0e10cSrcweir 
2013*cdf0e10cSrcweir                                     // remember that current point IS written
2014*cdf0e10cSrcweir                                     bDidWriteAsCurve = true;
2015*cdf0e10cSrcweir 
2016*cdf0e10cSrcweir                                     // remember new last position
2017*cdf0e10cSrcweir                                     mnLastX = nX;
2018*cdf0e10cSrcweir                                     mnLastY = nY;
2019*cdf0e10cSrcweir                                 }
2020*cdf0e10cSrcweir                             }
2021*cdf0e10cSrcweir                         }
2022*cdf0e10cSrcweir                     }
2023*cdf0e10cSrcweir                 }
2024*cdf0e10cSrcweir 
2025*cdf0e10cSrcweir                 if(!bDidWriteAsCurve)
2026*cdf0e10cSrcweir                 {
2027*cdf0e10cSrcweir                     // current point not yet written, prepare coordinates
2028*cdf0e10cSrcweir                     sal_Int32 nX, nY;
2029*cdf0e10cSrcweir 
2030*cdf0e10cSrcweir                     Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize,
2031*cdf0e10cSrcweir                         mrViewBox, bScale, bTranslate);
2032*cdf0e10cSrcweir 
2033*cdf0e10cSrcweir                     if(bDidWriteStart)
2034*cdf0e10cSrcweir                     {
2035*cdf0e10cSrcweir                         // write as normal point
2036*cdf0e10cSrcweir                         if(mnLastX == nX)
2037*cdf0e10cSrcweir                         {
2038*cdf0e10cSrcweir                             if(bRelative)
2039*cdf0e10cSrcweir                             {
2040*cdf0e10cSrcweir                                 if(aLastCommand != sal_Unicode('v'))
2041*cdf0e10cSrcweir                                     aNewString += String(sal_Unicode('v'));
2042*cdf0e10cSrcweir 
2043*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
2044*cdf0e10cSrcweir 
2045*cdf0e10cSrcweir                                 aLastCommand = sal_Unicode('v');
2046*cdf0e10cSrcweir                             }
2047*cdf0e10cSrcweir                             else
2048*cdf0e10cSrcweir                             {
2049*cdf0e10cSrcweir                                 if(aLastCommand != sal_Unicode('V'))
2050*cdf0e10cSrcweir                                     aNewString += String(sal_Unicode('V'));
2051*cdf0e10cSrcweir 
2052*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nY);
2053*cdf0e10cSrcweir 
2054*cdf0e10cSrcweir                                 aLastCommand = sal_Unicode('V');
2055*cdf0e10cSrcweir                             }
2056*cdf0e10cSrcweir                         }
2057*cdf0e10cSrcweir                         else if(mnLastY == nY)
2058*cdf0e10cSrcweir                         {
2059*cdf0e10cSrcweir                             if(bRelative)
2060*cdf0e10cSrcweir                             {
2061*cdf0e10cSrcweir                                 if(aLastCommand != sal_Unicode('h'))
2062*cdf0e10cSrcweir                                     aNewString += String(sal_Unicode('h'));
2063*cdf0e10cSrcweir 
2064*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
2065*cdf0e10cSrcweir 
2066*cdf0e10cSrcweir                                 aLastCommand = sal_Unicode('h');
2067*cdf0e10cSrcweir                             }
2068*cdf0e10cSrcweir                             else
2069*cdf0e10cSrcweir                             {
2070*cdf0e10cSrcweir                                 if(aLastCommand != sal_Unicode('H'))
2071*cdf0e10cSrcweir                                     aNewString += String(sal_Unicode('H'));
2072*cdf0e10cSrcweir 
2073*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nX);
2074*cdf0e10cSrcweir 
2075*cdf0e10cSrcweir                                 aLastCommand = sal_Unicode('H');
2076*cdf0e10cSrcweir                             }
2077*cdf0e10cSrcweir                         }
2078*cdf0e10cSrcweir                         else
2079*cdf0e10cSrcweir                         {
2080*cdf0e10cSrcweir                             if(bRelative)
2081*cdf0e10cSrcweir                             {
2082*cdf0e10cSrcweir                                 if(aLastCommand != sal_Unicode('l'))
2083*cdf0e10cSrcweir                                     aNewString += String(sal_Unicode('l'));
2084*cdf0e10cSrcweir 
2085*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
2086*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
2087*cdf0e10cSrcweir 
2088*cdf0e10cSrcweir                                 aLastCommand = sal_Unicode('l');
2089*cdf0e10cSrcweir                             }
2090*cdf0e10cSrcweir                             else
2091*cdf0e10cSrcweir                             {
2092*cdf0e10cSrcweir                                 if(aLastCommand != sal_Unicode('L'))
2093*cdf0e10cSrcweir                                     aNewString += String(sal_Unicode('L'));
2094*cdf0e10cSrcweir 
2095*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nX);
2096*cdf0e10cSrcweir                                 Imp_PutNumberCharWithSpace(aNewString, nY);
2097*cdf0e10cSrcweir 
2098*cdf0e10cSrcweir                                 aLastCommand = sal_Unicode('L');
2099*cdf0e10cSrcweir                             }
2100*cdf0e10cSrcweir                         }
2101*cdf0e10cSrcweir                     }
2102*cdf0e10cSrcweir                     else
2103*cdf0e10cSrcweir                     {
2104*cdf0e10cSrcweir                         // write as start point
2105*cdf0e10cSrcweir                         if(bRelative)
2106*cdf0e10cSrcweir                         {
2107*cdf0e10cSrcweir                             aNewString += String(sal_Unicode('m'));
2108*cdf0e10cSrcweir 
2109*cdf0e10cSrcweir                             Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX);
2110*cdf0e10cSrcweir                             Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY);
2111*cdf0e10cSrcweir 
2112*cdf0e10cSrcweir                             aLastCommand = sal_Unicode('l');
2113*cdf0e10cSrcweir                         }
2114*cdf0e10cSrcweir                         else
2115*cdf0e10cSrcweir                         {
2116*cdf0e10cSrcweir                             aNewString += String(sal_Unicode('M'));
2117*cdf0e10cSrcweir 
2118*cdf0e10cSrcweir                             Imp_PutNumberCharWithSpace(aNewString, nX);
2119*cdf0e10cSrcweir                             Imp_PutNumberCharWithSpace(aNewString, nY);
2120*cdf0e10cSrcweir 
2121*cdf0e10cSrcweir                             aLastCommand = sal_Unicode('L');
2122*cdf0e10cSrcweir                         }
2123*cdf0e10cSrcweir 
2124*cdf0e10cSrcweir                         // remember start written
2125*cdf0e10cSrcweir                         bDidWriteStart = true;
2126*cdf0e10cSrcweir                     }
2127*cdf0e10cSrcweir 
2128*cdf0e10cSrcweir                     // remember new last position
2129*cdf0e10cSrcweir                     mnLastX = nX;
2130*cdf0e10cSrcweir                     mnLastY = nY;
2131*cdf0e10cSrcweir                 }
2132*cdf0e10cSrcweir             }
2133*cdf0e10cSrcweir 
2134*cdf0e10cSrcweir             // next point
2135*cdf0e10cSrcweir             pPointArray++;
2136*cdf0e10cSrcweir             pFlagArray++;
2137*cdf0e10cSrcweir         }
2138*cdf0e10cSrcweir 
2139*cdf0e10cSrcweir         // close path if closed poly
2140*cdf0e10cSrcweir         if(bClosed)
2141*cdf0e10cSrcweir         {
2142*cdf0e10cSrcweir             if(bRelative)
2143*cdf0e10cSrcweir                 aNewString += String(sal_Unicode('z'));
2144*cdf0e10cSrcweir             else
2145*cdf0e10cSrcweir                 aNewString += String(sal_Unicode('Z'));
2146*cdf0e10cSrcweir         }
2147*cdf0e10cSrcweir 
2148*cdf0e10cSrcweir         // append new string
2149*cdf0e10cSrcweir         msString += aNewString;
2150*cdf0e10cSrcweir     }
2151*cdf0e10cSrcweir }
2152*cdf0e10cSrcweir 
2153*cdf0e10cSrcweir // #100617# Linear double reader
2154*cdf0e10cSrcweir double Imp_ImportDoubleAndSpaces(
2155*cdf0e10cSrcweir     double fRetval, const OUString& rStr, sal_Int32& rPos,
2156*cdf0e10cSrcweir     const sal_Int32 nLen, const SvXMLUnitConverter& rConv)
2157*cdf0e10cSrcweir {
2158*cdf0e10cSrcweir     fRetval = Imp_GetDoubleChar(rStr, rPos, nLen, rConv, fRetval);
2159*cdf0e10cSrcweir     Imp_SkipSpacesAndCommas(rStr, rPos, nLen);
2160*cdf0e10cSrcweir     return fRetval;
2161*cdf0e10cSrcweir }
2162*cdf0e10cSrcweir 
2163*cdf0e10cSrcweir // #100617# Allow to read doubles, too. This will need to be changed to
2164*cdf0e10cSrcweir // the usage of Imp_ImportDoubleAndSpaces(...). For now, this is sufficient
2165*cdf0e10cSrcweir // since the interface cannot transport doubles.
2166*cdf0e10cSrcweir sal_Int32 Imp_ImportNumberAndSpaces(
2167*cdf0e10cSrcweir     sal_Int32 nRetval, const OUString& rStr, sal_Int32& rPos,
2168*cdf0e10cSrcweir     const sal_Int32 nLen, const SvXMLUnitConverter& rConv)
2169*cdf0e10cSrcweir {
2170*cdf0e10cSrcweir     nRetval = FRound(Imp_ImportDoubleAndSpaces(double(nRetval), rStr, rPos, nLen, rConv));
2171*cdf0e10cSrcweir     Imp_SkipSpacesAndCommas(rStr, rPos, nLen);
2172*cdf0e10cSrcweir     return nRetval;
2173*cdf0e10cSrcweir }
2174*cdf0e10cSrcweir 
2175*cdf0e10cSrcweir void Imp_PrepareCoorImport(sal_Int32& nX, sal_Int32& nY,
2176*cdf0e10cSrcweir     const awt::Point& rObjectPos, const awt::Size& rObjectSize,
2177*cdf0e10cSrcweir     const SdXMLImExViewBox& rViewBox, const bool bScale, const bool bTranslate)
2178*cdf0e10cSrcweir {
2179*cdf0e10cSrcweir     if(bTranslate)
2180*cdf0e10cSrcweir     {
2181*cdf0e10cSrcweir         nX -= rViewBox.GetX();
2182*cdf0e10cSrcweir         nY -= rViewBox.GetY();
2183*cdf0e10cSrcweir     }
2184*cdf0e10cSrcweir 
2185*cdf0e10cSrcweir     if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight())
2186*cdf0e10cSrcweir     {
2187*cdf0e10cSrcweir         nX = (nX * rObjectSize.Width) / rViewBox.GetWidth();
2188*cdf0e10cSrcweir         nY = (nY * rObjectSize.Height) / rViewBox.GetHeight();
2189*cdf0e10cSrcweir     }
2190*cdf0e10cSrcweir 
2191*cdf0e10cSrcweir     nX += rObjectPos.X;
2192*cdf0e10cSrcweir     nY += rObjectPos.Y;
2193*cdf0e10cSrcweir }
2194*cdf0e10cSrcweir 
2195*cdf0e10cSrcweir void Imp_AddExportPoints(sal_Int32 nX, sal_Int32 nY,
2196*cdf0e10cSrcweir     awt::Point* pPoints, drawing::PolygonFlags* pFlags,
2197*cdf0e10cSrcweir     const sal_Int32 nInnerIndex,
2198*cdf0e10cSrcweir     drawing::PolygonFlags eFlag)
2199*cdf0e10cSrcweir {
2200*cdf0e10cSrcweir     if(pPoints)
2201*cdf0e10cSrcweir         pPoints[nInnerIndex] = awt::Point( nX, nY );
2202*cdf0e10cSrcweir 
2203*cdf0e10cSrcweir     if(pFlags)
2204*cdf0e10cSrcweir         pFlags[nInnerIndex] = eFlag;
2205*cdf0e10cSrcweir }
2206*cdf0e10cSrcweir 
2207*cdf0e10cSrcweir void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection)
2208*cdf0e10cSrcweir {
2209*cdf0e10cSrcweir     const sal_Int32 nLen1(FRound(aVec1.getLength()));
2210*cdf0e10cSrcweir     const sal_Int32 nLen2(FRound(aVec2.getLength()));
2211*cdf0e10cSrcweir     aVec1.normalize();
2212*cdf0e10cSrcweir     aVec2.normalize();
2213*cdf0e10cSrcweir     aVec1 += aVec2;
2214*cdf0e10cSrcweir     const sal_Int32 nLen3(FRound(aVec1.getLength() * ((nLen1 + nLen2) / 2.0)));
2215*cdf0e10cSrcweir 
2216*cdf0e10cSrcweir     bSameLength = (abs(nLen1 - nLen2) <= BORDER_INTEGERS_ARE_EQUAL);
2217*cdf0e10cSrcweir     bSameDirection = (nLen3 <= BORDER_INTEGERS_ARE_EQUAL);
2218*cdf0e10cSrcweir }
2219*cdf0e10cSrcweir 
2220*cdf0e10cSrcweir void Imp_CorrectPolygonFlag(const sal_uInt32 nInnerIndex, const awt::Point* const pInnerSequence,
2221*cdf0e10cSrcweir     drawing::PolygonFlags* const pInnerFlags, const sal_Int32 nX1, const sal_Int32 nY1)
2222*cdf0e10cSrcweir {
2223*cdf0e10cSrcweir     if(nInnerIndex)
2224*cdf0e10cSrcweir     {
2225*cdf0e10cSrcweir         const awt::Point aPPrev1 = pInnerSequence[nInnerIndex - 1];
2226*cdf0e10cSrcweir 
2227*cdf0e10cSrcweir         if(nInnerIndex > 1)
2228*cdf0e10cSrcweir         {
2229*cdf0e10cSrcweir             const awt::Point aPPrev2 = pInnerSequence[nInnerIndex - 2];
2230*cdf0e10cSrcweir             const drawing::PolygonFlags aFPrev2 = pInnerFlags[nInnerIndex - 2];
2231*cdf0e10cSrcweir             ::basegfx::B2DVector aVec1(aPPrev2.X - aPPrev1.X, aPPrev2.Y - aPPrev1.Y);
2232*cdf0e10cSrcweir             ::basegfx::B2DVector aVec2(nX1 - aPPrev1.X, nY1 - aPPrev1.Y);
2233*cdf0e10cSrcweir             bool bSameLength(false);
2234*cdf0e10cSrcweir             bool bSameDirection(false);
2235*cdf0e10cSrcweir 
2236*cdf0e10cSrcweir             // get vector values
2237*cdf0e10cSrcweir             Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection);
2238*cdf0e10cSrcweir 
2239*cdf0e10cSrcweir             if(drawing::PolygonFlags_CONTROL == aFPrev2)
2240*cdf0e10cSrcweir             {
2241*cdf0e10cSrcweir                 // point before is a control point
2242*cdf0e10cSrcweir                 if(bSameDirection)
2243*cdf0e10cSrcweir                 {
2244*cdf0e10cSrcweir                     if(bSameLength)
2245*cdf0e10cSrcweir                     {
2246*cdf0e10cSrcweir                         // set to PolygonFlags_SYMMETRIC
2247*cdf0e10cSrcweir                         pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC;
2248*cdf0e10cSrcweir                     }
2249*cdf0e10cSrcweir                     else
2250*cdf0e10cSrcweir                     {
2251*cdf0e10cSrcweir                         // set to PolygonFlags_SMOOTH
2252*cdf0e10cSrcweir                         pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH;
2253*cdf0e10cSrcweir                     }
2254*cdf0e10cSrcweir                 }
2255*cdf0e10cSrcweir                 else
2256*cdf0e10cSrcweir                 {
2257*cdf0e10cSrcweir                     // set to PolygonFlags_NORMAL
2258*cdf0e10cSrcweir                     pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL;
2259*cdf0e10cSrcweir                 }
2260*cdf0e10cSrcweir             }
2261*cdf0e10cSrcweir             else
2262*cdf0e10cSrcweir             {
2263*cdf0e10cSrcweir                 // point before is a simple curve point
2264*cdf0e10cSrcweir                 if(bSameDirection)
2265*cdf0e10cSrcweir                 {
2266*cdf0e10cSrcweir                     // set to PolygonFlags_SMOOTH
2267*cdf0e10cSrcweir                     pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH;
2268*cdf0e10cSrcweir                 }
2269*cdf0e10cSrcweir                 else
2270*cdf0e10cSrcweir                 {
2271*cdf0e10cSrcweir                     // set to PolygonFlags_NORMAL
2272*cdf0e10cSrcweir                     pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL;
2273*cdf0e10cSrcweir                 }
2274*cdf0e10cSrcweir             }
2275*cdf0e10cSrcweir         }
2276*cdf0e10cSrcweir         else
2277*cdf0e10cSrcweir         {
2278*cdf0e10cSrcweir             // no point before starpoint, set type to PolygonFlags_NORMAL
2279*cdf0e10cSrcweir             pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL;
2280*cdf0e10cSrcweir         }
2281*cdf0e10cSrcweir     }
2282*cdf0e10cSrcweir }
2283*cdf0e10cSrcweir 
2284*cdf0e10cSrcweir SdXMLImExSvgDElement::SdXMLImExSvgDElement(const OUString& rNew,
2285*cdf0e10cSrcweir     const SdXMLImExViewBox& rViewBox,
2286*cdf0e10cSrcweir     const awt::Point& rObjectPos,
2287*cdf0e10cSrcweir     const awt::Size& rObjectSize,
2288*cdf0e10cSrcweir     const SvXMLUnitConverter& rConv)
2289*cdf0e10cSrcweir :   msString( rNew ),
2290*cdf0e10cSrcweir     mrViewBox( rViewBox ),
2291*cdf0e10cSrcweir     mbIsClosed( false ),
2292*cdf0e10cSrcweir     mbIsCurve( false ),
2293*cdf0e10cSrcweir     mnLastX( 0L ),
2294*cdf0e10cSrcweir     mnLastY( 0L ),
2295*cdf0e10cSrcweir     maPoly( 0L ),
2296*cdf0e10cSrcweir     maFlag( 0L )
2297*cdf0e10cSrcweir {
2298*cdf0e10cSrcweir     // convert string to polygon
2299*cdf0e10cSrcweir     const OUString aStr(msString.getStr(), msString.getLength());
2300*cdf0e10cSrcweir     const sal_Int32 nLen(aStr.getLength());
2301*cdf0e10cSrcweir     sal_Int32 nPos(0);
2302*cdf0e10cSrcweir     sal_Int32 nNumPolys(0L);
2303*cdf0e10cSrcweir     bool bEllipticalArc(false);
2304*cdf0e10cSrcweir 
2305*cdf0e10cSrcweir     // object size and ViewBox size different?
2306*cdf0e10cSrcweir     bool bScale(rObjectSize.Width != mrViewBox.GetWidth()
2307*cdf0e10cSrcweir         || rObjectSize.Height != mrViewBox.GetHeight());
2308*cdf0e10cSrcweir     bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L);
2309*cdf0e10cSrcweir 
2310*cdf0e10cSrcweir     // first loop: count polys and get flags
2311*cdf0e10cSrcweir     Imp_SkipSpaces(aStr, nPos, nLen);
2312*cdf0e10cSrcweir 
2313*cdf0e10cSrcweir     while(nPos < nLen)
2314*cdf0e10cSrcweir     {
2315*cdf0e10cSrcweir         switch(aStr[nPos++])
2316*cdf0e10cSrcweir         {
2317*cdf0e10cSrcweir             case 'Z' :
2318*cdf0e10cSrcweir             case 'z' :
2319*cdf0e10cSrcweir             {
2320*cdf0e10cSrcweir                 break;
2321*cdf0e10cSrcweir             }
2322*cdf0e10cSrcweir             case 'M' :
2323*cdf0e10cSrcweir             case 'm' :
2324*cdf0e10cSrcweir             {
2325*cdf0e10cSrcweir                 nNumPolys++;
2326*cdf0e10cSrcweir                 break;
2327*cdf0e10cSrcweir             }
2328*cdf0e10cSrcweir             case 'S' :
2329*cdf0e10cSrcweir             case 's' :
2330*cdf0e10cSrcweir             case 'C' :
2331*cdf0e10cSrcweir             case 'c' :
2332*cdf0e10cSrcweir             case 'Q' :
2333*cdf0e10cSrcweir             case 'q' :
2334*cdf0e10cSrcweir             case 'T' :
2335*cdf0e10cSrcweir             case 't' :
2336*cdf0e10cSrcweir             {
2337*cdf0e10cSrcweir                 mbIsCurve = true;
2338*cdf0e10cSrcweir                 break;
2339*cdf0e10cSrcweir             }
2340*cdf0e10cSrcweir             case 'L' :
2341*cdf0e10cSrcweir             case 'l' :
2342*cdf0e10cSrcweir             case 'H' :
2343*cdf0e10cSrcweir             case 'h' :
2344*cdf0e10cSrcweir             case 'V' :
2345*cdf0e10cSrcweir             case 'v' :
2346*cdf0e10cSrcweir             {
2347*cdf0e10cSrcweir                 // normal, interpreted values. All okay.
2348*cdf0e10cSrcweir                 break;
2349*cdf0e10cSrcweir             }
2350*cdf0e10cSrcweir             case 'A' :
2351*cdf0e10cSrcweir             case 'a' :
2352*cdf0e10cSrcweir             {
2353*cdf0e10cSrcweir                 // Not yet interpreted value.
2354*cdf0e10cSrcweir                 bEllipticalArc = true;
2355*cdf0e10cSrcweir                 break;
2356*cdf0e10cSrcweir             }
2357*cdf0e10cSrcweir         }
2358*cdf0e10cSrcweir     }
2359*cdf0e10cSrcweir 
2360*cdf0e10cSrcweir     DBG_ASSERT(!bEllipticalArc, "XMLIMP: non-interpreted tags in svg:d element!");
2361*cdf0e10cSrcweir 
2362*cdf0e10cSrcweir     if(nNumPolys)
2363*cdf0e10cSrcweir     {
2364*cdf0e10cSrcweir         // alloc arrays
2365*cdf0e10cSrcweir         maPoly.realloc(nNumPolys);
2366*cdf0e10cSrcweir         if(IsCurve())
2367*cdf0e10cSrcweir             maFlag.realloc(nNumPolys);
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir         // get outer sequences
2370*cdf0e10cSrcweir         drawing::PointSequence* pOuterSequence = maPoly.getArray();
2371*cdf0e10cSrcweir         drawing::FlagSequence* pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L;
2372*cdf0e10cSrcweir 
2373*cdf0e10cSrcweir         // prepare new loop, count
2374*cdf0e10cSrcweir         sal_uInt32 nPointCount(0L);
2375*cdf0e10cSrcweir         nPos = 0;
2376*cdf0e10cSrcweir         Imp_SkipSpaces(aStr, nPos, nLen);
2377*cdf0e10cSrcweir 
2378*cdf0e10cSrcweir         // #104076# reset closed flag for next to be started polygon
2379*cdf0e10cSrcweir         mbIsClosed = false;
2380*cdf0e10cSrcweir 
2381*cdf0e10cSrcweir         while(nPos < nLen)
2382*cdf0e10cSrcweir         {
2383*cdf0e10cSrcweir             switch(aStr[nPos])
2384*cdf0e10cSrcweir             {
2385*cdf0e10cSrcweir                 case 'z' :
2386*cdf0e10cSrcweir                 case 'Z' :
2387*cdf0e10cSrcweir                 {
2388*cdf0e10cSrcweir                     nPos++;
2389*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2390*cdf0e10cSrcweir 
2391*cdf0e10cSrcweir                     // #104076# remember closed state of current polygon
2392*cdf0e10cSrcweir                     mbIsClosed = true;
2393*cdf0e10cSrcweir 
2394*cdf0e10cSrcweir                     break;
2395*cdf0e10cSrcweir                 }
2396*cdf0e10cSrcweir                 case 'm' :
2397*cdf0e10cSrcweir                 case 'M' :
2398*cdf0e10cSrcweir                 {
2399*cdf0e10cSrcweir                     // new poly starts, end-process current poly
2400*cdf0e10cSrcweir                     if(nPointCount)
2401*cdf0e10cSrcweir                     {
2402*cdf0e10cSrcweir                         // #104076# If this partial polygon is closed, use one more point
2403*cdf0e10cSrcweir                         // to represent that
2404*cdf0e10cSrcweir                         if(mbIsClosed)
2405*cdf0e10cSrcweir                         {
2406*cdf0e10cSrcweir                             nPointCount++;
2407*cdf0e10cSrcweir                         }
2408*cdf0e10cSrcweir 
2409*cdf0e10cSrcweir                         pOuterSequence->realloc(nPointCount);
2410*cdf0e10cSrcweir                         pOuterSequence++;
2411*cdf0e10cSrcweir 
2412*cdf0e10cSrcweir                         if(pOuterFlags)
2413*cdf0e10cSrcweir                         {
2414*cdf0e10cSrcweir                             pOuterFlags->realloc(nPointCount);
2415*cdf0e10cSrcweir                             pOuterFlags++;
2416*cdf0e10cSrcweir                         }
2417*cdf0e10cSrcweir 
2418*cdf0e10cSrcweir                         // reset point count for next polygon
2419*cdf0e10cSrcweir                         nPointCount = 0L;
2420*cdf0e10cSrcweir                     }
2421*cdf0e10cSrcweir 
2422*cdf0e10cSrcweir                     // #104076# reset closed flag for next to be started polygon
2423*cdf0e10cSrcweir                     mbIsClosed = false;
2424*cdf0e10cSrcweir 
2425*cdf0e10cSrcweir                     // NO break, continue in next case
2426*cdf0e10cSrcweir                 }
2427*cdf0e10cSrcweir                 case 'L' :
2428*cdf0e10cSrcweir                 case 'l' :
2429*cdf0e10cSrcweir                 {
2430*cdf0e10cSrcweir                     nPos++;
2431*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2432*cdf0e10cSrcweir 
2433*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2434*cdf0e10cSrcweir                     {
2435*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2436*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2437*cdf0e10cSrcweir                         nPointCount++;
2438*cdf0e10cSrcweir                     }
2439*cdf0e10cSrcweir                     break;
2440*cdf0e10cSrcweir                 }
2441*cdf0e10cSrcweir                 case 'H' :
2442*cdf0e10cSrcweir                 case 'h' :
2443*cdf0e10cSrcweir                 case 'V' :
2444*cdf0e10cSrcweir                 case 'v' :
2445*cdf0e10cSrcweir                 {
2446*cdf0e10cSrcweir                     nPos++;
2447*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2448*cdf0e10cSrcweir 
2449*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2450*cdf0e10cSrcweir                     {
2451*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2452*cdf0e10cSrcweir                         nPointCount++;
2453*cdf0e10cSrcweir                     }
2454*cdf0e10cSrcweir                     break;
2455*cdf0e10cSrcweir                 }
2456*cdf0e10cSrcweir                 case 'S' :
2457*cdf0e10cSrcweir                 case 's' :
2458*cdf0e10cSrcweir                 {
2459*cdf0e10cSrcweir                     nPos++;
2460*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2461*cdf0e10cSrcweir 
2462*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2463*cdf0e10cSrcweir                     {
2464*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2465*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2466*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2467*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2468*cdf0e10cSrcweir                         nPointCount += 3;
2469*cdf0e10cSrcweir                     }
2470*cdf0e10cSrcweir                     break;
2471*cdf0e10cSrcweir                 }
2472*cdf0e10cSrcweir                 case 'C' :
2473*cdf0e10cSrcweir                 case 'c' :
2474*cdf0e10cSrcweir                 {
2475*cdf0e10cSrcweir                     nPos++;
2476*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2477*cdf0e10cSrcweir 
2478*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2479*cdf0e10cSrcweir                     {
2480*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2481*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2482*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2483*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2484*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2485*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2486*cdf0e10cSrcweir                         nPointCount += 3;
2487*cdf0e10cSrcweir                     }
2488*cdf0e10cSrcweir                     break;
2489*cdf0e10cSrcweir                 }
2490*cdf0e10cSrcweir 
2491*cdf0e10cSrcweir                 // #100617# quadratic beziers, supported as cubic ones
2492*cdf0e10cSrcweir                 case 'Q' :
2493*cdf0e10cSrcweir                 case 'q' :
2494*cdf0e10cSrcweir                 {
2495*cdf0e10cSrcweir                     nPos++;
2496*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2497*cdf0e10cSrcweir 
2498*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2499*cdf0e10cSrcweir                     {
2500*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2501*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2502*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2503*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2504*cdf0e10cSrcweir 
2505*cdf0e10cSrcweir                         // use three points since quadratic is imported as cubic
2506*cdf0e10cSrcweir                         nPointCount += 3;
2507*cdf0e10cSrcweir                     }
2508*cdf0e10cSrcweir                     break;
2509*cdf0e10cSrcweir                 }
2510*cdf0e10cSrcweir 
2511*cdf0e10cSrcweir                 // #100617# relative quadratic beziers, supported as cubic ones
2512*cdf0e10cSrcweir                 case 'T' :
2513*cdf0e10cSrcweir                 case 't' :
2514*cdf0e10cSrcweir                 {
2515*cdf0e10cSrcweir                     nPos++;
2516*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2517*cdf0e10cSrcweir 
2518*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2519*cdf0e10cSrcweir                     {
2520*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2521*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2522*cdf0e10cSrcweir 
2523*cdf0e10cSrcweir                         // use three points since quadratic is imported as cubic
2524*cdf0e10cSrcweir                         nPointCount += 3;
2525*cdf0e10cSrcweir                     }
2526*cdf0e10cSrcweir                     break;
2527*cdf0e10cSrcweir                 }
2528*cdf0e10cSrcweir 
2529*cdf0e10cSrcweir                 // #100617# not yet supported: elliptical arc
2530*cdf0e10cSrcweir                 case 'A' :
2531*cdf0e10cSrcweir                 case 'a' :
2532*cdf0e10cSrcweir                 {
2533*cdf0e10cSrcweir                     DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!");
2534*cdf0e10cSrcweir                     nPos++;
2535*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2536*cdf0e10cSrcweir 
2537*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2538*cdf0e10cSrcweir                     {
2539*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2540*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2541*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2542*cdf0e10cSrcweir                         Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen);
2543*cdf0e10cSrcweir                         Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen);
2544*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2545*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
2546*cdf0e10cSrcweir                     }
2547*cdf0e10cSrcweir                     break;
2548*cdf0e10cSrcweir                 }
2549*cdf0e10cSrcweir 
2550*cdf0e10cSrcweir                 default:
2551*cdf0e10cSrcweir                 {
2552*cdf0e10cSrcweir                     nPos++;
2553*cdf0e10cSrcweir                     DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!");
2554*cdf0e10cSrcweir                     break;
2555*cdf0e10cSrcweir                 }
2556*cdf0e10cSrcweir             }
2557*cdf0e10cSrcweir         }
2558*cdf0e10cSrcweir 
2559*cdf0e10cSrcweir         // alloc last poly (when points used)
2560*cdf0e10cSrcweir         if(nPointCount)
2561*cdf0e10cSrcweir         {
2562*cdf0e10cSrcweir             // #104076# If this partial polygon is closed, use one more point
2563*cdf0e10cSrcweir             // to represent that
2564*cdf0e10cSrcweir             if(mbIsClosed)
2565*cdf0e10cSrcweir             {
2566*cdf0e10cSrcweir                 nPointCount++;
2567*cdf0e10cSrcweir             }
2568*cdf0e10cSrcweir 
2569*cdf0e10cSrcweir             pOuterSequence->realloc(nPointCount);
2570*cdf0e10cSrcweir             pOuterSequence++;
2571*cdf0e10cSrcweir 
2572*cdf0e10cSrcweir             if(pOuterFlags)
2573*cdf0e10cSrcweir             {
2574*cdf0e10cSrcweir                 pOuterFlags->realloc(nPointCount);
2575*cdf0e10cSrcweir                 pOuterFlags++;
2576*cdf0e10cSrcweir             }
2577*cdf0e10cSrcweir         }
2578*cdf0e10cSrcweir 
2579*cdf0e10cSrcweir         // set pointers back
2580*cdf0e10cSrcweir         pOuterSequence = maPoly.getArray();
2581*cdf0e10cSrcweir         pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L;
2582*cdf0e10cSrcweir         awt::Point* pNotSoInnerSequence = 0L;
2583*cdf0e10cSrcweir         drawing::PolygonFlags* pNotSoInnerFlags = 0L;
2584*cdf0e10cSrcweir         sal_uInt32 nInnerIndex(0L);
2585*cdf0e10cSrcweir 
2586*cdf0e10cSrcweir         // prepare new loop, read points
2587*cdf0e10cSrcweir         nPos = 0;
2588*cdf0e10cSrcweir         Imp_SkipSpaces(aStr, nPos, nLen);
2589*cdf0e10cSrcweir 
2590*cdf0e10cSrcweir         // #104076# reset closed flag for next to be started polygon
2591*cdf0e10cSrcweir         mbIsClosed = false;
2592*cdf0e10cSrcweir 
2593*cdf0e10cSrcweir         while(nPos < nLen)
2594*cdf0e10cSrcweir         {
2595*cdf0e10cSrcweir             bool bRelative(false);
2596*cdf0e10cSrcweir 
2597*cdf0e10cSrcweir             switch(aStr[nPos])
2598*cdf0e10cSrcweir             {
2599*cdf0e10cSrcweir                 case 'z' :
2600*cdf0e10cSrcweir                 case 'Z' :
2601*cdf0e10cSrcweir                 {
2602*cdf0e10cSrcweir                     nPos++;
2603*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2604*cdf0e10cSrcweir 
2605*cdf0e10cSrcweir                     // #104076# remember closed state of current polygon
2606*cdf0e10cSrcweir                     mbIsClosed = true;
2607*cdf0e10cSrcweir 
2608*cdf0e10cSrcweir                     // closed: add first point again
2609*cdf0e10cSrcweir                     // sal_Int32 nX(pInnerSequence[0].X);
2610*cdf0e10cSrcweir                     // sal_Int32 nY(pInnerSequence[0].Y);
2611*cdf0e10cSrcweir                     // Imp_AddExportPoints(nX, nY, pInnerSequence, pInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL);
2612*cdf0e10cSrcweir 
2613*cdf0e10cSrcweir                     break;
2614*cdf0e10cSrcweir                 }
2615*cdf0e10cSrcweir 
2616*cdf0e10cSrcweir                 case 'm' :
2617*cdf0e10cSrcweir                 {
2618*cdf0e10cSrcweir                     bRelative = true;
2619*cdf0e10cSrcweir                 }
2620*cdf0e10cSrcweir                 case 'M' :
2621*cdf0e10cSrcweir                 {
2622*cdf0e10cSrcweir                     // #104076# end-process current poly
2623*cdf0e10cSrcweir                     if(mbIsClosed)
2624*cdf0e10cSrcweir                     {
2625*cdf0e10cSrcweir                         if(pNotSoInnerSequence)
2626*cdf0e10cSrcweir                         {
2627*cdf0e10cSrcweir                             // closed: add first point again
2628*cdf0e10cSrcweir                             sal_Int32 nX(pNotSoInnerSequence[0].X);
2629*cdf0e10cSrcweir                             sal_Int32 nY(pNotSoInnerSequence[0].Y);
2630*cdf0e10cSrcweir                             Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL);
2631*cdf0e10cSrcweir                         }
2632*cdf0e10cSrcweir 
2633*cdf0e10cSrcweir                         // reset closed flag for next to be started polygon
2634*cdf0e10cSrcweir                         mbIsClosed = false;
2635*cdf0e10cSrcweir                     }
2636*cdf0e10cSrcweir 
2637*cdf0e10cSrcweir                     // next poly
2638*cdf0e10cSrcweir                     pNotSoInnerSequence = pOuterSequence->getArray();
2639*cdf0e10cSrcweir                     pOuterSequence++;
2640*cdf0e10cSrcweir 
2641*cdf0e10cSrcweir                     if(pOuterFlags)
2642*cdf0e10cSrcweir                     {
2643*cdf0e10cSrcweir                         pNotSoInnerFlags = pOuterFlags->getArray();
2644*cdf0e10cSrcweir                         pOuterFlags++;
2645*cdf0e10cSrcweir                     }
2646*cdf0e10cSrcweir 
2647*cdf0e10cSrcweir                     nInnerIndex = 0L;
2648*cdf0e10cSrcweir 
2649*cdf0e10cSrcweir                     nPos++;
2650*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2651*cdf0e10cSrcweir 
2652*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2653*cdf0e10cSrcweir                     {
2654*cdf0e10cSrcweir                         sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2655*cdf0e10cSrcweir                         sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2656*cdf0e10cSrcweir 
2657*cdf0e10cSrcweir                         if(bRelative)
2658*cdf0e10cSrcweir                         {
2659*cdf0e10cSrcweir                             nX += mnLastX;
2660*cdf0e10cSrcweir                             nY += mnLastY;
2661*cdf0e10cSrcweir                         }
2662*cdf0e10cSrcweir 
2663*cdf0e10cSrcweir                         // set last position
2664*cdf0e10cSrcweir                         mnLastX = nX;
2665*cdf0e10cSrcweir                         mnLastY = nY;
2666*cdf0e10cSrcweir 
2667*cdf0e10cSrcweir                         // calc transform and add point and flag
2668*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2669*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL);
2670*cdf0e10cSrcweir                     }
2671*cdf0e10cSrcweir                     break;
2672*cdf0e10cSrcweir                 }
2673*cdf0e10cSrcweir 
2674*cdf0e10cSrcweir                 case 'l' :
2675*cdf0e10cSrcweir                 {
2676*cdf0e10cSrcweir                     bRelative = true;
2677*cdf0e10cSrcweir                 }
2678*cdf0e10cSrcweir                 case 'L' :
2679*cdf0e10cSrcweir                 {
2680*cdf0e10cSrcweir                     nPos++;
2681*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2682*cdf0e10cSrcweir 
2683*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2684*cdf0e10cSrcweir                     {
2685*cdf0e10cSrcweir                         sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2686*cdf0e10cSrcweir                         sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2687*cdf0e10cSrcweir 
2688*cdf0e10cSrcweir                         if(bRelative)
2689*cdf0e10cSrcweir                         {
2690*cdf0e10cSrcweir                             nX += mnLastX;
2691*cdf0e10cSrcweir                             nY += mnLastY;
2692*cdf0e10cSrcweir                         }
2693*cdf0e10cSrcweir 
2694*cdf0e10cSrcweir                         // set last position
2695*cdf0e10cSrcweir                         mnLastX = nX;
2696*cdf0e10cSrcweir                         mnLastY = nY;
2697*cdf0e10cSrcweir 
2698*cdf0e10cSrcweir                         // calc transform and add point and flag
2699*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2700*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL);
2701*cdf0e10cSrcweir                     }
2702*cdf0e10cSrcweir                     break;
2703*cdf0e10cSrcweir                 }
2704*cdf0e10cSrcweir 
2705*cdf0e10cSrcweir                 case 'h' :
2706*cdf0e10cSrcweir                 {
2707*cdf0e10cSrcweir                     bRelative = true;
2708*cdf0e10cSrcweir                 }
2709*cdf0e10cSrcweir                 case 'H' :
2710*cdf0e10cSrcweir                 {
2711*cdf0e10cSrcweir                     nPos++;
2712*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2713*cdf0e10cSrcweir 
2714*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2715*cdf0e10cSrcweir                     {
2716*cdf0e10cSrcweir                         sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2717*cdf0e10cSrcweir                         sal_Int32 nY(mnLastY);
2718*cdf0e10cSrcweir 
2719*cdf0e10cSrcweir                         if(bRelative)
2720*cdf0e10cSrcweir                             nX += mnLastX;
2721*cdf0e10cSrcweir 
2722*cdf0e10cSrcweir                         // set last position
2723*cdf0e10cSrcweir                         mnLastX = nX;
2724*cdf0e10cSrcweir 
2725*cdf0e10cSrcweir                         // calc transform and add point and flag
2726*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2727*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL);
2728*cdf0e10cSrcweir                     }
2729*cdf0e10cSrcweir                     break;
2730*cdf0e10cSrcweir                 }
2731*cdf0e10cSrcweir 
2732*cdf0e10cSrcweir                 case 'v' :
2733*cdf0e10cSrcweir                 {
2734*cdf0e10cSrcweir                     bRelative = true;
2735*cdf0e10cSrcweir                 }
2736*cdf0e10cSrcweir                 case 'V' :
2737*cdf0e10cSrcweir                 {
2738*cdf0e10cSrcweir                     nPos++;
2739*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2740*cdf0e10cSrcweir 
2741*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2742*cdf0e10cSrcweir                     {
2743*cdf0e10cSrcweir                         sal_Int32 nX(mnLastX);
2744*cdf0e10cSrcweir                         sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2745*cdf0e10cSrcweir 
2746*cdf0e10cSrcweir                         if(bRelative)
2747*cdf0e10cSrcweir                             nY += mnLastY;
2748*cdf0e10cSrcweir 
2749*cdf0e10cSrcweir                         // set last position
2750*cdf0e10cSrcweir                         mnLastY = nY;
2751*cdf0e10cSrcweir 
2752*cdf0e10cSrcweir                         // calc transform and add point and flag
2753*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2754*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL);
2755*cdf0e10cSrcweir                     }
2756*cdf0e10cSrcweir                     break;
2757*cdf0e10cSrcweir                 }
2758*cdf0e10cSrcweir 
2759*cdf0e10cSrcweir                 case 's' :
2760*cdf0e10cSrcweir                 {
2761*cdf0e10cSrcweir                     bRelative = true;
2762*cdf0e10cSrcweir                 }
2763*cdf0e10cSrcweir                 case 'S' :
2764*cdf0e10cSrcweir                 {
2765*cdf0e10cSrcweir                     nPos++;
2766*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2767*cdf0e10cSrcweir 
2768*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2769*cdf0e10cSrcweir                     {
2770*cdf0e10cSrcweir                         sal_Int32 nX1;
2771*cdf0e10cSrcweir                         sal_Int32 nY1;
2772*cdf0e10cSrcweir                         sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2773*cdf0e10cSrcweir                         sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2774*cdf0e10cSrcweir                         sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2775*cdf0e10cSrcweir                         sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2776*cdf0e10cSrcweir 
2777*cdf0e10cSrcweir                         if(bRelative)
2778*cdf0e10cSrcweir                         {
2779*cdf0e10cSrcweir                             nX2 += mnLastX;
2780*cdf0e10cSrcweir                             nY2 += mnLastY;
2781*cdf0e10cSrcweir                             nX += mnLastX;
2782*cdf0e10cSrcweir                             nY += mnLastY;
2783*cdf0e10cSrcweir                         }
2784*cdf0e10cSrcweir 
2785*cdf0e10cSrcweir                         // set last position
2786*cdf0e10cSrcweir                         mnLastX = nX;
2787*cdf0e10cSrcweir                         mnLastY = nY;
2788*cdf0e10cSrcweir 
2789*cdf0e10cSrcweir                         // calc transform for new points
2790*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2791*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2792*cdf0e10cSrcweir 
2793*cdf0e10cSrcweir                         // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC
2794*cdf0e10cSrcweir                         // and the Point X1,Y1 can be constructed by mirroring the point before it.
2795*cdf0e10cSrcweir                         nX1 = nX2;
2796*cdf0e10cSrcweir                         nY1 = nY2;
2797*cdf0e10cSrcweir                         if(nInnerIndex)
2798*cdf0e10cSrcweir                         {
2799*cdf0e10cSrcweir                             awt::Point aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1];
2800*cdf0e10cSrcweir 
2801*cdf0e10cSrcweir                             if(nInnerIndex > 1)
2802*cdf0e10cSrcweir                             {
2803*cdf0e10cSrcweir                                 awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2];
2804*cdf0e10cSrcweir                                 nX1 = aPPrev1.X -(aPPrev2.X - aPPrev1.X);
2805*cdf0e10cSrcweir                                 nY1 = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y);
2806*cdf0e10cSrcweir                             }
2807*cdf0e10cSrcweir 
2808*cdf0e10cSrcweir                             // set curve point to symmetric
2809*cdf0e10cSrcweir                             pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC;
2810*cdf0e10cSrcweir                         }
2811*cdf0e10cSrcweir 
2812*cdf0e10cSrcweir                         // add calculated control point
2813*cdf0e10cSrcweir                         Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2814*cdf0e10cSrcweir 
2815*cdf0e10cSrcweir                         // add new points and set flags
2816*cdf0e10cSrcweir                         Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2817*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH);
2818*cdf0e10cSrcweir                     }
2819*cdf0e10cSrcweir                     break;
2820*cdf0e10cSrcweir                 }
2821*cdf0e10cSrcweir 
2822*cdf0e10cSrcweir                 case 'c' :
2823*cdf0e10cSrcweir                 {
2824*cdf0e10cSrcweir                     bRelative = true;
2825*cdf0e10cSrcweir                 }
2826*cdf0e10cSrcweir                 case 'C' :
2827*cdf0e10cSrcweir                 {
2828*cdf0e10cSrcweir                     nPos++;
2829*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2830*cdf0e10cSrcweir 
2831*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2832*cdf0e10cSrcweir                     {
2833*cdf0e10cSrcweir                         sal_Int32 nX1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2834*cdf0e10cSrcweir                         sal_Int32 nY1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2835*cdf0e10cSrcweir                         sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2836*cdf0e10cSrcweir                         sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2837*cdf0e10cSrcweir                         sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2838*cdf0e10cSrcweir                         sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2839*cdf0e10cSrcweir 
2840*cdf0e10cSrcweir                         if(bRelative)
2841*cdf0e10cSrcweir                         {
2842*cdf0e10cSrcweir                             nX1 += mnLastX;
2843*cdf0e10cSrcweir                             nY1 += mnLastY;
2844*cdf0e10cSrcweir                             nX2 += mnLastX;
2845*cdf0e10cSrcweir                             nY2 += mnLastY;
2846*cdf0e10cSrcweir                             nX += mnLastX;
2847*cdf0e10cSrcweir                             nY += mnLastY;
2848*cdf0e10cSrcweir                         }
2849*cdf0e10cSrcweir 
2850*cdf0e10cSrcweir                         // set last position
2851*cdf0e10cSrcweir                         mnLastX = nX;
2852*cdf0e10cSrcweir                         mnLastY = nY;
2853*cdf0e10cSrcweir 
2854*cdf0e10cSrcweir                         // calc transform for new points
2855*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX1, nY1, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2856*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2857*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2858*cdf0e10cSrcweir 
2859*cdf0e10cSrcweir                         // correct polygon flag for previous point
2860*cdf0e10cSrcweir                         Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1);
2861*cdf0e10cSrcweir 
2862*cdf0e10cSrcweir                         // add new points and set flags
2863*cdf0e10cSrcweir                         Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2864*cdf0e10cSrcweir                         Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2865*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH);
2866*cdf0e10cSrcweir                     }
2867*cdf0e10cSrcweir                     break;
2868*cdf0e10cSrcweir                 }
2869*cdf0e10cSrcweir 
2870*cdf0e10cSrcweir                 // #100617# quadratic beziers are imported as cubic
2871*cdf0e10cSrcweir                 case 'q' :
2872*cdf0e10cSrcweir                 {
2873*cdf0e10cSrcweir                     bRelative = true;
2874*cdf0e10cSrcweir                 }
2875*cdf0e10cSrcweir                 case 'Q' :
2876*cdf0e10cSrcweir                 {
2877*cdf0e10cSrcweir                     nPos++;
2878*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2879*cdf0e10cSrcweir 
2880*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2881*cdf0e10cSrcweir                     {
2882*cdf0e10cSrcweir                         sal_Int32 nXX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2883*cdf0e10cSrcweir                         sal_Int32 nYY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2884*cdf0e10cSrcweir                         sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2885*cdf0e10cSrcweir                         sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2886*cdf0e10cSrcweir 
2887*cdf0e10cSrcweir                         if(bRelative)
2888*cdf0e10cSrcweir                         {
2889*cdf0e10cSrcweir                             nXX += mnLastX;
2890*cdf0e10cSrcweir                             nYY += mnLastY;
2891*cdf0e10cSrcweir                             nX += mnLastX;
2892*cdf0e10cSrcweir                             nY += mnLastY;
2893*cdf0e10cSrcweir                         }
2894*cdf0e10cSrcweir 
2895*cdf0e10cSrcweir                         // set last position
2896*cdf0e10cSrcweir                         mnLastX = nX;
2897*cdf0e10cSrcweir                         mnLastY = nY;
2898*cdf0e10cSrcweir 
2899*cdf0e10cSrcweir                         // calc transform for new points
2900*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nXX, nYY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2901*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2902*cdf0e10cSrcweir 
2903*cdf0e10cSrcweir                         // calculate X1,X2
2904*cdf0e10cSrcweir                         awt::Point aPPrev1 = (nInnerIndex) ? pNotSoInnerSequence[nInnerIndex-1] : pNotSoInnerSequence[0];
2905*cdf0e10cSrcweir                         sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0);
2906*cdf0e10cSrcweir                         sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0);
2907*cdf0e10cSrcweir                         sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0);
2908*cdf0e10cSrcweir                         sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0);
2909*cdf0e10cSrcweir 
2910*cdf0e10cSrcweir                         // correct polygon flag for previous point
2911*cdf0e10cSrcweir                         Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1);
2912*cdf0e10cSrcweir 
2913*cdf0e10cSrcweir                         // add new points and set flags
2914*cdf0e10cSrcweir                         Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2915*cdf0e10cSrcweir                         Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2916*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH);
2917*cdf0e10cSrcweir                     }
2918*cdf0e10cSrcweir                     break;
2919*cdf0e10cSrcweir                 }
2920*cdf0e10cSrcweir 
2921*cdf0e10cSrcweir                 // #100617# relative quadratic beziers are imported as cubic
2922*cdf0e10cSrcweir                 case 't' :
2923*cdf0e10cSrcweir                 {
2924*cdf0e10cSrcweir                     bRelative = true;
2925*cdf0e10cSrcweir                 }
2926*cdf0e10cSrcweir                 case 'T' :
2927*cdf0e10cSrcweir                 {
2928*cdf0e10cSrcweir                     nPos++;
2929*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2930*cdf0e10cSrcweir 
2931*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2932*cdf0e10cSrcweir                     {
2933*cdf0e10cSrcweir                         sal_Int32 nXX;
2934*cdf0e10cSrcweir                         sal_Int32 nYY;
2935*cdf0e10cSrcweir                         sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2936*cdf0e10cSrcweir                         sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv));
2937*cdf0e10cSrcweir 
2938*cdf0e10cSrcweir                         if(bRelative)
2939*cdf0e10cSrcweir                         {
2940*cdf0e10cSrcweir                             nX += mnLastX;
2941*cdf0e10cSrcweir                             nY += mnLastY;
2942*cdf0e10cSrcweir                         }
2943*cdf0e10cSrcweir 
2944*cdf0e10cSrcweir                         // set last position
2945*cdf0e10cSrcweir                         mnLastX = nX;
2946*cdf0e10cSrcweir                         mnLastY = nY;
2947*cdf0e10cSrcweir 
2948*cdf0e10cSrcweir                         // calc transform for new points
2949*cdf0e10cSrcweir                         Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate);
2950*cdf0e10cSrcweir 
2951*cdf0e10cSrcweir                         // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC
2952*cdf0e10cSrcweir                         // and the Point X1,Y1 can be constructed by mirroring the point before it.
2953*cdf0e10cSrcweir                         nXX = nX;
2954*cdf0e10cSrcweir                         nYY = nY;
2955*cdf0e10cSrcweir                         awt::Point aPPrev1 = pNotSoInnerSequence[0];
2956*cdf0e10cSrcweir 
2957*cdf0e10cSrcweir                         if(nInnerIndex)
2958*cdf0e10cSrcweir                         {
2959*cdf0e10cSrcweir                             aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1];
2960*cdf0e10cSrcweir 
2961*cdf0e10cSrcweir                             if(nInnerIndex > 1)
2962*cdf0e10cSrcweir                             {
2963*cdf0e10cSrcweir                                 awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2];
2964*cdf0e10cSrcweir                                 nXX = aPPrev1.X -(aPPrev2.X - aPPrev1.X);
2965*cdf0e10cSrcweir                                 nYY = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y);
2966*cdf0e10cSrcweir                             }
2967*cdf0e10cSrcweir 
2968*cdf0e10cSrcweir                             // set curve point to smooth here, since length
2969*cdf0e10cSrcweir                             // is changed and thus only c1 can be used.
2970*cdf0e10cSrcweir                             pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH;
2971*cdf0e10cSrcweir                         }
2972*cdf0e10cSrcweir 
2973*cdf0e10cSrcweir                         // calculate X1,X2
2974*cdf0e10cSrcweir                         sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0);
2975*cdf0e10cSrcweir                         sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0);
2976*cdf0e10cSrcweir                         sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0);
2977*cdf0e10cSrcweir                         sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0);
2978*cdf0e10cSrcweir 
2979*cdf0e10cSrcweir                         // correct polygon flag for previous point
2980*cdf0e10cSrcweir                         Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1);
2981*cdf0e10cSrcweir 
2982*cdf0e10cSrcweir                         // add new points and set flags
2983*cdf0e10cSrcweir                         Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2984*cdf0e10cSrcweir                         Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL);
2985*cdf0e10cSrcweir                         Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH);
2986*cdf0e10cSrcweir                     }
2987*cdf0e10cSrcweir                     break;
2988*cdf0e10cSrcweir                 }
2989*cdf0e10cSrcweir 
2990*cdf0e10cSrcweir                 // #100617# not yet supported: elliptical arc
2991*cdf0e10cSrcweir                 case 'A' :
2992*cdf0e10cSrcweir                 case 'a' :
2993*cdf0e10cSrcweir                 {
2994*cdf0e10cSrcweir                     DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!");
2995*cdf0e10cSrcweir                     nPos++;
2996*cdf0e10cSrcweir                     Imp_SkipSpaces(aStr, nPos, nLen);
2997*cdf0e10cSrcweir 
2998*cdf0e10cSrcweir                     while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos))
2999*cdf0e10cSrcweir                     {
3000*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
3001*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
3002*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
3003*cdf0e10cSrcweir                         Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen);
3004*cdf0e10cSrcweir                         Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen);
3005*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
3006*cdf0e10cSrcweir                         Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen);
3007*cdf0e10cSrcweir                     }
3008*cdf0e10cSrcweir                     break;
3009*cdf0e10cSrcweir                 }
3010*cdf0e10cSrcweir 
3011*cdf0e10cSrcweir                 default:
3012*cdf0e10cSrcweir                 {
3013*cdf0e10cSrcweir                     nPos++;
3014*cdf0e10cSrcweir                     DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!");
3015*cdf0e10cSrcweir                     break;
3016*cdf0e10cSrcweir                 }
3017*cdf0e10cSrcweir             }
3018*cdf0e10cSrcweir         }
3019*cdf0e10cSrcweir 
3020*cdf0e10cSrcweir         // #104076# end-process closed state of last poly
3021*cdf0e10cSrcweir         if(mbIsClosed)
3022*cdf0e10cSrcweir         {
3023*cdf0e10cSrcweir             if(pNotSoInnerSequence)
3024*cdf0e10cSrcweir             {
3025*cdf0e10cSrcweir                 // closed: add first point again
3026*cdf0e10cSrcweir                 sal_Int32 nX(pNotSoInnerSequence[0].X);
3027*cdf0e10cSrcweir                 sal_Int32 nY(pNotSoInnerSequence[0].Y);
3028*cdf0e10cSrcweir                 Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL);
3029*cdf0e10cSrcweir             }
3030*cdf0e10cSrcweir         }
3031*cdf0e10cSrcweir 
3032*cdf0e10cSrcweir         // #87202# If it's a curve and it's closed the last point maybe too much
3033*cdf0e10cSrcweir         // and just exported since SVG does not allow special handling of same
3034*cdf0e10cSrcweir         // start and end point, remove this last point.
3035*cdf0e10cSrcweir         // Evtl. correct the last curve flags, too.
3036*cdf0e10cSrcweir         if(IsCurve() && IsClosed())
3037*cdf0e10cSrcweir         {
3038*cdf0e10cSrcweir             // make one more loop over the PolyPolygon
3039*cdf0e10cSrcweir             pOuterSequence = maPoly.getArray();
3040*cdf0e10cSrcweir             pOuterFlags = maFlag.getArray();
3041*cdf0e10cSrcweir             sal_Int32 nOuterCnt(maPoly.getLength());
3042*cdf0e10cSrcweir 
3043*cdf0e10cSrcweir             for(sal_Int32 a(0); a < nOuterCnt; a++)
3044*cdf0e10cSrcweir             {
3045*cdf0e10cSrcweir                 // get Polygon pointers
3046*cdf0e10cSrcweir                 awt::Point* pInnerSequence = pOuterSequence->getArray();
3047*cdf0e10cSrcweir                 drawing::PolygonFlags* pInnerFlags = pOuterFlags->getArray();
3048*cdf0e10cSrcweir                 sal_Int32 nInnerCnt(pOuterSequence->getLength());
3049*cdf0e10cSrcweir 
3050*cdf0e10cSrcweir                 while( nInnerCnt >= 2
3051*cdf0e10cSrcweir                     && ((pInnerSequence + (nInnerCnt - 2))->X == (pInnerSequence + (nInnerCnt - 1))->X)
3052*cdf0e10cSrcweir                     && ((pInnerSequence + (nInnerCnt - 2))->Y == (pInnerSequence + (nInnerCnt - 1))->Y)
3053*cdf0e10cSrcweir                     && drawing::PolygonFlags_CONTROL != *(pInnerFlags + (nInnerCnt - 2)))
3054*cdf0e10cSrcweir                 {
3055*cdf0e10cSrcweir                     // remove last point from array
3056*cdf0e10cSrcweir                     pOuterSequence->realloc(nInnerCnt - 1);
3057*cdf0e10cSrcweir                     pOuterFlags->realloc(nInnerCnt - 1);
3058*cdf0e10cSrcweir 
3059*cdf0e10cSrcweir                     // get new pointers
3060*cdf0e10cSrcweir                     pInnerSequence = pOuterSequence->getArray();
3061*cdf0e10cSrcweir                     pInnerFlags = pOuterFlags->getArray();
3062*cdf0e10cSrcweir                     nInnerCnt = pOuterSequence->getLength();
3063*cdf0e10cSrcweir                 }
3064*cdf0e10cSrcweir 
3065*cdf0e10cSrcweir                 // now evtl. correct the last curve flags
3066*cdf0e10cSrcweir                 if(nInnerCnt >= 4)
3067*cdf0e10cSrcweir                 {
3068*cdf0e10cSrcweir                     if( pInnerSequence->X == (pInnerSequence + (nInnerCnt - 1))->X
3069*cdf0e10cSrcweir                         && pInnerSequence->Y == (pInnerSequence + (nInnerCnt - 1))->Y
3070*cdf0e10cSrcweir                         && drawing::PolygonFlags_CONTROL == *(pInnerFlags + 1)
3071*cdf0e10cSrcweir                         && drawing::PolygonFlags_CONTROL == *(pInnerFlags + (nInnerCnt - 2)))
3072*cdf0e10cSrcweir                     {
3073*cdf0e10cSrcweir                         awt::Point aPrev = *(pInnerSequence + (nInnerCnt - 2));
3074*cdf0e10cSrcweir                         awt::Point aCurr = *pInnerSequence;
3075*cdf0e10cSrcweir                         awt::Point aNext = *(pInnerSequence + 1);
3076*cdf0e10cSrcweir                         ::basegfx::B2DVector aVec1(aPrev.X - aCurr.X, aPrev.Y - aCurr.Y);
3077*cdf0e10cSrcweir                         ::basegfx::B2DVector aVec2(aNext.X - aCurr.X, aNext.Y - aCurr.Y);
3078*cdf0e10cSrcweir                         bool bSameLength(false);
3079*cdf0e10cSrcweir                         bool bSameDirection(false);
3080*cdf0e10cSrcweir 
3081*cdf0e10cSrcweir                         // get vector values
3082*cdf0e10cSrcweir                         Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection);
3083*cdf0e10cSrcweir 
3084*cdf0e10cSrcweir                         // set correct flag value
3085*cdf0e10cSrcweir                         if(bSameDirection)
3086*cdf0e10cSrcweir                         {
3087*cdf0e10cSrcweir                             if(bSameLength)
3088*cdf0e10cSrcweir                             {
3089*cdf0e10cSrcweir                                 // set to PolygonFlags_SYMMETRIC
3090*cdf0e10cSrcweir                                 *pInnerFlags = drawing::PolygonFlags_SYMMETRIC;
3091*cdf0e10cSrcweir                                 *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SYMMETRIC;
3092*cdf0e10cSrcweir                             }
3093*cdf0e10cSrcweir                             else
3094*cdf0e10cSrcweir                             {
3095*cdf0e10cSrcweir                                 // set to PolygonFlags_SMOOTH
3096*cdf0e10cSrcweir                                 *pInnerFlags = drawing::PolygonFlags_SMOOTH;
3097*cdf0e10cSrcweir                                 *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SMOOTH;
3098*cdf0e10cSrcweir                             }
3099*cdf0e10cSrcweir                         }
3100*cdf0e10cSrcweir                         else
3101*cdf0e10cSrcweir                         {
3102*cdf0e10cSrcweir                             // set to PolygonFlags_NORMAL
3103*cdf0e10cSrcweir                             *pInnerFlags = drawing::PolygonFlags_NORMAL;
3104*cdf0e10cSrcweir                             *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_NORMAL;
3105*cdf0e10cSrcweir                         }
3106*cdf0e10cSrcweir                     }
3107*cdf0e10cSrcweir                 }
3108*cdf0e10cSrcweir 
3109*cdf0e10cSrcweir                 // switch to next Polygon
3110*cdf0e10cSrcweir                 pOuterSequence++;
3111*cdf0e10cSrcweir                 pOuterFlags++;
3112*cdf0e10cSrcweir             }
3113*cdf0e10cSrcweir         }
3114*cdf0e10cSrcweir     }
3115*cdf0e10cSrcweir }
3116*cdf0e10cSrcweir 
3117*cdf0e10cSrcweir // eof
3118