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