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