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