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