Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "ximpcustomshape.hxx"
21 : #include "ximpshap.hxx"
22 : #include <rtl/math.hxx>
23 : #include <rtl/ustrbuf.hxx>
24 : #include <rtl/ustring.hxx>
25 : #include <com/sun/star/uno/Reference.h>
26 : #include <com/sun/star/beans/XPropertySet.hpp>
27 : #include <com/sun/star/xml/sax/XAttributeList.hpp>
28 : #include <com/sun/star/container/XIndexContainer.hpp>
29 : #include <xmloff/xmltoken.hxx>
30 : #include "EnhancedCustomShapeToken.hxx"
31 : #include <xmloff/xmlimp.hxx>
32 : #include <xmloff/xmltkmap.hxx>
33 : #include <xmloff/xmlnmspe.hxx>
34 : #include <xmloff/nmspmap.hxx>
35 : #include <xmloff/xmluconv.hxx>
36 : #include "xexptran.hxx"
37 : #include <xmloff/xmlerror.hxx>
38 : #include <com/sun/star/drawing/Direction3D.hpp>
39 : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
40 : #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
41 : #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
42 : #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
43 : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
44 : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
45 : #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
46 : #include <com/sun/star/drawing/ProjectionMode.hpp>
47 : #include <com/sun/star/drawing/HomogenMatrix3.hpp>
48 : #include <boost/unordered_map.hpp>
49 : #include <basegfx/vector/b2dvector.hxx>
50 : #include <sax/tools/converter.hxx>
51 :
52 : using namespace ::com::sun::star;
53 : using namespace ::xmloff::token;
54 : using namespace ::xmloff::EnhancedCustomShapeToken;
55 :
56 0 : TYPEINIT1( XMLEnhancedCustomShapeContext, SvXMLImportContext );
57 :
58 69 : XMLEnhancedCustomShapeContext::XMLEnhancedCustomShapeContext( SvXMLImport& rImport,
59 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
60 : sal_uInt16 nPrefix, const OUString& rLocalName,
61 : std::vector< com::sun::star::beans::PropertyValue >& rCustomShapeGeometry ) :
62 : SvXMLImportContext( rImport, nPrefix, rLocalName ),
63 69 : mrUnitConverter( rImport.GetMM100UnitConverter() ),
64 : mrxShape( rxShape ),
65 138 : mrCustomShapeGeometry( rCustomShapeGeometry )
66 : {
67 69 : }
68 :
69 : const SvXMLEnumMapEntry aXML_GluePointEnumMap[] =
70 : {
71 : { XML_NONE, 0 },
72 : { XML_SEGMENTS, 1 },
73 : { XML_NONE, 2 },
74 : { XML_RECTANGLE, 3 },
75 : { XML_TOKEN_INVALID, 0 }
76 : };
77 25 : void GetBool( std::vector< com::sun::star::beans::PropertyValue >& rDest,
78 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
79 : {
80 : bool bAttrBool;
81 25 : if (::sax::Converter::convertBool( bAttrBool, rValue ))
82 : {
83 25 : beans::PropertyValue aProp;
84 25 : aProp.Name = EASGet( eDestProp );
85 25 : aProp.Value <<= bAttrBool;
86 25 : rDest.push_back( aProp );
87 : }
88 25 : }
89 :
90 0 : void GetInt32( std::vector< com::sun::star::beans::PropertyValue >& rDest,
91 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
92 : {
93 : sal_Int32 nAttrNumber;
94 0 : if (::sax::Converter::convertNumber( nAttrNumber, rValue ))
95 : {
96 0 : beans::PropertyValue aProp;
97 0 : aProp.Name = EASGet( eDestProp );
98 0 : aProp.Value <<= nAttrNumber;
99 0 : rDest.push_back( aProp );
100 : }
101 0 : }
102 :
103 0 : void GetDouble( std::vector< com::sun::star::beans::PropertyValue >& rDest,
104 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
105 : {
106 : double fAttrDouble;
107 0 : if (::sax::Converter::convertDouble( fAttrDouble, rValue ))
108 : {
109 0 : beans::PropertyValue aProp;
110 0 : aProp.Name = EASGet( eDestProp );
111 0 : aProp.Value <<= fAttrDouble;
112 0 : rDest.push_back( aProp );
113 : }
114 0 : }
115 :
116 69 : void GetString( std::vector< com::sun::star::beans::PropertyValue >& rDest,
117 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
118 : {
119 69 : beans::PropertyValue aProp;
120 69 : aProp.Name = EASGet( eDestProp );
121 69 : aProp.Value <<= rValue;
122 69 : rDest.push_back( aProp );
123 69 : }
124 :
125 2 : void GetEnum( std::vector< com::sun::star::beans::PropertyValue >& rDest,
126 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp,
127 : const SvXMLEnumMapEntry& rMap )
128 : {
129 : sal_uInt16 eKind;
130 2 : if( SvXMLUnitConverter::convertEnum( eKind, rValue, &rMap ) )
131 : {
132 2 : sal_Int16 nEnum = (sal_Int16)eKind;
133 2 : beans::PropertyValue aProp;
134 2 : aProp.Name = EASGet( eDestProp );
135 2 : aProp.Value <<= nEnum;
136 2 : rDest.push_back( aProp );
137 : }
138 2 : }
139 :
140 0 : void GetDoublePercentage( std::vector< com::sun::star::beans::PropertyValue >& rDest,
141 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
142 : {
143 : sal_Int16 const eSrcUnit = ::sax::Converter::GetUnitFromString(
144 0 : rValue, util::MeasureUnit::MM_100TH);
145 0 : if (util::MeasureUnit::PERCENT == eSrcUnit)
146 : {
147 : rtl_math_ConversionStatus eStatus;
148 : double fAttrDouble = ::rtl::math::stringToDouble( rValue,
149 0 : '.', ',', &eStatus, NULL );
150 0 : if ( eStatus == rtl_math_ConversionStatus_Ok )
151 : {
152 0 : beans::PropertyValue aProp;
153 0 : aProp.Name = EASGet( eDestProp );
154 0 : aProp.Value <<= fAttrDouble;
155 0 : rDest.push_back( aProp );
156 : }
157 : }
158 0 : }
159 :
160 0 : void GetB3DVector( std::vector< com::sun::star::beans::PropertyValue >& rDest,
161 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
162 : {
163 0 : ::basegfx::B3DVector aB3DVector;
164 0 : if ( SvXMLUnitConverter::convertB3DVector( aB3DVector, rValue ) )
165 : {
166 0 : drawing::Direction3D aDirection3D( aB3DVector.getX(), aB3DVector.getY(), aB3DVector.getZ() );
167 0 : beans::PropertyValue aProp;
168 0 : aProp.Name = EASGet( eDestProp );
169 0 : aProp.Value <<= aDirection3D;
170 0 : rDest.push_back( aProp );
171 0 : }
172 0 : }
173 :
174 1568 : sal_Bool GetEquationName( const OUString& rEquation, const sal_Int32 nStart, OUString& rEquationName )
175 : {
176 1568 : sal_Int32 nIndex = nStart;
177 6665 : while( nIndex < rEquation.getLength() )
178 : {
179 5026 : sal_Unicode nChar = rEquation[ nIndex ];
180 5026 : if (
181 1568 : ( ( nChar >= 'a' ) && ( nChar <= 'z' ) )
182 3458 : || ( ( nChar >= 'A' ) && ( nChar <= 'Z' ) )
183 3458 : || ( ( nChar >= '0' ) && ( nChar <= '9' ) )
184 : )
185 : {
186 3529 : nIndex++;
187 : }
188 : else
189 : break;
190 : }
191 1568 : sal_Bool bValid = ( nIndex - nStart ) != 0;
192 1568 : if ( bValid )
193 1568 : rEquationName = rEquation.copy( nStart, nIndex - nStart );
194 1568 : return bValid;
195 : }
196 :
197 3824 : sal_Bool GetNextParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, sal_Int32& nIndex, const OUString& rParaString )
198 : {
199 3824 : if ( nIndex >= rParaString.getLength() )
200 139 : return sal_False;
201 :
202 3685 : sal_Bool bValid = sal_True;
203 3685 : sal_Bool bNumberRequired = sal_True;
204 3685 : sal_Bool bMustBePositiveWholeNumbered = sal_False;
205 :
206 3685 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL;
207 3685 : if ( rParaString[ nIndex ] == '$' )
208 : {
209 51 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT;
210 51 : bMustBePositiveWholeNumbered = sal_True;
211 51 : nIndex++;
212 : }
213 3634 : else if ( rParaString[ nIndex ] == '?' )
214 : {
215 1091 : nIndex++;
216 1091 : bNumberRequired = sal_False;
217 1091 : OUString aEquationName;
218 1091 : bValid = GetEquationName( rParaString, nIndex, aEquationName );
219 1091 : if ( bValid )
220 : {
221 1091 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION;
222 1091 : rParameter.Value <<= aEquationName;
223 1091 : nIndex += aEquationName.getLength();
224 1091 : }
225 : }
226 2543 : else if ( rParaString[ nIndex ] > '9' )
227 : {
228 26 : bNumberRequired = sal_False;
229 26 : if ( rParaString.matchIgnoreAsciiCaseAsciiL( "left", 4, nIndex ) )
230 : {
231 8 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT;
232 8 : nIndex += 4;
233 : }
234 18 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "top", 3, nIndex ) )
235 : {
236 14 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP;
237 14 : nIndex += 3;
238 : }
239 4 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "right", 5, nIndex ) )
240 : {
241 2 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT;
242 2 : nIndex += 5;
243 : }
244 2 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "bottom", 6, nIndex ) )
245 : {
246 2 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM;
247 2 : nIndex += 6;
248 : }
249 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "xstretch", 8, nIndex ) )
250 : {
251 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::XSTRETCH;
252 0 : nIndex += 8;
253 : }
254 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "ystretch", 8, nIndex ) )
255 : {
256 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::YSTRETCH;
257 0 : nIndex += 8;
258 : }
259 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "hasstroke", 9, nIndex ) )
260 : {
261 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HASSTROKE;
262 0 : nIndex += 9;
263 : }
264 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "hasfill", 7, nIndex ) )
265 : {
266 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HASFILL;
267 0 : nIndex += 7;
268 : }
269 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "width", 5, nIndex ) )
270 : {
271 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::WIDTH;
272 0 : nIndex += 5;
273 : }
274 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "height", 6, nIndex ) )
275 : {
276 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HEIGHT;
277 0 : nIndex += 6;
278 : }
279 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "logwidth", 8, nIndex ) )
280 : {
281 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGWIDTH;
282 0 : nIndex += 8;
283 : }
284 0 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "logheight", 9, nIndex ) )
285 : {
286 0 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT;
287 0 : nIndex += 9;
288 : }
289 : else
290 0 : bValid = sal_False;
291 : }
292 3685 : if ( bValid )
293 : {
294 3685 : if ( bNumberRequired )
295 : {
296 2568 : sal_Int32 nStartIndex = nIndex;
297 2568 : sal_Int32 nEIndex = 0; // index of "E" in double
298 :
299 2568 : sal_Bool bE = sal_False; // set if a double is including a "E" statement
300 2568 : sal_Bool bENum = sal_False; // there is at least one number after "E"
301 2568 : sal_Bool bDot = sal_False; // set if there is a dot included
302 2568 : sal_Bool bEnd = sal_False; // set for each value that can not be part of a double/integer
303 :
304 14478 : while( ( nIndex < rParaString.getLength() ) && bValid )
305 : {
306 11674 : switch( rParaString[ nIndex ] )
307 : {
308 : case '.' :
309 : {
310 1 : if ( bMustBePositiveWholeNumbered )
311 0 : bValid = sal_False;
312 : else
313 : {
314 1 : if ( bDot )
315 0 : bValid = sal_False;
316 : else
317 1 : bDot = sal_True;
318 : }
319 : }
320 1 : break;
321 : case '-' :
322 : {
323 13 : if ( bMustBePositiveWholeNumbered )
324 0 : bValid = sal_False;
325 : else
326 : {
327 13 : if ( nStartIndex == nIndex )
328 13 : bValid = sal_True;
329 0 : else if ( bE )
330 : {
331 0 : if ( nEIndex + 1 == nIndex )
332 0 : bValid = sal_True;
333 0 : else if ( bENum )
334 0 : bEnd = sal_True;
335 : else
336 0 : bValid = sal_False;
337 : }
338 : }
339 : }
340 13 : break;
341 :
342 : case 'e' :
343 : case 'E' :
344 : {
345 0 : if ( bMustBePositiveWholeNumbered )
346 0 : bEnd = sal_True;
347 : else
348 : {
349 0 : if ( !bE )
350 : {
351 0 : bE = sal_True;
352 0 : nEIndex = nIndex;
353 : }
354 : else
355 0 : bEnd = sal_True;
356 : }
357 : }
358 0 : break;
359 : case '0' :
360 : case '1' :
361 : case '2' :
362 : case '3' :
363 : case '4' :
364 : case '5' :
365 : case '6' :
366 : case '7' :
367 : case '8' :
368 : case '9' :
369 : {
370 9328 : if ( bE && ! bENum )
371 0 : bENum = sal_True;
372 : }
373 9328 : break;
374 : default:
375 2332 : bEnd = sal_True;
376 : }
377 11674 : if ( !bEnd )
378 9342 : nIndex++;
379 : else
380 2332 : break;
381 : }
382 2568 : if ( nIndex == nStartIndex )
383 0 : bValid = sal_False;
384 2568 : if ( bValid )
385 : {
386 2568 : OUString aNumber( rParaString.copy( nStartIndex, nIndex - nStartIndex ) );
387 2568 : if ( bE || bDot )
388 : {
389 : double fAttrDouble;
390 1 : if (::sax::Converter::convertDouble(fAttrDouble, aNumber))
391 1 : rParameter.Value <<= fAttrDouble;
392 : else
393 0 : bValid = sal_False;
394 : }
395 : else
396 : {
397 : sal_Int32 nValue;
398 2567 : if (::sax::Converter::convertNumber(nValue, aNumber))
399 2567 : rParameter.Value <<= nValue;
400 : else
401 0 : bValid = sal_False;
402 2568 : }
403 : }
404 : }
405 : }
406 3685 : if ( bValid )
407 : {
408 : // skipping white spaces and commas (#i121507#)
409 3685 : const sal_Unicode aSpace(' ');
410 3685 : const sal_Unicode aCommata(',');
411 :
412 10759 : while(nIndex < rParaString.getLength())
413 : {
414 6779 : const sal_Unicode aCandidate(rParaString[nIndex]);
415 :
416 6779 : if(aSpace == aCandidate || aCommata == aCandidate)
417 : {
418 3389 : nIndex++;
419 : }
420 : else
421 : {
422 : break;
423 : }
424 : }
425 : }
426 3685 : return bValid;
427 : }
428 :
429 1 : void GetPosition3D( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:extrusion-viewpoint
430 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp,
431 : SvXMLUnitConverter& rUnitConverter )
432 : {
433 1 : drawing::Position3D aPosition3D;
434 1 : if ( rUnitConverter.convertPosition3D( aPosition3D, rValue ) )
435 : {
436 1 : beans::PropertyValue aProp;
437 1 : aProp.Name = EASGet( eDestProp );
438 1 : aProp.Value <<= aPosition3D;
439 1 : rDest.push_back( aProp );
440 : }
441 1 : }
442 :
443 0 : void GetDoubleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-point-leaving-directions
444 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
445 : {
446 0 : std::vector< double > vDirection;
447 0 : sal_Int32 nIndex = 0;
448 0 : do
449 : {
450 : double fAttrDouble;
451 0 : OUString aToken( rValue.getToken( 0, ',', nIndex ) );
452 0 : if (!::sax::Converter::convertDouble( fAttrDouble, aToken ))
453 0 : break;
454 : else
455 0 : vDirection.push_back( fAttrDouble );
456 : }
457 0 : while ( nIndex >= 0 );
458 :
459 0 : if ( !vDirection.empty() )
460 : {
461 0 : uno::Sequence< double > aDirectionsSeq( vDirection.size() );
462 0 : std::vector< double >::const_iterator aIter = vDirection.begin();
463 0 : std::vector< double >::const_iterator aEnd = vDirection.end();
464 0 : double* pValues = aDirectionsSeq.getArray();
465 :
466 0 : while ( aIter != aEnd )
467 0 : *pValues++ = *aIter++;
468 :
469 0 : beans::PropertyValue aProp;
470 0 : aProp.Name = EASGet( eDestProp );
471 0 : aProp.Value <<= aDirectionsSeq;
472 0 : rDest.push_back( aProp );
473 0 : }
474 0 : }
475 :
476 0 : void GetSizeSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest,
477 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
478 : {
479 0 : std::vector< sal_Int32 > vNum;
480 0 : sal_Int32 nIndex = 0;
481 0 : do
482 : {
483 : sal_Int32 n;
484 0 : OUString aToken( rValue.getToken( 0, ' ', nIndex ) );
485 0 : if (!::sax::Converter::convertNumber( n, aToken ))
486 0 : break;
487 : else
488 0 : vNum.push_back( n );
489 : }
490 0 : while ( nIndex >= 0 );
491 :
492 0 : if ( !vNum.empty() )
493 : {
494 0 : uno::Sequence< awt::Size > aSizeSeq( vNum.size() / 2 );
495 0 : std::vector< sal_Int32 >::const_iterator aIter = vNum.begin();
496 0 : std::vector< sal_Int32 >::const_iterator aEnd = vNum.end();
497 0 : awt::Size* pValues = aSizeSeq.getArray();
498 :
499 0 : while ( aIter != aEnd ) {
500 0 : pValues->Width = *aIter++;
501 0 : if ( aIter != aEnd )
502 0 : pValues->Height = *aIter++;
503 0 : pValues ++;
504 : }
505 :
506 0 : beans::PropertyValue aProp;
507 0 : aProp.Name = EASGet( eDestProp );
508 0 : aProp.Value <<= aSizeSeq;
509 0 : rDest.push_back( aProp );
510 0 : }
511 0 : }
512 :
513 100 : void GetEnhancedParameter( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position
514 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
515 : {
516 100 : sal_Int32 nIndex = 0;
517 100 : com::sun::star::drawing::EnhancedCustomShapeParameter aParameter;
518 100 : if ( GetNextParameter( aParameter, nIndex, rValue ) )
519 : {
520 100 : beans::PropertyValue aProp;
521 100 : aProp.Name = EASGet( eDestProp );
522 100 : aProp.Value <<= aParameter;
523 100 : rDest.push_back( aProp );
524 100 : }
525 100 : }
526 :
527 54 : void GetEnhancedParameterPair( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position
528 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
529 : {
530 54 : sal_Int32 nIndex = 0;
531 54 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair;
532 108 : if ( GetNextParameter( aParameterPair.First, nIndex, rValue )
533 54 : && GetNextParameter( aParameterPair.Second, nIndex, rValue ) )
534 : {
535 54 : beans::PropertyValue aProp;
536 54 : aProp.Name = EASGet( eDestProp );
537 54 : aProp.Value <<= aParameterPair;
538 54 : rDest.push_back( aProp );
539 54 : }
540 54 : }
541 :
542 35 : sal_Int32 GetEnhancedParameterPairSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-points
543 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
544 : {
545 35 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vParameter;
546 70 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameter;
547 :
548 35 : sal_Int32 nIndex = 0;
549 475 : while ( GetNextParameter( aParameter.First, nIndex, rValue )
550 220 : && GetNextParameter( aParameter.Second, nIndex, rValue ) )
551 : {
552 185 : vParameter.push_back( aParameter );
553 : }
554 35 : if ( !vParameter.empty() )
555 : {
556 35 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aParameterSeq( vParameter.size() );
557 35 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aIter = vParameter.begin();
558 35 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aEnd = vParameter.end();
559 35 : com::sun::star::drawing::EnhancedCustomShapeParameterPair* pValues = aParameterSeq.getArray();
560 :
561 255 : while ( aIter != aEnd )
562 185 : *pValues++ = *aIter++;
563 :
564 70 : beans::PropertyValue aProp;
565 35 : aProp.Name = EASGet( eDestProp );
566 35 : aProp.Value <<= aParameterSeq;
567 70 : rDest.push_back( aProp );
568 : }
569 70 : return vParameter.size();
570 : }
571 :
572 58 : void GetEnhancedRectangleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:text-areas
573 : const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
574 : {
575 58 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame > vTextFrame;
576 116 : com::sun::star::drawing::EnhancedCustomShapeTextFrame aParameter;
577 :
578 58 : sal_Int32 nIndex = 0;
579 :
580 292 : while ( GetNextParameter( aParameter.TopLeft.First, nIndex, rValue )
581 59 : && GetNextParameter( aParameter.TopLeft.Second, nIndex, rValue )
582 59 : && GetNextParameter( aParameter.BottomRight.First, nIndex, rValue )
583 176 : && GetNextParameter( aParameter.BottomRight.Second, nIndex, rValue ) )
584 : {
585 59 : vTextFrame.push_back( aParameter );
586 : }
587 58 : if ( !vTextFrame.empty() )
588 : {
589 58 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrameSeq( vTextFrame.size() );
590 58 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aIter = vTextFrame.begin();
591 58 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aEnd = vTextFrame.end();
592 58 : com::sun::star::drawing::EnhancedCustomShapeTextFrame* pValues = aTextFrameSeq.getArray();
593 :
594 175 : while ( aIter != aEnd )
595 59 : *pValues++ = *aIter++;
596 :
597 116 : beans::PropertyValue aProp;
598 58 : aProp.Name = EASGet( eDestProp );
599 58 : aProp.Value <<= aTextFrameSeq;
600 116 : rDest.push_back( aProp );
601 58 : }
602 58 : }
603 :
604 69 : void GetEnhancedPath( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:enhanced-path
605 : const OUString& rValue )
606 : {
607 69 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vCoordinates;
608 138 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment > vSegments;
609 :
610 69 : sal_Int32 nIndex = 0;
611 69 : sal_Int32 nParameterCount = 0;
612 :
613 69 : sal_Int32 nParametersNeeded = 1;
614 69 : sal_Int16 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
615 :
616 69 : sal_Bool bValid = sal_True;
617 :
618 2877 : while( bValid && ( nIndex < rValue.getLength() ) )
619 : {
620 2739 : switch( rValue[ nIndex ] )
621 : {
622 : case 'M' :
623 : {
624 147 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
625 147 : nParametersNeeded = 1;
626 147 : nIndex++;
627 : }
628 147 : break;
629 : case 'L' :
630 : {
631 131 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
632 131 : nParametersNeeded = 1;
633 131 : nIndex++;
634 : }
635 131 : break;
636 : case 'C' :
637 : {
638 54 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
639 54 : nParametersNeeded = 3;
640 54 : nIndex++;
641 : }
642 54 : break;
643 : case 'Z' :
644 : {
645 134 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
646 134 : nParametersNeeded = 0;
647 134 : nIndex++;
648 : }
649 134 : break;
650 : case 'N' :
651 : {
652 149 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
653 149 : nParametersNeeded = 0;
654 149 : nIndex++;
655 : }
656 149 : break;
657 : case 'F' :
658 : {
659 14 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL;
660 14 : nParametersNeeded = 0;
661 14 : nIndex++;
662 : }
663 14 : break;
664 : case 'S' :
665 : {
666 4 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE;
667 4 : nParametersNeeded = 0;
668 4 : nIndex++;
669 : }
670 4 : break;
671 : case 'T' :
672 : {
673 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
674 0 : nParametersNeeded = 3;
675 0 : nIndex++;
676 : }
677 0 : break;
678 : case 'U' :
679 : {
680 16 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
681 16 : nParametersNeeded = 3;
682 16 : nIndex++;
683 : }
684 16 : break;
685 : case 'A' :
686 : {
687 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
688 0 : nParametersNeeded = 4;
689 0 : nIndex++;
690 : }
691 0 : break;
692 : case 'B' :
693 : {
694 3 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC;
695 3 : nParametersNeeded = 4;
696 3 : nIndex++;
697 : }
698 3 : break;
699 : case 'G' :
700 : {
701 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO;
702 0 : nParametersNeeded = 2;
703 0 : nIndex++;
704 : }
705 0 : break;
706 : case 'H' :
707 : {
708 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::DARKEN;
709 0 : nParametersNeeded = 0;
710 0 : nIndex++;
711 : }
712 0 : break;
713 : case 'I' :
714 : {
715 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS;
716 0 : nParametersNeeded = 0;
717 0 : nIndex++;
718 : }
719 0 : break;
720 : case 'J' :
721 : {
722 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN;
723 0 : nParametersNeeded = 0;
724 0 : nIndex++;
725 : }
726 0 : break;
727 : case 'K' :
728 : {
729 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
730 0 : nParametersNeeded = 0;
731 0 : nIndex++;
732 : }
733 0 : break;
734 : case 'W' :
735 : {
736 1 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
737 1 : nParametersNeeded = 4;
738 1 : nIndex++;
739 : }
740 1 : break;
741 : case 'V' :
742 : {
743 1 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
744 1 : nParametersNeeded = 4;
745 1 : nIndex++;
746 : }
747 1 : break;
748 : case 'X' :
749 : {
750 21 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
751 21 : nParametersNeeded = 1;
752 21 : nIndex++;
753 : }
754 21 : break;
755 : case 'Y' :
756 : {
757 24 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
758 24 : nParametersNeeded = 1;
759 24 : nIndex++;
760 : }
761 24 : break;
762 : case 'Q' :
763 : {
764 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
765 0 : nParametersNeeded = 2;
766 0 : nIndex++;
767 : }
768 0 : break;
769 : case ' ' :
770 : {
771 631 : nIndex++;
772 : }
773 631 : break;
774 :
775 : case '$' :
776 : case '?' :
777 : case '0' :
778 : case '1' :
779 : case '2' :
780 : case '3' :
781 : case '4' :
782 : case '5' :
783 : case '6' :
784 : case '7' :
785 : case '8' :
786 : case '9' :
787 : case '.' :
788 : case '-' :
789 : {
790 1409 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aPair;
791 2818 : if ( GetNextParameter( aPair.First, nIndex, rValue ) &&
792 1409 : GetNextParameter( aPair.Second, nIndex, rValue ) )
793 : {
794 1409 : vCoordinates.push_back( aPair );
795 1409 : nParameterCount++;
796 : }
797 : else
798 0 : bValid = sal_False;
799 : }
800 1409 : break;
801 : default:
802 0 : nIndex++;
803 0 : break;
804 : }
805 2739 : if ( !nParameterCount && !nParametersNeeded )
806 : {
807 301 : com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
808 301 : aSegment.Command = nLatestSegmentCommand;
809 301 : aSegment.Count = 0;
810 301 : vSegments.push_back( aSegment );
811 301 : nParametersNeeded = 0x7fffffff;
812 : }
813 2438 : else if ( nParameterCount >= nParametersNeeded )
814 : {
815 : // check if the last command is identical,
816 : // if so, we just need to increment the count
817 926 : if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) )
818 528 : vSegments[ vSegments.size() -1 ].Count++;
819 : else
820 : {
821 398 : com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
822 398 : aSegment.Command = nLatestSegmentCommand;
823 398 : aSegment.Count = 1;
824 398 : vSegments.push_back( aSegment );
825 : }
826 926 : nParameterCount = 0;
827 : }
828 : }
829 : // adding the Coordinates property
830 69 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > seqCoordinates( vCoordinates.size() );
831 69 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesIter = vCoordinates.begin();
832 69 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesEnd = vCoordinates.end();
833 69 : com::sun::star::drawing::EnhancedCustomShapeParameterPair* pCoordinateValues = seqCoordinates.getArray();
834 :
835 1547 : while ( aCoordinatesIter != aCoordinatesEnd )
836 1409 : *pCoordinateValues++ = *aCoordinatesIter++;
837 :
838 138 : beans::PropertyValue aProp;
839 69 : aProp.Name = EASGet( EAS_Coordinates );
840 69 : aProp.Value <<= seqCoordinates;
841 69 : rDest.push_back( aProp );
842 :
843 :
844 : // adding the Segments property
845 138 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments( vSegments.size() );
846 69 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsIter = vSegments.begin();
847 69 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsEnd = vSegments.end();
848 69 : com::sun::star::drawing::EnhancedCustomShapeSegment* pSegmentValues = seqSegments.getArray();
849 :
850 837 : while ( aSegmentsIter != aSegmentsEnd )
851 699 : *pSegmentValues++ = *aSegmentsIter++;
852 :
853 69 : aProp.Name = EASGet( EAS_Segments );
854 69 : aProp.Value <<= seqSegments;
855 207 : rDest.push_back( aProp );
856 69 : }
857 :
858 46 : void GetAdjustmentValues( std::vector< com::sun::star::beans::PropertyValue >& rDest, // draw:adjustments
859 : const OUString& rValue )
860 : {
861 46 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > vAdjustmentValue;
862 92 : com::sun::star::drawing::EnhancedCustomShapeParameter aParameter;
863 46 : sal_Int32 nIndex = 0;
864 143 : while ( GetNextParameter( aParameter, nIndex, rValue ) )
865 : {
866 51 : com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue aAdj;
867 51 : if ( aParameter.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL )
868 : {
869 51 : aAdj.Value <<= aParameter.Value;
870 51 : aAdj.State = beans::PropertyState_DIRECT_VALUE;
871 : }
872 : else
873 0 : aAdj.State = beans::PropertyState_DEFAULT_VALUE; // this should not be, but better than setting nothing
874 :
875 51 : vAdjustmentValue.push_back( aAdj );
876 51 : }
877 :
878 46 : sal_Int32 nAdjustmentValues = vAdjustmentValue.size();
879 46 : if ( nAdjustmentValues )
880 : {
881 46 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( nAdjustmentValues );
882 46 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aIter = vAdjustmentValue.begin();
883 46 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aEnd = vAdjustmentValue.end();
884 46 : com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue* pValues = aAdjustmentValues.getArray();
885 :
886 143 : while ( aIter != aEnd )
887 51 : *pValues++ = *aIter++;
888 :
889 92 : beans::PropertyValue aProp;
890 46 : aProp.Name = EASGet( EAS_AdjustmentValues );
891 46 : aProp.Value <<= aAdjustmentValues;
892 92 : rDest.push_back( aProp );
893 46 : }
894 46 : }
895 :
896 69 : void XMLEnhancedCustomShapeContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
897 : {
898 69 : sal_Int16 nLength = xAttrList->getLength();
899 69 : if ( nLength )
900 : {
901 : sal_Int32 nAttrNumber;
902 468 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
903 : {
904 399 : OUString aLocalName;
905 798 : const OUString& rValue = xAttrList->getValueByIndex( nAttr );
906 399 : /* sven fixme, this must be checked! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
907 :
908 399 : switch( EASGet( aLocalName ) )
909 : {
910 : case EAS_type :
911 69 : GetString( mrCustomShapeGeometry, rValue, EAS_Type );
912 69 : break;
913 : case EAS_mirror_horizontal :
914 6 : GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredX );
915 6 : break;
916 : case EAS_mirror_vertical :
917 5 : GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredY );
918 5 : break;
919 : case EAS_viewBox :
920 : {
921 68 : SdXMLImExViewBox aViewBox( rValue, GetImport().GetMM100UnitConverter() );
922 : awt::Rectangle aRect(
923 68 : basegfx::fround(aViewBox.GetX()),
924 68 : basegfx::fround(aViewBox.GetY()),
925 68 : basegfx::fround(aViewBox.GetWidth()),
926 272 : basegfx::fround(aViewBox.GetHeight()));
927 :
928 68 : if(0 == aRect.Width && 0 == aRect.Height)
929 : {
930 : // #i124452# If in svg:viewBox no width and height is given the objects should normally
931 : // not be visible at all, but in this case it is a bug in LO to write empty svg:viewBox
932 : // entries for CustomShapes. To allow for a better ODF user experience, just correct this
933 : // here by getting the real object scale from the already set transformation from the xShape.
934 : // Hopefully LO will fix that bug (but this will still leave the files with the error), but
935 : // even when not this will do no harm as long noone uses this state explicitely for some
936 : // purpose (e.g. to really have CustomShapes without content, but unlikely).
937 2 : uno::Reference< beans::XPropertySet > xProps(mrxShape, uno::UNO_QUERY_THROW);
938 4 : uno::Any aObjectTransform = xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")));
939 2 : drawing::HomogenMatrix3 aTransformMatrix;
940 2 : aObjectTransform >>= aTransformMatrix;
941 4 : basegfx::B2DHomMatrix aMatrix;
942 :
943 2 : aMatrix.set(0, 0, aTransformMatrix.Line1.Column1);
944 2 : aMatrix.set(0, 1, aTransformMatrix.Line1.Column2);
945 2 : aMatrix.set(0, 2, aTransformMatrix.Line1.Column3);
946 2 : aMatrix.set(1, 0, aTransformMatrix.Line2.Column1);
947 2 : aMatrix.set(1, 1, aTransformMatrix.Line2.Column2);
948 2 : aMatrix.set(1, 2, aTransformMatrix.Line2.Column3);
949 2 : aMatrix.set(2, 0, aTransformMatrix.Line3.Column1);
950 2 : aMatrix.set(2, 1, aTransformMatrix.Line3.Column2);
951 2 : aMatrix.set(2, 2, aTransformMatrix.Line3.Column3);
952 :
953 4 : basegfx::B2DVector aScale, aTranslate;
954 : double fRotate, fShearX;
955 :
956 2 : aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
957 :
958 2 : aRect.Width = basegfx::fround(fabs(aScale.getX()));
959 4 : aRect.Height = basegfx::fround(fabs(aScale.getY()));
960 : }
961 :
962 136 : beans::PropertyValue aProp;
963 68 : aProp.Name = EASGet( EAS_ViewBox );
964 68 : aProp.Value <<= aRect;
965 136 : mrCustomShapeGeometry.push_back( aProp );
966 : }
967 68 : break;
968 : case EAS_sub_view_size:
969 0 : GetSizeSequence( maPath, rValue, EAS_SubViewSize );
970 0 : break;
971 : case EAS_text_rotate_angle :
972 0 : GetDouble( mrCustomShapeGeometry, rValue, EAS_TextRotateAngle );
973 0 : break;
974 : case EAS_extrusion_allowed :
975 0 : GetBool( maPath, rValue, EAS_ExtrusionAllowed );
976 0 : break;
977 : case EAS_text_path_allowed :
978 0 : GetBool( maPath, rValue, EAS_TextPathAllowed );
979 0 : break;
980 : case EAS_concentric_gradient_fill_allowed :
981 0 : GetBool( maPath, rValue, EAS_ConcentricGradientFillAllowed );
982 0 : break;
983 : case EAS_extrusion :
984 0 : GetBool( maExtrusion, rValue, EAS_Extrusion );
985 0 : break;
986 : case EAS_extrusion_brightness :
987 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Brightness );
988 0 : break;
989 : case EAS_extrusion_depth :
990 : {
991 1 : sal_Int32 nIndex = 0;
992 1 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair;
993 1 : com::sun::star::drawing::EnhancedCustomShapeParameter& rDepth = aParameterPair.First;
994 1 : com::sun::star::drawing::EnhancedCustomShapeParameter& rFraction = aParameterPair.Second;
995 1 : if ( GetNextParameter( rDepth, nIndex, rValue ) )
996 : {
997 : // try to catch the unit for the depth
998 : sal_Int16 const eSrcUnit(
999 : ::sax::Converter::GetUnitFromString(
1000 1 : rValue, util::MeasureUnit::MM_100TH));
1001 :
1002 1 : OUStringBuffer aUnitStr;
1003 : double fFactor = ::sax::Converter::GetConversionFactor(
1004 1 : aUnitStr, util::MeasureUnit::MM_100TH, eSrcUnit);
1005 1 : if ( ( fFactor != 1.0 ) && ( fFactor != 0.0 ) )
1006 : {
1007 1 : double fDepth(0.0);
1008 1 : if ( rDepth.Value >>= fDepth )
1009 : {
1010 1 : fDepth /= fFactor;
1011 1 : rDepth.Value <<= fDepth;
1012 : }
1013 : }
1014 1 : if ( rValue.matchIgnoreAsciiCase( aUnitStr.toString(), nIndex ) )
1015 1 : nIndex += aUnitStr.getLength();
1016 :
1017 : // skipping white spaces
1018 3 : while( ( nIndex < rValue.getLength() ) && rValue[ nIndex ] == ' ' )
1019 1 : nIndex++;
1020 :
1021 1 : if ( GetNextParameter( rFraction, nIndex, rValue ) )
1022 : {
1023 1 : beans::PropertyValue aProp;
1024 1 : aProp.Name = EASGet( EAS_Depth );
1025 1 : aProp.Value <<= aParameterPair;
1026 1 : maExtrusion.push_back( aProp );
1027 1 : }
1028 1 : }
1029 : }
1030 1 : break;
1031 : case EAS_extrusion_diffusion :
1032 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Diffusion );
1033 0 : break;
1034 : case EAS_extrusion_number_of_line_segments :
1035 0 : GetInt32( maExtrusion, rValue, EAS_NumberOfLineSegments );
1036 0 : break;
1037 : case EAS_extrusion_light_face :
1038 0 : GetBool( maExtrusion, rValue, EAS_LightFace );
1039 0 : break;
1040 : case EAS_extrusion_first_light_harsh :
1041 0 : GetBool( maExtrusion, rValue, EAS_FirstLightHarsh );
1042 0 : break;
1043 : case EAS_extrusion_second_light_harsh :
1044 0 : GetBool( maExtrusion, rValue, EAS_SecondLightHarsh );
1045 0 : break;
1046 : case EAS_extrusion_first_light_level :
1047 0 : GetDoublePercentage( maExtrusion, rValue, EAS_FirstLightLevel );
1048 0 : break;
1049 : case EAS_extrusion_second_light_level :
1050 0 : GetDoublePercentage( maExtrusion, rValue, EAS_SecondLightLevel );
1051 0 : break;
1052 : case EAS_extrusion_first_light_direction :
1053 0 : GetB3DVector( maExtrusion, rValue, EAS_FirstLightDirection );
1054 0 : break;
1055 : case EAS_extrusion_second_light_direction :
1056 0 : GetB3DVector( maExtrusion, rValue, EAS_SecondLightDirection );
1057 0 : break;
1058 : case EAS_extrusion_metal :
1059 0 : GetBool( maExtrusion, rValue, EAS_Metal );
1060 0 : break;
1061 : case EAS_shade_mode :
1062 : {
1063 0 : drawing::ShadeMode eShadeMode( drawing::ShadeMode_FLAT );
1064 0 : if( IsXMLToken( rValue, XML_PHONG ) )
1065 0 : eShadeMode = drawing::ShadeMode_PHONG;
1066 0 : else if ( IsXMLToken( rValue, XML_GOURAUD ) )
1067 0 : eShadeMode = drawing::ShadeMode_SMOOTH;
1068 0 : else if ( IsXMLToken( rValue, XML_DRAFT ) )
1069 0 : eShadeMode = drawing::ShadeMode_DRAFT;
1070 :
1071 0 : beans::PropertyValue aProp;
1072 0 : aProp.Name = EASGet( EAS_ShadeMode );
1073 0 : aProp.Value <<= eShadeMode;
1074 0 : maExtrusion.push_back( aProp );
1075 : }
1076 0 : break;
1077 : case EAS_extrusion_rotation_angle :
1078 0 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_RotateAngle );
1079 0 : break;
1080 : case EAS_extrusion_rotation_center :
1081 0 : GetB3DVector( maExtrusion, rValue, EAS_RotationCenter );
1082 0 : break;
1083 : case EAS_extrusion_shininess :
1084 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Shininess );
1085 0 : break;
1086 : case EAS_extrusion_skew :
1087 1 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_Skew );
1088 1 : break;
1089 : case EAS_extrusion_specularity :
1090 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Specularity );
1091 0 : break;
1092 : case EAS_projection :
1093 : {
1094 1 : drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PERSPECTIVE );
1095 1 : if( IsXMLToken( rValue, XML_PARALLEL ) )
1096 0 : eProjectionMode = drawing::ProjectionMode_PARALLEL;
1097 :
1098 1 : beans::PropertyValue aProp;
1099 1 : aProp.Name = EASGet( EAS_ProjectionMode );
1100 1 : aProp.Value <<= eProjectionMode;
1101 1 : maExtrusion.push_back( aProp );
1102 : }
1103 1 : break;
1104 : case EAS_extrusion_viewpoint :
1105 1 : GetPosition3D( maExtrusion, rValue, EAS_ViewPoint, mrUnitConverter );
1106 1 : break;
1107 : case EAS_extrusion_origin :
1108 1 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_Origin );
1109 1 : break;
1110 : case EAS_extrusion_color :
1111 0 : GetBool( maExtrusion, rValue, EAS_Color );
1112 0 : break;
1113 : case EAS_enhanced_path :
1114 69 : GetEnhancedPath( maPath, rValue );
1115 69 : break;
1116 : case EAS_path_stretchpoint_x :
1117 : {
1118 19 : if (::sax::Converter::convertNumber(nAttrNumber, rValue))
1119 : {
1120 19 : beans::PropertyValue aProp;
1121 19 : aProp.Name = EASGet( EAS_StretchX );
1122 19 : aProp.Value <<= nAttrNumber;
1123 19 : maPath.push_back( aProp );
1124 : }
1125 : }
1126 19 : break;
1127 : case EAS_path_stretchpoint_y :
1128 : {
1129 17 : if (::sax::Converter::convertNumber(nAttrNumber, rValue))
1130 : {
1131 17 : beans::PropertyValue aProp;
1132 17 : aProp.Name = EASGet( EAS_StretchY );
1133 17 : aProp.Value <<= nAttrNumber;
1134 17 : maPath.push_back( aProp );
1135 : }
1136 : }
1137 17 : break;
1138 : case EAS_text_areas :
1139 58 : GetEnhancedRectangleSequence( maPath, rValue, EAS_TextFrames );
1140 58 : break;
1141 : case EAS_glue_points :
1142 : {
1143 35 : sal_Int32 i, nPairs = GetEnhancedParameterPairSequence( maPath, rValue, EAS_GluePoints );
1144 35 : GetImport().GetShapeImport()->moveGluePointMapping( mrxShape, nPairs );
1145 220 : for ( i = 0; i < nPairs; i++ )
1146 185 : GetImport().GetShapeImport()->addGluePointMapping( mrxShape, i + 4, i + 4 );
1147 : }
1148 35 : break;
1149 : case EAS_glue_point_type :
1150 2 : GetEnum( maPath, rValue, EAS_GluePointType, *aXML_GluePointEnumMap );
1151 2 : break;
1152 : case EAS_glue_point_leaving_directions :
1153 0 : GetDoubleSequence( maPath, rValue, EAS_GluePointLeavingDirections );
1154 0 : break;
1155 : case EAS_text_path :
1156 0 : GetBool( maTextPath, rValue, EAS_TextPath );
1157 0 : break;
1158 : case EAS_text_path_mode :
1159 : {
1160 0 : com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode( com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL );
1161 0 : if( IsXMLToken( rValue, XML_PATH ) )
1162 0 : eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH;
1163 0 : else if ( IsXMLToken( rValue, XML_SHAPE ) )
1164 0 : eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE;
1165 :
1166 0 : beans::PropertyValue aProp;
1167 0 : aProp.Name = EASGet( EAS_TextPathMode );
1168 0 : aProp.Value <<= eTextPathMode;
1169 0 : maTextPath.push_back( aProp );
1170 : }
1171 0 : break;
1172 : case EAS_text_path_scale :
1173 : {
1174 0 : sal_Bool bScaleX = IsXMLToken( rValue, XML_SHAPE );
1175 0 : beans::PropertyValue aProp;
1176 0 : aProp.Name = EASGet( EAS_ScaleX );
1177 0 : aProp.Value <<= bScaleX;
1178 0 : maTextPath.push_back( aProp );
1179 : }
1180 0 : break;
1181 : case EAS_text_path_same_letter_heights :
1182 0 : GetBool( maTextPath, rValue, EAS_SameLetterHeights );
1183 0 : break;
1184 : case EAS_modifiers :
1185 46 : GetAdjustmentValues( mrCustomShapeGeometry, rValue );
1186 46 : break;
1187 : default:
1188 0 : break;
1189 : }
1190 399 : }
1191 : }
1192 69 : }
1193 :
1194 46 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1195 : const std::vector< beans::PropertyValues >& rElement,
1196 : const OUString& rElementName )
1197 : {
1198 46 : if ( !rElement.empty() )
1199 : {
1200 46 : uno::Sequence< beans::PropertyValues > aPropSeq( rElement.size() );
1201 46 : std::vector< beans::PropertyValues >::const_iterator aIter = rElement.begin();
1202 46 : std::vector< beans::PropertyValues >::const_iterator aEnd = rElement.end();
1203 46 : beans::PropertyValues* pValues = aPropSeq.getArray();
1204 :
1205 141 : while ( aIter != aEnd )
1206 49 : *pValues++ = *aIter++;
1207 :
1208 92 : beans::PropertyValue aProp;
1209 46 : aProp.Name = rElementName;
1210 46 : aProp.Value <<= aPropSeq;
1211 92 : rPropVec.push_back( aProp );
1212 : }
1213 46 : }
1214 :
1215 69 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1216 : const std::vector< OUString >& rElement,
1217 : const OUString& rElementName )
1218 : {
1219 69 : if ( !rElement.empty() )
1220 : {
1221 49 : uno::Sequence< OUString > aPropSeq( rElement.size() );
1222 49 : std::vector< OUString >::const_iterator aIter = rElement.begin();
1223 49 : std::vector< OUString >::const_iterator aEnd = rElement.end();
1224 49 : OUString* pValues = aPropSeq.getArray();
1225 :
1226 791 : while ( aIter != aEnd )
1227 693 : *pValues++ = *aIter++;
1228 :
1229 98 : beans::PropertyValue aProp;
1230 49 : aProp.Name = rElementName;
1231 49 : aProp.Value <<= aPropSeq;
1232 98 : rPropVec.push_back( aProp );
1233 : }
1234 69 : }
1235 :
1236 207 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1237 : const std::vector< com::sun::star::beans::PropertyValue >& rElement,
1238 : const OUString& rElementName )
1239 : {
1240 207 : if ( !rElement.empty() )
1241 : {
1242 70 : uno::Sequence< beans::PropertyValue > aPropSeq( rElement.size() );
1243 70 : std::vector< beans::PropertyValue >::const_iterator aIter = rElement.begin();
1244 70 : std::vector< beans::PropertyValue >::const_iterator aEnd = rElement.end();
1245 70 : beans::PropertyValue* pValues = aPropSeq.getArray();
1246 :
1247 414 : while ( aIter != aEnd )
1248 274 : *pValues++ = *aIter++;
1249 :
1250 140 : beans::PropertyValue aProp;
1251 70 : aProp.Name = rElementName;
1252 70 : aProp.Value <<= aPropSeq;
1253 140 : rPropVec.push_back( aProp );
1254 : }
1255 207 : }
1256 :
1257 : typedef boost::unordered_map< OUString, sal_Int32, OUStringHash, OUStringEqFunc> EquationHashMap;
1258 :
1259 : /* if rPara.Type is from type EnhancedCustomShapeParameterType::EQUATION, the name of the equation
1260 : will be converted from OUString to index */
1261 2132 : void CheckAndResolveEquationParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rPara, EquationHashMap* pH )
1262 : {
1263 2132 : if ( rPara.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION )
1264 : {
1265 1091 : OUString aEquationName;
1266 1091 : if ( rPara.Value >>= aEquationName )
1267 : {
1268 1091 : sal_Int32 nIndex = 0;
1269 1091 : EquationHashMap::iterator aHashIter( pH->find( aEquationName ) );
1270 1091 : if ( aHashIter != pH->end() )
1271 1091 : nIndex = (*aHashIter).second;
1272 1091 : rPara.Value <<= nIndex;
1273 1091 : }
1274 : }
1275 2132 : }
1276 :
1277 69 : void XMLEnhancedCustomShapeContext::EndElement()
1278 : {
1279 : // resolve properties that are indexing a Equation
1280 69 : if ( !maEquations.empty() )
1281 : {
1282 : // creating hash map containing the name and index of each equation
1283 49 : EquationHashMap* pH = new EquationHashMap;
1284 49 : std::vector< OUString >::iterator aEquationNameIter = maEquationNames.begin();
1285 49 : std::vector< OUString >::iterator aEquationNameEnd = maEquationNames.end();
1286 791 : while( aEquationNameIter != aEquationNameEnd )
1287 : {
1288 693 : (*pH)[ *aEquationNameIter ] = (sal_Int32)( aEquationNameIter - maEquationNames.begin() );
1289 693 : ++aEquationNameIter;
1290 : }
1291 :
1292 : // resolve equation
1293 49 : std::vector< OUString >::iterator aEquationIter = maEquations.begin();
1294 49 : std::vector< OUString >::iterator aEquationEnd = maEquations.end();
1295 791 : while( aEquationIter != aEquationEnd )
1296 : {
1297 693 : sal_Int32 nIndexOf = 0;
1298 1170 : do
1299 : {
1300 1170 : nIndexOf = aEquationIter->indexOf( '?', nIndexOf );
1301 1170 : if ( nIndexOf != -1 )
1302 : {
1303 477 : OUString aEquationName;
1304 477 : if ( GetEquationName( *aEquationIter, nIndexOf + 1, aEquationName ) )
1305 : {
1306 : // copying first characters inclusive '?'
1307 477 : OUString aNew( aEquationIter->copy( 0, nIndexOf + 1 ) );
1308 477 : sal_Int32 nIndex = 0;
1309 477 : EquationHashMap::iterator aHashIter( pH->find( aEquationName ) );
1310 477 : if ( aHashIter != pH->end() )
1311 477 : nIndex = (*aHashIter).second;
1312 477 : aNew += OUString::number( nIndex );
1313 477 : aNew += aEquationIter->copy( nIndexOf + aEquationName.getLength() + 1 );
1314 477 : *aEquationIter = aNew;
1315 : }
1316 477 : nIndexOf++;
1317 : }
1318 : }
1319 : while( nIndexOf != -1 );
1320 693 : ++aEquationIter;
1321 : }
1322 :
1323 : // Path
1324 : sal_Int32 i;
1325 49 : std::vector< beans::PropertyValue >::iterator aPathIter = maPath.begin();
1326 49 : std::vector< beans::PropertyValue >::iterator aPathEnd = maPath.end();
1327 309 : while ( aPathIter != aPathEnd )
1328 : {
1329 211 : switch( EASGet( aPathIter->Name ) )
1330 : {
1331 : case EAS_Coordinates :
1332 : case EAS_GluePoints :
1333 : {
1334 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rSeq =
1335 : *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >*)
1336 77 : aPathIter->Value.getValue());
1337 945 : for ( i = 0; i < rSeq.getLength(); i++ )
1338 : {
1339 868 : CheckAndResolveEquationParameter( rSeq[ i ].First, pH );
1340 868 : CheckAndResolveEquationParameter( rSeq[ i ].Second, pH );
1341 : }
1342 : }
1343 77 : break;
1344 : case EAS_TextFrames :
1345 : {
1346 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >& rSeq =
1347 : *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >*)
1348 47 : aPathIter->Value.getValue());
1349 95 : for ( i = 0; i < rSeq.getLength(); i++ )
1350 : {
1351 48 : CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.First, pH );
1352 48 : CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.Second, pH );
1353 48 : CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.First, pH );
1354 48 : CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.Second, pH );
1355 : }
1356 : }
1357 47 : break;
1358 : default:
1359 87 : break;
1360 : }
1361 211 : ++aPathIter;
1362 : }
1363 49 : std::vector< beans::PropertyValues >::iterator aHandleIter = maHandles.begin();
1364 49 : std::vector< beans::PropertyValues >::iterator aHandleEnd = maHandles.end();
1365 147 : while ( aHandleIter != aHandleEnd )
1366 : {
1367 49 : beans::PropertyValue* pValues = aHandleIter->getArray();
1368 215 : for ( i = 0; i < aHandleIter->getLength(); i++ )
1369 : {
1370 166 : switch( EASGet( pValues->Name ) )
1371 : {
1372 : case EAS_RangeYMinimum :
1373 : case EAS_RangeYMaximum :
1374 : case EAS_RangeXMinimum :
1375 : case EAS_RangeXMaximum :
1376 : case EAS_RadiusRangeMinimum :
1377 : case EAS_RadiusRangeMaximum :
1378 : {
1379 : CheckAndResolveEquationParameter( *((com::sun::star::drawing::EnhancedCustomShapeParameter*)
1380 100 : pValues->Value.getValue()), pH );
1381 : }
1382 100 : break;
1383 :
1384 : case EAS_Position :
1385 : case EAS_Polar :
1386 : {
1387 : CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*)
1388 52 : pValues->Value.getValue())).First, pH );
1389 : CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*)
1390 52 : pValues->Value.getValue())).Second, pH );
1391 : }
1392 52 : break;
1393 : default:
1394 14 : break;
1395 : }
1396 166 : pValues++;
1397 : }
1398 49 : ++aHandleIter;
1399 : }
1400 49 : delete pH;
1401 : }
1402 :
1403 69 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maExtrusion, EASGet( EAS_Extrusion ) );
1404 69 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maPath, EASGet( EAS_Path ) );
1405 69 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maTextPath, EASGet( EAS_TextPath ) );
1406 69 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maEquations, EASGet( EAS_Equations ) );
1407 69 : if ( !maHandles.empty() )
1408 46 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maHandles, EASGet( EAS_Handles ) );
1409 69 : }
1410 :
1411 742 : SvXMLImportContext* XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt16 nPrefix,const OUString& rLocalName,
1412 : const uno::Reference< xml::sax::XAttributeList> & xAttrList )
1413 : {
1414 742 : EnhancedCustomShapeTokenEnum aTokenEnum = EASGet( rLocalName );
1415 742 : if ( aTokenEnum == EAS_equation )
1416 : {
1417 693 : sal_Int16 nLength = xAttrList->getLength();
1418 693 : if ( nLength )
1419 : {
1420 693 : OUString aFormula;
1421 1386 : OUString aFormulaName;
1422 2079 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
1423 : {
1424 1386 : OUString aLocalName;
1425 2772 : const OUString& rValue = xAttrList->getValueByIndex( nAttr );
1426 1386 : /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
1427 :
1428 1386 : switch( EASGet( aLocalName ) )
1429 : {
1430 : case EAS_formula :
1431 693 : aFormula = rValue;
1432 693 : break;
1433 : case EAS_name :
1434 693 : aFormulaName = rValue;
1435 693 : break;
1436 : default:
1437 0 : break;
1438 : }
1439 1386 : }
1440 693 : if ( !aFormulaName.isEmpty() || !aFormula.isEmpty() )
1441 : {
1442 693 : maEquations.push_back( aFormula );
1443 693 : maEquationNames.push_back( aFormulaName );
1444 693 : }
1445 : }
1446 : }
1447 49 : else if ( aTokenEnum == EAS_handle )
1448 : {
1449 49 : std::vector< com::sun::star::beans::PropertyValue > aHandle;
1450 49 : const sal_Int16 nLength = xAttrList->getLength();
1451 215 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
1452 : {
1453 166 : OUString aLocalName;
1454 332 : const OUString& rValue = xAttrList->getValueByIndex( nAttr );
1455 166 : /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
1456 166 : switch( EASGet( aLocalName ) )
1457 : {
1458 : case EAS_handle_mirror_vertical :
1459 0 : GetBool( aHandle, rValue, EAS_MirroredY );
1460 0 : break;
1461 : case EAS_handle_mirror_horizontal :
1462 0 : GetBool( aHandle, rValue, EAS_MirroredX );
1463 0 : break;
1464 : case EAS_handle_switched :
1465 14 : GetBool( aHandle, rValue, EAS_Switched );
1466 14 : break;
1467 : case EAS_handle_position :
1468 49 : GetEnhancedParameterPair( aHandle, rValue, EAS_Position );
1469 49 : break;
1470 : case EAS_handle_range_x_minimum :
1471 28 : GetEnhancedParameter( aHandle, rValue, EAS_RangeXMinimum );
1472 28 : break;
1473 : case EAS_handle_range_x_maximum :
1474 28 : GetEnhancedParameter( aHandle, rValue, EAS_RangeXMaximum );
1475 28 : break;
1476 : case EAS_handle_range_y_minimum :
1477 19 : GetEnhancedParameter( aHandle, rValue, EAS_RangeYMinimum );
1478 19 : break;
1479 : case EAS_handle_range_y_maximum :
1480 19 : GetEnhancedParameter( aHandle, rValue, EAS_RangeYMaximum );
1481 19 : break;
1482 : case EAS_handle_polar :
1483 3 : GetEnhancedParameterPair( aHandle, rValue, EAS_Polar );
1484 3 : break;
1485 : case EAS_handle_radius_range_minimum :
1486 3 : GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMinimum );
1487 3 : break;
1488 : case EAS_handle_radius_range_maximum :
1489 3 : GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMaximum );
1490 3 : break;
1491 : default:
1492 0 : break;
1493 : }
1494 166 : }
1495 49 : beans::PropertyValues aPropSeq( aHandle.size() );
1496 49 : std::vector< beans::PropertyValue >::const_iterator aIter = aHandle.begin();
1497 49 : std::vector< beans::PropertyValue >::const_iterator aEnd = aHandle.end();
1498 49 : beans::PropertyValue* pValues = aPropSeq.getArray();
1499 :
1500 264 : while ( aIter != aEnd )
1501 166 : *pValues++ = *aIter++;
1502 :
1503 49 : maHandles.push_back( aPropSeq );
1504 : }
1505 742 : return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
1506 : }
1507 :
1508 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|