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 62 : XMLEnhancedCustomShapeContext::XMLEnhancedCustomShapeContext( SvXMLImport& rImport,
57 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
58 : sal_uInt16 nPrefix, const rtl::OUString& rLocalName,
59 : std::vector< com::sun::star::beans::PropertyValue >& rCustomShapeGeometry ) :
60 : SvXMLImportContext( rImport, nPrefix, rLocalName ),
61 62 : mrUnitConverter( rImport.GetMM100UnitConverter() ),
62 : mrxShape( rxShape ),
63 124 : mrCustomShapeGeometry( rCustomShapeGeometry )
64 : {
65 62 : }
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 18 : void GetBool( std::vector< com::sun::star::beans::PropertyValue >& rDest,
76 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
77 : {
78 : bool bAttrBool;
79 18 : if (::sax::Converter::convertBool( bAttrBool, rValue ))
80 : {
81 18 : beans::PropertyValue aProp;
82 18 : aProp.Name = EASGet( eDestProp );
83 18 : aProp.Value <<= bAttrBool;
84 18 : rDest.push_back( aProp );
85 : }
86 18 : }
87 :
88 0 : void GetInt32( std::vector< com::sun::star::beans::PropertyValue >& rDest,
89 : const rtl::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 rtl::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 rtl::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 62 : void GetString( std::vector< com::sun::star::beans::PropertyValue >& rDest,
131 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
132 : {
133 62 : beans::PropertyValue aProp;
134 62 : aProp.Name = EASGet( eDestProp );
135 62 : aProp.Value <<= rValue;
136 62 : rDest.push_back( aProp );
137 62 : }
138 :
139 2 : void GetEnum( std::vector< com::sun::star::beans::PropertyValue >& rDest,
140 : const rtl::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 rtl::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 rtl::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 1520 : sal_Bool GetEquationName( const rtl::OUString& rEquation, const sal_Int32 nStart, rtl::OUString& rEquationName )
189 : {
190 1520 : sal_Int32 nIndex = nStart;
191 6471 : while( nIndex < rEquation.getLength() )
192 : {
193 4884 : sal_Unicode nChar = rEquation[ nIndex ];
194 4884 : if (
195 : ( ( nChar >= 'a' ) && ( nChar <= 'z' ) )
196 : || ( ( nChar >= 'A' ) && ( nChar <= 'Z' ) )
197 : || ( ( nChar >= '0' ) && ( nChar <= '9' ) )
198 : )
199 : {
200 3431 : nIndex++;
201 : }
202 : else
203 1453 : break;
204 : }
205 1520 : sal_Bool bValid = ( nIndex - nStart ) != 0;
206 1520 : if ( bValid )
207 1520 : rEquationName = rEquation.copy( nStart, nIndex - nStart );
208 1520 : return bValid;
209 : }
210 :
211 3640 : sal_Bool GetNextParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, sal_Int32& nIndex, const rtl::OUString& rParaString )
212 : {
213 3640 : if ( nIndex >= rParaString.getLength() )
214 128 : return sal_False;
215 :
216 3512 : sal_Bool bValid = sal_True;
217 3512 : sal_Bool bNumberRequired = sal_True;
218 3512 : sal_Bool bMustBePositiveWholeNumbered = sal_False;
219 :
220 3512 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL;
221 3512 : if ( rParaString[ nIndex ] == (sal_Unicode)'$' )
222 : {
223 48 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT;
224 48 : bMustBePositiveWholeNumbered = sal_True;
225 48 : nIndex++;
226 : }
227 3464 : else if ( rParaString[ nIndex ] == (sal_Unicode)'?' )
228 : {
229 1053 : nIndex++;
230 1053 : bNumberRequired = sal_False;
231 1053 : rtl::OUString aEquationName;
232 1053 : bValid = GetEquationName( rParaString, nIndex, aEquationName );
233 1053 : if ( bValid )
234 : {
235 1053 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION;
236 1053 : rParameter.Value <<= aEquationName;
237 1053 : nIndex += aEquationName.getLength();
238 1053 : }
239 : }
240 2411 : else if ( rParaString[ nIndex ] > (sal_Unicode)'9' )
241 : {
242 25 : bNumberRequired = sal_False;
243 25 : if ( rParaString.matchIgnoreAsciiCaseAsciiL( "left", 4, nIndex ) )
244 : {
245 8 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT;
246 8 : nIndex += 4;
247 : }
248 17 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "top", 3, nIndex ) )
249 : {
250 13 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP;
251 13 : 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 3512 : if ( bValid )
307 : {
308 3512 : if ( bNumberRequired )
309 : {
310 2434 : sal_Int32 nStartIndex = nIndex;
311 2434 : sal_Int32 nEIndex = 0; // index of "E" in double
312 :
313 2434 : sal_Bool bE = sal_False; // set if a double is including a "E" statement
314 2434 : sal_Bool bENum = sal_False; // there is at least one number after "E"
315 2434 : sal_Bool bDot = sal_False; // set if there is a dot included
316 2434 : sal_Bool bEnd = sal_False; // set for each value that can not be part of a double/integer
317 :
318 13751 : while( ( nIndex < rParaString.getLength() ) && bValid )
319 : {
320 11096 : 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 8869 : if ( bE && ! bENum )
385 0 : bENum = sal_True;
386 : }
387 8869 : break;
388 : default:
389 2213 : bEnd = sal_True;
390 : }
391 11096 : if ( !bEnd )
392 8883 : nIndex++;
393 : else
394 2213 : break;
395 : }
396 2434 : if ( nIndex == nStartIndex )
397 0 : bValid = sal_False;
398 2434 : if ( bValid )
399 : {
400 2434 : rtl::OUString aNumber( rParaString.copy( nStartIndex, nIndex - nStartIndex ) );
401 2434 : 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 2433 : if (::sax::Converter::convertNumber(nValue, aNumber))
413 2433 : rParameter.Value <<= nValue;
414 : else
415 0 : bValid = sal_False;
416 2434 : }
417 : }
418 : }
419 : }
420 3512 : if ( bValid )
421 : { // skipping white spaces
422 10260 : while( ( nIndex < rParaString.getLength() ) && rParaString[ nIndex ] == (sal_Unicode)' ' )
423 3236 : nIndex++;
424 : }
425 3512 : return bValid;
426 : }
427 :
428 1 : void GetPosition3D( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:extrusion-viewpoint
429 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp,
430 : SvXMLUnitConverter& rUnitConverter )
431 : {
432 1 : drawing::Position3D aPosition3D;
433 1 : if ( rUnitConverter.convertPosition3D( aPosition3D, rValue ) )
434 : {
435 1 : beans::PropertyValue aProp;
436 1 : aProp.Name = EASGet( eDestProp );
437 1 : aProp.Value <<= aPosition3D;
438 1 : rDest.push_back( aProp );
439 : }
440 1 : }
441 :
442 0 : void GetDoubleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-point-leaving-directions
443 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
444 : {
445 0 : std::vector< double > vDirection;
446 0 : sal_Int32 nIndex = 0;
447 0 : do
448 : {
449 : double fAttrDouble;
450 0 : rtl::OUString aToken( rValue.getToken( 0, ',', nIndex ) );
451 0 : if (!::sax::Converter::convertDouble( fAttrDouble, aToken ))
452 : break;
453 : else
454 0 : vDirection.push_back( fAttrDouble );
455 : }
456 : while ( nIndex >= 0 );
457 :
458 0 : if ( !vDirection.empty() )
459 : {
460 0 : uno::Sequence< double > aDirectionsSeq( vDirection.size() );
461 0 : std::vector< double >::const_iterator aIter = vDirection.begin();
462 0 : std::vector< double >::const_iterator aEnd = vDirection.end();
463 0 : double* pValues = aDirectionsSeq.getArray();
464 :
465 0 : while ( aIter != aEnd )
466 0 : *pValues++ = *aIter++;
467 :
468 0 : beans::PropertyValue aProp;
469 0 : aProp.Name = EASGet( eDestProp );
470 0 : aProp.Value <<= aDirectionsSeq;
471 0 : rDest.push_back( aProp );
472 0 : }
473 0 : }
474 :
475 94 : void GetEnhancedParameter( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position
476 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
477 : {
478 94 : sal_Int32 nIndex = 0;
479 94 : com::sun::star::drawing::EnhancedCustomShapeParameter aParameter;
480 94 : if ( GetNextParameter( aParameter, nIndex, rValue ) )
481 : {
482 94 : beans::PropertyValue aProp;
483 94 : aProp.Name = EASGet( eDestProp );
484 94 : aProp.Value <<= aParameter;
485 94 : rDest.push_back( aProp );
486 94 : }
487 94 : }
488 :
489 51 : void GetEnhancedParameterPair( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position
490 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
491 : {
492 51 : sal_Int32 nIndex = 0;
493 51 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair;
494 102 : if ( GetNextParameter( aParameterPair.First, nIndex, rValue )
495 51 : && GetNextParameter( aParameterPair.Second, nIndex, rValue ) )
496 : {
497 51 : beans::PropertyValue aProp;
498 51 : aProp.Name = EASGet( eDestProp );
499 51 : aProp.Value <<= aParameterPair;
500 51 : rDest.push_back( aProp );
501 51 : }
502 51 : }
503 :
504 33 : sal_Int32 GetEnhancedParameterPairSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-points
505 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
506 : {
507 33 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vParameter;
508 33 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameter;
509 :
510 33 : sal_Int32 nIndex = 0;
511 404 : while ( GetNextParameter( aParameter.First, nIndex, rValue )
512 169 : && GetNextParameter( aParameter.Second, nIndex, rValue ) )
513 : {
514 169 : vParameter.push_back( aParameter );
515 : }
516 33 : if ( !vParameter.empty() )
517 : {
518 33 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aParameterSeq( vParameter.size() );
519 33 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aIter = vParameter.begin();
520 33 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aEnd = vParameter.end();
521 33 : com::sun::star::drawing::EnhancedCustomShapeParameterPair* pValues = aParameterSeq.getArray();
522 :
523 235 : while ( aIter != aEnd )
524 169 : *pValues++ = *aIter++;
525 :
526 33 : beans::PropertyValue aProp;
527 33 : aProp.Name = EASGet( eDestProp );
528 33 : aProp.Value <<= aParameterSeq;
529 33 : rDest.push_back( aProp );
530 : }
531 33 : return vParameter.size();
532 : }
533 :
534 52 : void GetEnhancedRectangleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:text-areas
535 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
536 : {
537 52 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame > vTextFrame;
538 52 : com::sun::star::drawing::EnhancedCustomShapeTextFrame aParameter;
539 :
540 52 : sal_Int32 nIndex = 0;
541 :
542 316 : while ( GetNextParameter( aParameter.TopLeft.First, nIndex, rValue )
543 53 : && GetNextParameter( aParameter.TopLeft.Second, nIndex, rValue )
544 53 : && GetNextParameter( aParameter.BottomRight.First, nIndex, rValue )
545 53 : && GetNextParameter( aParameter.BottomRight.Second, nIndex, rValue ) )
546 : {
547 53 : vTextFrame.push_back( aParameter );
548 : }
549 52 : if ( !vTextFrame.empty() )
550 : {
551 52 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrameSeq( vTextFrame.size() );
552 52 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aIter = vTextFrame.begin();
553 52 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aEnd = vTextFrame.end();
554 52 : com::sun::star::drawing::EnhancedCustomShapeTextFrame* pValues = aTextFrameSeq.getArray();
555 :
556 157 : while ( aIter != aEnd )
557 53 : *pValues++ = *aIter++;
558 :
559 52 : beans::PropertyValue aProp;
560 52 : aProp.Name = EASGet( eDestProp );
561 52 : aProp.Value <<= aTextFrameSeq;
562 52 : rDest.push_back( aProp );
563 52 : }
564 52 : }
565 :
566 62 : void GetEnhancedPath( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:enhanced-path
567 : const rtl::OUString& rValue )
568 : {
569 62 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vCoordinates;
570 62 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment > vSegments;
571 :
572 62 : sal_Int32 nIndex = 0;
573 62 : sal_Int32 nParameterCount = 0;
574 :
575 62 : sal_Int32 nParametersNeeded = 1;
576 62 : sal_Int16 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
577 :
578 62 : sal_Bool bValid = sal_True;
579 :
580 2715 : while( bValid && ( nIndex < rValue.getLength() ) )
581 : {
582 2591 : switch( rValue[ nIndex ] )
583 : {
584 : case 'M' :
585 : {
586 140 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
587 140 : nParametersNeeded = 1;
588 140 : nIndex++;
589 : }
590 140 : break;
591 : case 'L' :
592 : {
593 124 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
594 124 : nParametersNeeded = 1;
595 124 : nIndex++;
596 : }
597 124 : break;
598 : case 'C' :
599 : {
600 52 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
601 52 : nParametersNeeded = 3;
602 52 : nIndex++;
603 : }
604 52 : break;
605 : case 'Z' :
606 : {
607 123 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
608 123 : nParametersNeeded = 0;
609 123 : nIndex++;
610 : }
611 123 : break;
612 : case 'N' :
613 : {
614 136 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
615 136 : nParametersNeeded = 0;
616 136 : nIndex++;
617 : }
618 136 : break;
619 : case 'F' :
620 : {
621 12 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL;
622 12 : nParametersNeeded = 0;
623 12 : nIndex++;
624 : }
625 12 : break;
626 : case 'S' :
627 : {
628 4 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE;
629 4 : nParametersNeeded = 0;
630 4 : nIndex++;
631 : }
632 4 : break;
633 : case 'T' :
634 : {
635 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
636 0 : nParametersNeeded = 3;
637 0 : nIndex++;
638 : }
639 0 : break;
640 : case 'U' :
641 : {
642 10 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
643 10 : nParametersNeeded = 3;
644 10 : nIndex++;
645 : }
646 10 : break;
647 : case 'A' :
648 : {
649 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
650 0 : nParametersNeeded = 4;
651 0 : nIndex++;
652 : }
653 0 : break;
654 : case 'B' :
655 : {
656 3 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC;
657 3 : nParametersNeeded = 4;
658 3 : nIndex++;
659 : }
660 3 : break;
661 : case 'G' :
662 : {
663 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO;
664 0 : nParametersNeeded = 2;
665 0 : nIndex++;
666 : }
667 0 : break;
668 : case 'W' :
669 : {
670 1 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
671 1 : nParametersNeeded = 4;
672 1 : nIndex++;
673 : }
674 1 : break;
675 : case 'V' :
676 : {
677 1 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
678 1 : nParametersNeeded = 4;
679 1 : nIndex++;
680 : }
681 1 : break;
682 : case 'X' :
683 : {
684 19 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
685 19 : nParametersNeeded = 1;
686 19 : nIndex++;
687 : }
688 19 : break;
689 : case 'Y' :
690 : {
691 22 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
692 22 : nParametersNeeded = 1;
693 22 : nIndex++;
694 : }
695 22 : break;
696 : case 'Q' :
697 : {
698 0 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
699 0 : nParametersNeeded = 2;
700 0 : nIndex++;
701 : }
702 0 : break;
703 : case ' ' :
704 : {
705 586 : nIndex++;
706 : }
707 586 : break;
708 :
709 : case '$' :
710 : case '?' :
711 : case '0' :
712 : case '1' :
713 : case '2' :
714 : case '3' :
715 : case '4' :
716 : case '5' :
717 : case '6' :
718 : case '7' :
719 : case '8' :
720 : case '9' :
721 : case '.' :
722 : case '-' :
723 : {
724 1358 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aPair;
725 2716 : if ( GetNextParameter( aPair.First, nIndex, rValue ) &&
726 1358 : GetNextParameter( aPair.Second, nIndex, rValue ) )
727 : {
728 1358 : vCoordinates.push_back( aPair );
729 1358 : nParameterCount++;
730 : }
731 : else
732 0 : bValid = sal_False;
733 : }
734 1358 : break;
735 : default:
736 0 : nIndex++;
737 0 : break;
738 : }
739 2591 : if ( !nParameterCount && !nParametersNeeded )
740 : {
741 275 : com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
742 275 : aSegment.Command = nLatestSegmentCommand;
743 275 : aSegment.Count = 0;
744 275 : vSegments.push_back( aSegment );
745 275 : nParametersNeeded = 0x7fffffff;
746 : }
747 2316 : else if ( nParameterCount >= nParametersNeeded )
748 : {
749 : // check if the last command is identical,
750 : // if so, we just need to increment the count
751 891 : if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) )
752 519 : vSegments[ vSegments.size() -1 ].Count++;
753 : else
754 : {
755 372 : com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
756 372 : aSegment.Command = nLatestSegmentCommand;
757 372 : aSegment.Count = 1;
758 372 : vSegments.push_back( aSegment );
759 : }
760 891 : nParameterCount = 0;
761 : }
762 : }
763 : // adding the Coordinates property
764 62 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > seqCoordinates( vCoordinates.size() );
765 62 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesIter = vCoordinates.begin();
766 62 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesEnd = vCoordinates.end();
767 62 : com::sun::star::drawing::EnhancedCustomShapeParameterPair* pCoordinateValues = seqCoordinates.getArray();
768 :
769 1482 : while ( aCoordinatesIter != aCoordinatesEnd )
770 1358 : *pCoordinateValues++ = *aCoordinatesIter++;
771 :
772 62 : beans::PropertyValue aProp;
773 62 : aProp.Name = EASGet( EAS_Coordinates );
774 62 : aProp.Value <<= seqCoordinates;
775 62 : rDest.push_back( aProp );
776 :
777 :
778 : // adding the Segments property
779 62 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments( vSegments.size() );
780 62 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsIter = vSegments.begin();
781 62 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsEnd = vSegments.end();
782 62 : com::sun::star::drawing::EnhancedCustomShapeSegment* pSegmentValues = seqSegments.getArray();
783 :
784 771 : while ( aSegmentsIter != aSegmentsEnd )
785 647 : *pSegmentValues++ = *aSegmentsIter++;
786 :
787 62 : aProp.Name = EASGet( EAS_Segments );
788 62 : aProp.Value <<= seqSegments;
789 62 : rDest.push_back( aProp );
790 62 : }
791 :
792 43 : void GetAdjustmentValues( std::vector< com::sun::star::beans::PropertyValue >& rDest, // draw:adjustments
793 : const rtl::OUString& rValue )
794 : {
795 43 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > vAdjustmentValue;
796 43 : com::sun::star::drawing::EnhancedCustomShapeParameter aParameter;
797 43 : sal_Int32 nIndex = 0;
798 134 : while ( GetNextParameter( aParameter, nIndex, rValue ) )
799 : {
800 48 : com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue aAdj;
801 48 : if ( aParameter.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL )
802 : {
803 48 : aAdj.Value <<= aParameter.Value;
804 48 : aAdj.State = beans::PropertyState_DIRECT_VALUE;
805 : }
806 : else
807 0 : aAdj.State = beans::PropertyState_DEFAULT_VALUE; // this should not be, but better than setting nothing
808 :
809 48 : vAdjustmentValue.push_back( aAdj );
810 48 : }
811 :
812 43 : sal_Int32 nAdjustmentValues = vAdjustmentValue.size();
813 43 : if ( nAdjustmentValues )
814 : {
815 43 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( nAdjustmentValues );
816 43 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aIter = vAdjustmentValue.begin();
817 43 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aEnd = vAdjustmentValue.end();
818 43 : com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue* pValues = aAdjustmentValues.getArray();
819 :
820 134 : while ( aIter != aEnd )
821 48 : *pValues++ = *aIter++;
822 :
823 43 : beans::PropertyValue aProp;
824 43 : aProp.Name = EASGet( EAS_AdjustmentValues );
825 43 : aProp.Value <<= aAdjustmentValues;
826 43 : rDest.push_back( aProp );
827 43 : }
828 43 : }
829 :
830 62 : void XMLEnhancedCustomShapeContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
831 : {
832 62 : sal_Int16 nLength = xAttrList->getLength();
833 62 : if ( nLength )
834 : {
835 : sal_Int32 nAttrNumber;
836 421 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
837 : {
838 359 : rtl::OUString aLocalName;
839 359 : const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr );
840 359 : /* sven fixme, this must be checked! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
841 :
842 359 : switch( EASGet( aLocalName ) )
843 : {
844 : case EAS_type :
845 62 : GetString( mrCustomShapeGeometry, rValue, EAS_Type );
846 62 : break;
847 : case EAS_mirror_horizontal :
848 3 : GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredX );
849 3 : break;
850 : case EAS_mirror_vertical :
851 2 : GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredY );
852 2 : break;
853 : case EAS_viewBox :
854 : {
855 61 : SdXMLImExViewBox aViewBox( rValue, GetImport().GetMM100UnitConverter() );
856 61 : awt::Rectangle aRect( aViewBox.GetX(), aViewBox.GetY(), aViewBox.GetWidth(), aViewBox.GetHeight() );
857 61 : beans::PropertyValue aProp;
858 61 : aProp.Name = EASGet( EAS_ViewBox );
859 61 : aProp.Value <<= aRect;
860 61 : mrCustomShapeGeometry.push_back( aProp );
861 : }
862 61 : break;
863 : case EAS_text_rotate_angle :
864 0 : GetDouble( mrCustomShapeGeometry, rValue, EAS_TextRotateAngle );
865 0 : break;
866 : case EAS_extrusion_allowed :
867 0 : GetBool( maPath, rValue, EAS_ExtrusionAllowed );
868 0 : break;
869 : case EAS_text_path_allowed :
870 0 : GetBool( maPath, rValue, EAS_TextPathAllowed );
871 0 : break;
872 : case EAS_concentric_gradient_fill_allowed :
873 0 : GetBool( maPath, rValue, EAS_ConcentricGradientFillAllowed );
874 0 : break;
875 : case EAS_extrusion :
876 0 : GetBool( maExtrusion, rValue, EAS_Extrusion );
877 0 : break;
878 : case EAS_extrusion_brightness :
879 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Brightness );
880 0 : break;
881 : case EAS_extrusion_depth :
882 : {
883 1 : sal_Int32 nIndex = 0;
884 1 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair;
885 1 : com::sun::star::drawing::EnhancedCustomShapeParameter& rDepth = aParameterPair.First;
886 1 : com::sun::star::drawing::EnhancedCustomShapeParameter& rFraction = aParameterPair.Second;
887 1 : if ( GetNextParameter( rDepth, nIndex, rValue ) )
888 : {
889 : // try to catch the unit for the depth
890 : sal_Int16 const eSrcUnit(
891 : ::sax::Converter::GetUnitFromString(
892 1 : rValue, util::MeasureUnit::MM_100TH));
893 :
894 1 : rtl::OUStringBuffer aUnitStr;
895 : double fFactor = ::sax::Converter::GetConversionFactor(
896 1 : aUnitStr, util::MeasureUnit::MM_100TH, eSrcUnit);
897 1 : if ( ( fFactor != 1.0 ) && ( fFactor != 0.0 ) )
898 : {
899 1 : double fDepth(0.0);
900 1 : if ( rDepth.Value >>= fDepth )
901 : {
902 1 : fDepth /= fFactor;
903 1 : rDepth.Value <<= fDepth;
904 : }
905 : }
906 1 : if ( rValue.matchIgnoreAsciiCase( aUnitStr.toString(), nIndex ) )
907 1 : nIndex += aUnitStr.getLength();
908 :
909 : // skipping white spaces
910 3 : while( ( nIndex < rValue.getLength() ) && rValue[ nIndex ] == (sal_Unicode)' ' )
911 1 : nIndex++;
912 :
913 1 : if ( GetNextParameter( rFraction, nIndex, rValue ) )
914 : {
915 1 : beans::PropertyValue aProp;
916 1 : aProp.Name = EASGet( EAS_Depth );
917 1 : aProp.Value <<= aParameterPair;
918 1 : maExtrusion.push_back( aProp );
919 1 : }
920 1 : }
921 : }
922 1 : break;
923 : case EAS_extrusion_diffusion :
924 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Diffusion );
925 0 : break;
926 : case EAS_extrusion_number_of_line_segments :
927 0 : GetInt32( maExtrusion, rValue, EAS_NumberOfLineSegments );
928 0 : break;
929 : case EAS_extrusion_light_face :
930 0 : GetBool( maExtrusion, rValue, EAS_LightFace );
931 0 : break;
932 : case EAS_extrusion_first_light_harsh :
933 0 : GetBool( maExtrusion, rValue, EAS_FirstLightHarsh );
934 0 : break;
935 : case EAS_extrusion_second_light_harsh :
936 0 : GetBool( maExtrusion, rValue, EAS_SecondLightHarsh );
937 0 : break;
938 : case EAS_extrusion_first_light_level :
939 0 : GetDoublePercentage( maExtrusion, rValue, EAS_FirstLightLevel );
940 0 : break;
941 : case EAS_extrusion_second_light_level :
942 0 : GetDoublePercentage( maExtrusion, rValue, EAS_SecondLightLevel );
943 0 : break;
944 : case EAS_extrusion_first_light_direction :
945 0 : GetB3DVector( maExtrusion, rValue, EAS_FirstLightDirection );
946 0 : break;
947 : case EAS_extrusion_second_light_direction :
948 0 : GetB3DVector( maExtrusion, rValue, EAS_SecondLightDirection );
949 0 : break;
950 : case EAS_extrusion_metal :
951 0 : GetBool( maExtrusion, rValue, EAS_Metal );
952 0 : break;
953 : case EAS_shade_mode :
954 : {
955 0 : drawing::ShadeMode eShadeMode( drawing::ShadeMode_FLAT );
956 0 : if( IsXMLToken( rValue, XML_PHONG ) )
957 0 : eShadeMode = drawing::ShadeMode_PHONG;
958 0 : else if ( IsXMLToken( rValue, XML_GOURAUD ) )
959 0 : eShadeMode = drawing::ShadeMode_SMOOTH;
960 0 : else if ( IsXMLToken( rValue, XML_DRAFT ) )
961 0 : eShadeMode = drawing::ShadeMode_DRAFT;
962 :
963 0 : beans::PropertyValue aProp;
964 0 : aProp.Name = EASGet( EAS_ShadeMode );
965 0 : aProp.Value <<= eShadeMode;
966 0 : maExtrusion.push_back( aProp );
967 : }
968 0 : break;
969 : case EAS_extrusion_rotation_angle :
970 0 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_RotateAngle );
971 0 : break;
972 : case EAS_extrusion_rotation_center :
973 0 : GetB3DVector( maExtrusion, rValue, EAS_RotationCenter );
974 0 : break;
975 : case EAS_extrusion_shininess :
976 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Shininess );
977 0 : break;
978 : case EAS_extrusion_skew :
979 1 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_Skew );
980 1 : break;
981 : case EAS_extrusion_specularity :
982 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Specularity );
983 0 : break;
984 : case EAS_projection :
985 : {
986 1 : drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PERSPECTIVE );
987 1 : if( IsXMLToken( rValue, XML_PARALLEL ) )
988 0 : eProjectionMode = drawing::ProjectionMode_PARALLEL;
989 :
990 1 : beans::PropertyValue aProp;
991 1 : aProp.Name = EASGet( EAS_ProjectionMode );
992 1 : aProp.Value <<= eProjectionMode;
993 1 : maExtrusion.push_back( aProp );
994 : }
995 1 : break;
996 : case EAS_extrusion_viewpoint :
997 1 : GetPosition3D( maExtrusion, rValue, EAS_ViewPoint, mrUnitConverter );
998 1 : break;
999 : case EAS_extrusion_origin :
1000 1 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_Origin );
1001 1 : break;
1002 : case EAS_extrusion_color :
1003 0 : GetBool( maExtrusion, rValue, EAS_Color );
1004 0 : break;
1005 : case EAS_enhanced_path :
1006 62 : GetEnhancedPath( maPath, rValue );
1007 62 : break;
1008 : case EAS_path_stretchpoint_x :
1009 : {
1010 18 : if (::sax::Converter::convertNumber(nAttrNumber, rValue))
1011 : {
1012 18 : beans::PropertyValue aProp;
1013 18 : aProp.Name = EASGet( EAS_StretchX );
1014 18 : aProp.Value <<= nAttrNumber;
1015 18 : maPath.push_back( aProp );
1016 : }
1017 : }
1018 18 : break;
1019 : case EAS_path_stretchpoint_y :
1020 : {
1021 16 : if (::sax::Converter::convertNumber(nAttrNumber, rValue))
1022 : {
1023 16 : beans::PropertyValue aProp;
1024 16 : aProp.Name = EASGet( EAS_StretchY );
1025 16 : aProp.Value <<= nAttrNumber;
1026 16 : maPath.push_back( aProp );
1027 : }
1028 : }
1029 16 : break;
1030 : case EAS_text_areas :
1031 52 : GetEnhancedRectangleSequence( maPath, rValue, EAS_TextFrames );
1032 52 : break;
1033 : case EAS_glue_points :
1034 : {
1035 33 : sal_Int32 i, nPairs = GetEnhancedParameterPairSequence( maPath, rValue, EAS_GluePoints );
1036 33 : GetImport().GetShapeImport()->moveGluePointMapping( mrxShape, nPairs );
1037 202 : for ( i = 0; i < nPairs; i++ )
1038 169 : GetImport().GetShapeImport()->addGluePointMapping( mrxShape, i + 4, i + 4 );
1039 : }
1040 33 : break;
1041 : case EAS_glue_point_type :
1042 2 : GetEnum( maPath, rValue, EAS_GluePointType, *aXML_GluePointEnumMap );
1043 2 : break;
1044 : case EAS_glue_point_leaving_directions :
1045 0 : GetDoubleSequence( maPath, rValue, EAS_GluePointLeavingDirections );
1046 0 : break;
1047 : case EAS_text_path :
1048 0 : GetBool( maTextPath, rValue, EAS_TextPath );
1049 0 : break;
1050 : case EAS_text_path_mode :
1051 : {
1052 0 : com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode( com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL );
1053 0 : if( IsXMLToken( rValue, XML_PATH ) )
1054 0 : eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH;
1055 0 : else if ( IsXMLToken( rValue, XML_SHAPE ) )
1056 0 : eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE;
1057 :
1058 0 : beans::PropertyValue aProp;
1059 0 : aProp.Name = EASGet( EAS_TextPathMode );
1060 0 : aProp.Value <<= eTextPathMode;
1061 0 : maTextPath.push_back( aProp );
1062 : }
1063 0 : break;
1064 : case EAS_text_path_scale :
1065 : {
1066 0 : sal_Bool bScaleX = IsXMLToken( rValue, XML_SHAPE );
1067 0 : beans::PropertyValue aProp;
1068 0 : aProp.Name = EASGet( EAS_ScaleX );
1069 0 : aProp.Value <<= bScaleX;
1070 0 : maTextPath.push_back( aProp );
1071 : }
1072 0 : break;
1073 : case EAS_text_path_same_letter_heights :
1074 0 : GetBool( maTextPath, rValue, EAS_SameLetterHeights );
1075 0 : break;
1076 : case EAS_modifiers :
1077 43 : GetAdjustmentValues( mrCustomShapeGeometry, rValue );
1078 43 : break;
1079 : default:
1080 0 : break;
1081 : }
1082 359 : }
1083 : }
1084 62 : }
1085 :
1086 43 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1087 : const std::vector< beans::PropertyValues >& rElement,
1088 : const rtl::OUString& rElementName )
1089 : {
1090 43 : if ( !rElement.empty() )
1091 : {
1092 43 : uno::Sequence< beans::PropertyValues > aPropSeq( rElement.size() );
1093 43 : std::vector< beans::PropertyValues >::const_iterator aIter = rElement.begin();
1094 43 : std::vector< beans::PropertyValues >::const_iterator aEnd = rElement.end();
1095 43 : beans::PropertyValues* pValues = aPropSeq.getArray();
1096 :
1097 132 : while ( aIter != aEnd )
1098 46 : *pValues++ = *aIter++;
1099 :
1100 43 : beans::PropertyValue aProp;
1101 43 : aProp.Name = rElementName;
1102 43 : aProp.Value <<= aPropSeq;
1103 43 : rPropVec.push_back( aProp );
1104 : }
1105 43 : }
1106 :
1107 62 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1108 : const std::vector< rtl::OUString >& rElement,
1109 : const rtl::OUString& rElementName )
1110 : {
1111 62 : if ( !rElement.empty() )
1112 : {
1113 43 : uno::Sequence< rtl::OUString > aPropSeq( rElement.size() );
1114 43 : std::vector< rtl::OUString >::const_iterator aIter = rElement.begin();
1115 43 : std::vector< rtl::OUString >::const_iterator aEnd = rElement.end();
1116 43 : rtl::OUString* pValues = aPropSeq.getArray();
1117 :
1118 750 : while ( aIter != aEnd )
1119 664 : *pValues++ = *aIter++;
1120 :
1121 43 : beans::PropertyValue aProp;
1122 43 : aProp.Name = rElementName;
1123 43 : aProp.Value <<= aPropSeq;
1124 43 : rPropVec.push_back( aProp );
1125 : }
1126 62 : }
1127 :
1128 186 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1129 : const std::vector< com::sun::star::beans::PropertyValue >& rElement,
1130 : const rtl::OUString& rElementName )
1131 : {
1132 186 : if ( !rElement.empty() )
1133 : {
1134 63 : uno::Sequence< beans::PropertyValue > aPropSeq( rElement.size() );
1135 63 : std::vector< beans::PropertyValue >::const_iterator aIter = rElement.begin();
1136 63 : std::vector< beans::PropertyValue >::const_iterator aEnd = rElement.end();
1137 63 : beans::PropertyValue* pValues = aPropSeq.getArray();
1138 :
1139 376 : while ( aIter != aEnd )
1140 250 : *pValues++ = *aIter++;
1141 :
1142 63 : beans::PropertyValue aProp;
1143 63 : aProp.Name = rElementName;
1144 63 : aProp.Value <<= aPropSeq;
1145 63 : rPropVec.push_back( aProp );
1146 : }
1147 186 : }
1148 :
1149 : typedef boost::unordered_map< rtl::OUString, sal_Int32, rtl::OUStringHash, OUStringEqFunc> EquationHashMap;
1150 :
1151 : /* if rPara.Type is from type EnhancedCustomShapeParameterType::EQUATION, the name of the equation
1152 : will be converted from rtl::OUString to index */
1153 1972 : void CheckAndResolveEquationParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rPara, EquationHashMap* pH )
1154 : {
1155 1972 : if ( rPara.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION )
1156 : {
1157 1053 : rtl::OUString aEquationName;
1158 1053 : if ( rPara.Value >>= aEquationName )
1159 : {
1160 1053 : sal_Int32 nIndex = 0;
1161 1053 : EquationHashMap::iterator aHashIter( pH->find( aEquationName ) );
1162 1053 : if ( aHashIter != pH->end() )
1163 1053 : nIndex = (*aHashIter).second;
1164 1053 : rPara.Value <<= nIndex;
1165 1053 : }
1166 : }
1167 1972 : }
1168 :
1169 62 : void XMLEnhancedCustomShapeContext::EndElement()
1170 : {
1171 : // resolve properties that are indexing a Equation
1172 62 : if ( !maEquations.empty() )
1173 : {
1174 : // creating hash map containing the name and index of each equation
1175 43 : EquationHashMap* pH = new EquationHashMap;
1176 43 : std::vector< rtl::OUString >::iterator aEquationNameIter = maEquationNames.begin();
1177 43 : std::vector< rtl::OUString >::iterator aEquationNameEnd = maEquationNames.end();
1178 750 : while( aEquationNameIter != aEquationNameEnd )
1179 : {
1180 664 : (*pH)[ *aEquationNameIter ] = (sal_Int32)( aEquationNameIter - maEquationNames.begin() );
1181 664 : ++aEquationNameIter;
1182 : }
1183 :
1184 : // resolve equation
1185 43 : std::vector< rtl::OUString >::iterator aEquationIter = maEquations.begin();
1186 43 : std::vector< rtl::OUString >::iterator aEquationEnd = maEquations.end();
1187 750 : while( aEquationIter != aEquationEnd )
1188 : {
1189 664 : sal_Int32 nIndexOf = 0;
1190 1131 : do
1191 : {
1192 1131 : nIndexOf = aEquationIter->indexOf( '?', nIndexOf );
1193 1131 : if ( nIndexOf != -1 )
1194 : {
1195 467 : rtl::OUString aEquationName;
1196 467 : if ( GetEquationName( *aEquationIter, nIndexOf + 1, aEquationName ) )
1197 : {
1198 : // copying first characters inclusive '?'
1199 467 : rtl::OUString aNew( aEquationIter->copy( 0, nIndexOf + 1 ) );
1200 467 : sal_Int32 nIndex = 0;
1201 467 : EquationHashMap::iterator aHashIter( pH->find( aEquationName ) );
1202 467 : if ( aHashIter != pH->end() )
1203 467 : nIndex = (*aHashIter).second;
1204 467 : aNew += rtl::OUString::valueOf( nIndex );
1205 467 : aNew += aEquationIter->copy( nIndexOf + aEquationName.getLength() + 1 );
1206 467 : *aEquationIter = aNew;
1207 : }
1208 467 : nIndexOf++;
1209 : }
1210 : }
1211 : while( nIndexOf != -1 );
1212 664 : ++aEquationIter;
1213 : }
1214 :
1215 : // Path
1216 : sal_Int32 i;
1217 43 : std::vector< beans::PropertyValue >::iterator aPathIter = maPath.begin();
1218 43 : std::vector< beans::PropertyValue >::iterator aPathEnd = maPath.end();
1219 275 : while ( aPathIter != aPathEnd )
1220 : {
1221 189 : switch( EASGet( aPathIter->Name ) )
1222 : {
1223 : case EAS_Coordinates :
1224 : case EAS_GluePoints :
1225 : {
1226 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rSeq =
1227 : *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >*)
1228 69 : aPathIter->Value.getValue());
1229 875 : for ( i = 0; i < rSeq.getLength(); i++ )
1230 : {
1231 806 : CheckAndResolveEquationParameter( rSeq[ i ].First, pH );
1232 806 : CheckAndResolveEquationParameter( rSeq[ i ].Second, pH );
1233 : }
1234 : }
1235 69 : break;
1236 : case EAS_TextFrames :
1237 : {
1238 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >& rSeq =
1239 : *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >*)
1240 41 : aPathIter->Value.getValue());
1241 83 : for ( i = 0; i < rSeq.getLength(); i++ )
1242 : {
1243 42 : CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.First, pH );
1244 42 : CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.Second, pH );
1245 42 : CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.First, pH );
1246 42 : CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.Second, pH );
1247 : }
1248 : }
1249 41 : break;
1250 : default:
1251 79 : break;
1252 : }
1253 189 : ++aPathIter;
1254 : }
1255 43 : std::vector< beans::PropertyValues >::iterator aHandleIter = maHandles.begin();
1256 43 : std::vector< beans::PropertyValues >::iterator aHandleEnd = maHandles.end();
1257 132 : while ( aHandleIter != aHandleEnd )
1258 : {
1259 46 : beans::PropertyValue* pValues = aHandleIter->getArray();
1260 202 : for ( i = 0; i < aHandleIter->getLength(); i++ )
1261 : {
1262 156 : switch( EASGet( pValues->Name ) )
1263 : {
1264 : case EAS_RangeYMinimum :
1265 : case EAS_RangeYMaximum :
1266 : case EAS_RangeXMinimum :
1267 : case EAS_RangeXMaximum :
1268 : case EAS_RadiusRangeMinimum :
1269 : case EAS_RadiusRangeMaximum :
1270 : {
1271 : CheckAndResolveEquationParameter( *((com::sun::star::drawing::EnhancedCustomShapeParameter*)
1272 94 : pValues->Value.getValue()), pH );
1273 : }
1274 94 : break;
1275 :
1276 : case EAS_Position :
1277 : case EAS_Polar :
1278 : {
1279 : CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*)
1280 49 : pValues->Value.getValue())).First, pH );
1281 : CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*)
1282 49 : pValues->Value.getValue())).Second, pH );
1283 : }
1284 49 : break;
1285 : default:
1286 13 : break;
1287 : }
1288 156 : pValues++;
1289 : }
1290 46 : ++aHandleIter;
1291 : }
1292 43 : delete pH;
1293 : }
1294 :
1295 62 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maExtrusion, EASGet( EAS_Extrusion ) );
1296 62 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maPath, EASGet( EAS_Path ) );
1297 62 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maTextPath, EASGet( EAS_TextPath ) );
1298 62 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maEquations, EASGet( EAS_Equations ) );
1299 62 : if ( !maHandles.empty() )
1300 43 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maHandles, EASGet( EAS_Handles ) );
1301 62 : }
1302 :
1303 710 : SvXMLImportContext* XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt16 nPrefix,const rtl::OUString& rLocalName,
1304 : const uno::Reference< xml::sax::XAttributeList> & xAttrList )
1305 : {
1306 710 : EnhancedCustomShapeTokenEnum aTokenEnum = EASGet( rLocalName );
1307 710 : if ( aTokenEnum == EAS_equation )
1308 : {
1309 664 : sal_Int16 nLength = xAttrList->getLength();
1310 664 : if ( nLength )
1311 : {
1312 664 : rtl::OUString aFormula;
1313 664 : rtl::OUString aFormulaName;
1314 1992 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
1315 : {
1316 1328 : rtl::OUString aLocalName;
1317 1328 : const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr );
1318 1328 : /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
1319 :
1320 1328 : switch( EASGet( aLocalName ) )
1321 : {
1322 : case EAS_formula :
1323 664 : aFormula = rValue;
1324 664 : break;
1325 : case EAS_name :
1326 664 : aFormulaName = rValue;
1327 664 : break;
1328 : default:
1329 0 : break;
1330 : }
1331 1328 : }
1332 664 : if ( !aFormulaName.isEmpty() || !aFormula.isEmpty() )
1333 : {
1334 664 : maEquations.push_back( aFormula );
1335 664 : maEquationNames.push_back( aFormulaName );
1336 664 : }
1337 : }
1338 : }
1339 46 : else if ( aTokenEnum == EAS_handle )
1340 : {
1341 46 : std::vector< com::sun::star::beans::PropertyValue > aHandle;
1342 46 : const sal_Int16 nLength = xAttrList->getLength();
1343 202 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
1344 : {
1345 156 : rtl::OUString aLocalName;
1346 156 : const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr );
1347 156 : /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
1348 156 : switch( EASGet( aLocalName ) )
1349 : {
1350 : case EAS_handle_mirror_vertical :
1351 0 : GetBool( aHandle, rValue, EAS_MirroredY );
1352 0 : break;
1353 : case EAS_handle_mirror_horizontal :
1354 0 : GetBool( aHandle, rValue, EAS_MirroredX );
1355 0 : break;
1356 : case EAS_handle_switched :
1357 13 : GetBool( aHandle, rValue, EAS_Switched );
1358 13 : break;
1359 : case EAS_handle_position :
1360 46 : GetEnhancedParameterPair( aHandle, rValue, EAS_Position );
1361 46 : break;
1362 : case EAS_handle_range_x_minimum :
1363 27 : GetEnhancedParameter( aHandle, rValue, EAS_RangeXMinimum );
1364 27 : break;
1365 : case EAS_handle_range_x_maximum :
1366 27 : GetEnhancedParameter( aHandle, rValue, EAS_RangeXMaximum );
1367 27 : break;
1368 : case EAS_handle_range_y_minimum :
1369 17 : GetEnhancedParameter( aHandle, rValue, EAS_RangeYMinimum );
1370 17 : break;
1371 : case EAS_handle_range_y_maximum :
1372 17 : GetEnhancedParameter( aHandle, rValue, EAS_RangeYMaximum );
1373 17 : break;
1374 : case EAS_handle_polar :
1375 3 : GetEnhancedParameterPair( aHandle, rValue, EAS_Polar );
1376 3 : break;
1377 : case EAS_handle_radius_range_minimum :
1378 3 : GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMinimum );
1379 3 : break;
1380 : case EAS_handle_radius_range_maximum :
1381 3 : GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMaximum );
1382 3 : break;
1383 : default:
1384 0 : break;
1385 : }
1386 156 : }
1387 46 : beans::PropertyValues aPropSeq( aHandle.size() );
1388 46 : std::vector< beans::PropertyValue >::const_iterator aIter = aHandle.begin();
1389 46 : std::vector< beans::PropertyValue >::const_iterator aEnd = aHandle.end();
1390 46 : beans::PropertyValue* pValues = aPropSeq.getArray();
1391 :
1392 248 : while ( aIter != aEnd )
1393 156 : *pValues++ = *aIter++;
1394 :
1395 46 : maHandles.push_back( aPropSeq );
1396 : }
1397 710 : return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
1398 : }
1399 :
1400 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|