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