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 124 : 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 124 : mrUnitConverter( rImport.GetMM100UnitConverter() ),
62 : mrxShape( rxShape ),
63 248 : mrCustomShapeGeometry( rCustomShapeGeometry )
64 : {
65 124 : }
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 36 : void GetBool( std::vector< com::sun::star::beans::PropertyValue >& rDest,
76 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
77 : {
78 : bool bAttrBool;
79 36 : if (::sax::Converter::convertBool( bAttrBool, rValue ))
80 : {
81 36 : beans::PropertyValue aProp;
82 36 : aProp.Name = EASGet( eDestProp );
83 36 : aProp.Value <<= bAttrBool;
84 36 : rDest.push_back( aProp );
85 : }
86 36 : }
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 124 : void GetString( std::vector< com::sun::star::beans::PropertyValue >& rDest,
131 : const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
132 : {
133 124 : beans::PropertyValue aProp;
134 124 : aProp.Name = EASGet( eDestProp );
135 124 : aProp.Value <<= rValue;
136 124 : rDest.push_back( aProp );
137 124 : }
138 :
139 4 : 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 4 : if( SvXMLUnitConverter::convertEnum( eKind, rValue, &rMap ) )
145 : {
146 4 : sal_Int16 nEnum = (sal_Int16)eKind;
147 4 : beans::PropertyValue aProp;
148 4 : aProp.Name = EASGet( eDestProp );
149 4 : aProp.Value <<= nEnum;
150 4 : rDest.push_back( aProp );
151 : }
152 4 : }
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 3040 : sal_Bool GetEquationName( const rtl::OUString& rEquation, const sal_Int32 nStart, rtl::OUString& rEquationName )
189 : {
190 3040 : sal_Int32 nIndex = nStart;
191 12942 : while( nIndex < rEquation.getLength() )
192 : {
193 9768 : sal_Unicode nChar = rEquation[ nIndex ];
194 9768 : if (
195 : ( ( nChar >= 'a' ) && ( nChar <= 'z' ) )
196 : || ( ( nChar >= 'A' ) && ( nChar <= 'Z' ) )
197 : || ( ( nChar >= '0' ) && ( nChar <= '9' ) )
198 : )
199 : {
200 6862 : nIndex++;
201 : }
202 : else
203 2906 : break;
204 : }
205 3040 : sal_Bool bValid = ( nIndex - nStart ) != 0;
206 3040 : if ( bValid )
207 3040 : rEquationName = rEquation.copy( nStart, nIndex - nStart );
208 3040 : return bValid;
209 : }
210 :
211 7280 : sal_Bool GetNextParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, sal_Int32& nIndex, const rtl::OUString& rParaString )
212 : {
213 7280 : if ( nIndex >= rParaString.getLength() )
214 256 : return sal_False;
215 :
216 7024 : sal_Bool bValid = sal_True;
217 7024 : sal_Bool bNumberRequired = sal_True;
218 7024 : sal_Bool bMustBePositiveWholeNumbered = sal_False;
219 :
220 7024 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL;
221 7024 : if ( rParaString[ nIndex ] == (sal_Unicode)'$' )
222 : {
223 96 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT;
224 96 : bMustBePositiveWholeNumbered = sal_True;
225 96 : nIndex++;
226 : }
227 6928 : else if ( rParaString[ nIndex ] == (sal_Unicode)'?' )
228 : {
229 2106 : nIndex++;
230 2106 : bNumberRequired = sal_False;
231 2106 : rtl::OUString aEquationName;
232 2106 : bValid = GetEquationName( rParaString, nIndex, aEquationName );
233 2106 : if ( bValid )
234 : {
235 2106 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION;
236 2106 : rParameter.Value <<= aEquationName;
237 2106 : nIndex += aEquationName.getLength();
238 2106 : }
239 : }
240 4822 : else if ( rParaString[ nIndex ] > (sal_Unicode)'9' )
241 : {
242 50 : bNumberRequired = sal_False;
243 50 : if ( rParaString.matchIgnoreAsciiCaseAsciiL( "left", 4, nIndex ) )
244 : {
245 16 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT;
246 16 : nIndex += 4;
247 : }
248 34 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "top", 3, nIndex ) )
249 : {
250 26 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP;
251 26 : nIndex += 3;
252 : }
253 8 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "right", 5, nIndex ) )
254 : {
255 4 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT;
256 4 : nIndex += 5;
257 : }
258 4 : else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "bottom", 6, nIndex ) )
259 : {
260 4 : rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM;
261 4 : 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 7024 : if ( bValid )
307 : {
308 7024 : if ( bNumberRequired )
309 : {
310 4868 : sal_Int32 nStartIndex = nIndex;
311 4868 : sal_Int32 nEIndex = 0; // index of "E" in double
312 :
313 4868 : sal_Bool bE = sal_False; // set if a double is including a "E" statement
314 4868 : sal_Bool bENum = sal_False; // there is at least one number after "E"
315 4868 : sal_Bool bDot = sal_False; // set if there is a dot included
316 4868 : sal_Bool bEnd = sal_False; // set for each value that can not be part of a double/integer
317 :
318 27502 : while( ( nIndex < rParaString.getLength() ) && bValid )
319 : {
320 22192 : switch( rParaString[ nIndex ] )
321 : {
322 : case '.' :
323 : {
324 2 : if ( bMustBePositiveWholeNumbered )
325 0 : bValid = sal_False;
326 : else
327 : {
328 2 : if ( bDot )
329 0 : bValid = sal_False;
330 : else
331 2 : bDot = sal_True;
332 : }
333 : }
334 2 : break;
335 : case '-' :
336 : {
337 26 : if ( bMustBePositiveWholeNumbered )
338 0 : bValid = sal_False;
339 : else
340 : {
341 26 : if ( nStartIndex == nIndex )
342 26 : 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 26 : 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 17738 : if ( bE && ! bENum )
385 0 : bENum = sal_True;
386 : }
387 17738 : break;
388 : default:
389 4426 : bEnd = sal_True;
390 : }
391 22192 : if ( !bEnd )
392 17766 : nIndex++;
393 : else
394 4426 : break;
395 : }
396 4868 : if ( nIndex == nStartIndex )
397 0 : bValid = sal_False;
398 4868 : if ( bValid )
399 : {
400 4868 : rtl::OUString aNumber( rParaString.copy( nStartIndex, nIndex - nStartIndex ) );
401 4868 : if ( bE || bDot )
402 : {
403 : double fAttrDouble;
404 2 : if (::sax::Converter::convertDouble(fAttrDouble, aNumber))
405 2 : rParameter.Value <<= fAttrDouble;
406 : else
407 0 : bValid = sal_False;
408 : }
409 : else
410 : {
411 : sal_Int32 nValue;
412 4866 : if (::sax::Converter::convertNumber(nValue, aNumber))
413 4866 : rParameter.Value <<= nValue;
414 : else
415 0 : bValid = sal_False;
416 4868 : }
417 : }
418 : }
419 : }
420 7024 : if ( bValid )
421 : { // skipping white spaces
422 20520 : while( ( nIndex < rParaString.getLength() ) && rParaString[ nIndex ] == (sal_Unicode)' ' )
423 6472 : nIndex++;
424 : }
425 7024 : return bValid;
426 : }
427 :
428 2 : 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 2 : drawing::Position3D aPosition3D;
433 2 : if ( rUnitConverter.convertPosition3D( aPosition3D, rValue ) )
434 : {
435 2 : beans::PropertyValue aProp;
436 2 : aProp.Name = EASGet( eDestProp );
437 2 : aProp.Value <<= aPosition3D;
438 2 : rDest.push_back( aProp );
439 : }
440 2 : }
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 188 : 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 188 : sal_Int32 nIndex = 0;
479 188 : com::sun::star::drawing::EnhancedCustomShapeParameter aParameter;
480 188 : if ( GetNextParameter( aParameter, nIndex, rValue ) )
481 : {
482 188 : beans::PropertyValue aProp;
483 188 : aProp.Name = EASGet( eDestProp );
484 188 : aProp.Value <<= aParameter;
485 188 : rDest.push_back( aProp );
486 188 : }
487 188 : }
488 :
489 102 : 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 102 : sal_Int32 nIndex = 0;
493 102 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair;
494 204 : if ( GetNextParameter( aParameterPair.First, nIndex, rValue )
495 102 : && GetNextParameter( aParameterPair.Second, nIndex, rValue ) )
496 : {
497 102 : beans::PropertyValue aProp;
498 102 : aProp.Name = EASGet( eDestProp );
499 102 : aProp.Value <<= aParameterPair;
500 102 : rDest.push_back( aProp );
501 102 : }
502 102 : }
503 :
504 66 : 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 66 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vParameter;
508 66 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameter;
509 :
510 66 : sal_Int32 nIndex = 0;
511 808 : while ( GetNextParameter( aParameter.First, nIndex, rValue )
512 338 : && GetNextParameter( aParameter.Second, nIndex, rValue ) )
513 : {
514 338 : vParameter.push_back( aParameter );
515 : }
516 66 : if ( !vParameter.empty() )
517 : {
518 66 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aParameterSeq( vParameter.size() );
519 66 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aIter = vParameter.begin();
520 66 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aEnd = vParameter.end();
521 66 : com::sun::star::drawing::EnhancedCustomShapeParameterPair* pValues = aParameterSeq.getArray();
522 :
523 470 : while ( aIter != aEnd )
524 338 : *pValues++ = *aIter++;
525 :
526 66 : beans::PropertyValue aProp;
527 66 : aProp.Name = EASGet( eDestProp );
528 66 : aProp.Value <<= aParameterSeq;
529 66 : rDest.push_back( aProp );
530 : }
531 66 : return vParameter.size();
532 : }
533 :
534 104 : 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 104 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame > vTextFrame;
538 104 : com::sun::star::drawing::EnhancedCustomShapeTextFrame aParameter;
539 :
540 104 : sal_Int32 nIndex = 0;
541 :
542 632 : while ( GetNextParameter( aParameter.TopLeft.First, nIndex, rValue )
543 106 : && GetNextParameter( aParameter.TopLeft.Second, nIndex, rValue )
544 106 : && GetNextParameter( aParameter.BottomRight.First, nIndex, rValue )
545 106 : && GetNextParameter( aParameter.BottomRight.Second, nIndex, rValue ) )
546 : {
547 106 : vTextFrame.push_back( aParameter );
548 : }
549 104 : if ( !vTextFrame.empty() )
550 : {
551 104 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrameSeq( vTextFrame.size() );
552 104 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aIter = vTextFrame.begin();
553 104 : std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aEnd = vTextFrame.end();
554 104 : com::sun::star::drawing::EnhancedCustomShapeTextFrame* pValues = aTextFrameSeq.getArray();
555 :
556 314 : while ( aIter != aEnd )
557 106 : *pValues++ = *aIter++;
558 :
559 104 : beans::PropertyValue aProp;
560 104 : aProp.Name = EASGet( eDestProp );
561 104 : aProp.Value <<= aTextFrameSeq;
562 104 : rDest.push_back( aProp );
563 104 : }
564 104 : }
565 :
566 124 : void GetEnhancedPath( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:enhanced-path
567 : const rtl::OUString& rValue )
568 : {
569 124 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vCoordinates;
570 124 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment > vSegments;
571 :
572 124 : sal_Int32 nIndex = 0;
573 124 : sal_Int32 nParameterCount = 0;
574 :
575 124 : sal_Int32 nParametersNeeded = 1;
576 124 : sal_Int16 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
577 :
578 124 : sal_Bool bValid = sal_True;
579 :
580 5430 : while( bValid && ( nIndex < rValue.getLength() ) )
581 : {
582 5182 : switch( rValue[ nIndex ] )
583 : {
584 : case 'M' :
585 : {
586 280 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
587 280 : nParametersNeeded = 1;
588 280 : nIndex++;
589 : }
590 280 : break;
591 : case 'L' :
592 : {
593 248 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
594 248 : nParametersNeeded = 1;
595 248 : nIndex++;
596 : }
597 248 : break;
598 : case 'C' :
599 : {
600 104 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
601 104 : nParametersNeeded = 3;
602 104 : nIndex++;
603 : }
604 104 : break;
605 : case 'Z' :
606 : {
607 246 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
608 246 : nParametersNeeded = 0;
609 246 : nIndex++;
610 : }
611 246 : break;
612 : case 'N' :
613 : {
614 272 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
615 272 : nParametersNeeded = 0;
616 272 : nIndex++;
617 : }
618 272 : break;
619 : case 'F' :
620 : {
621 24 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL;
622 24 : nParametersNeeded = 0;
623 24 : nIndex++;
624 : }
625 24 : break;
626 : case 'S' :
627 : {
628 8 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE;
629 8 : nParametersNeeded = 0;
630 8 : nIndex++;
631 : }
632 8 : 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 20 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
643 20 : nParametersNeeded = 3;
644 20 : nIndex++;
645 : }
646 20 : 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 6 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC;
657 6 : nParametersNeeded = 4;
658 6 : nIndex++;
659 : }
660 6 : 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 2 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
671 2 : nParametersNeeded = 4;
672 2 : nIndex++;
673 : }
674 2 : break;
675 : case 'V' :
676 : {
677 2 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
678 2 : nParametersNeeded = 4;
679 2 : nIndex++;
680 : }
681 2 : break;
682 : case 'X' :
683 : {
684 38 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
685 38 : nParametersNeeded = 1;
686 38 : nIndex++;
687 : }
688 38 : break;
689 : case 'Y' :
690 : {
691 44 : nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
692 44 : nParametersNeeded = 1;
693 44 : nIndex++;
694 : }
695 44 : 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 1172 : nIndex++;
706 : }
707 1172 : 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 2716 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aPair;
725 5432 : if ( GetNextParameter( aPair.First, nIndex, rValue ) &&
726 2716 : GetNextParameter( aPair.Second, nIndex, rValue ) )
727 : {
728 2716 : vCoordinates.push_back( aPair );
729 2716 : nParameterCount++;
730 : }
731 : else
732 0 : bValid = sal_False;
733 : }
734 2716 : break;
735 : default:
736 0 : nIndex++;
737 0 : break;
738 : }
739 5182 : if ( !nParameterCount && !nParametersNeeded )
740 : {
741 550 : com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
742 550 : aSegment.Command = nLatestSegmentCommand;
743 550 : aSegment.Count = 0;
744 550 : vSegments.push_back( aSegment );
745 550 : nParametersNeeded = 0x7fffffff;
746 : }
747 4632 : else if ( nParameterCount >= nParametersNeeded )
748 : {
749 : // check if the last command is identical,
750 : // if so, we just need to increment the count
751 1782 : if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) )
752 1038 : vSegments[ vSegments.size() -1 ].Count++;
753 : else
754 : {
755 744 : com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
756 744 : aSegment.Command = nLatestSegmentCommand;
757 744 : aSegment.Count = 1;
758 744 : vSegments.push_back( aSegment );
759 : }
760 1782 : nParameterCount = 0;
761 : }
762 : }
763 : // adding the Coordinates property
764 124 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > seqCoordinates( vCoordinates.size() );
765 124 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesIter = vCoordinates.begin();
766 124 : std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesEnd = vCoordinates.end();
767 124 : com::sun::star::drawing::EnhancedCustomShapeParameterPair* pCoordinateValues = seqCoordinates.getArray();
768 :
769 2964 : while ( aCoordinatesIter != aCoordinatesEnd )
770 2716 : *pCoordinateValues++ = *aCoordinatesIter++;
771 :
772 124 : beans::PropertyValue aProp;
773 124 : aProp.Name = EASGet( EAS_Coordinates );
774 124 : aProp.Value <<= seqCoordinates;
775 124 : rDest.push_back( aProp );
776 :
777 :
778 : // adding the Segments property
779 124 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments( vSegments.size() );
780 124 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsIter = vSegments.begin();
781 124 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsEnd = vSegments.end();
782 124 : com::sun::star::drawing::EnhancedCustomShapeSegment* pSegmentValues = seqSegments.getArray();
783 :
784 1542 : while ( aSegmentsIter != aSegmentsEnd )
785 1294 : *pSegmentValues++ = *aSegmentsIter++;
786 :
787 124 : aProp.Name = EASGet( EAS_Segments );
788 124 : aProp.Value <<= seqSegments;
789 124 : rDest.push_back( aProp );
790 124 : }
791 :
792 86 : void GetAdjustmentValues( std::vector< com::sun::star::beans::PropertyValue >& rDest, // draw:adjustments
793 : const rtl::OUString& rValue )
794 : {
795 86 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > vAdjustmentValue;
796 86 : com::sun::star::drawing::EnhancedCustomShapeParameter aParameter;
797 86 : sal_Int32 nIndex = 0;
798 268 : while ( GetNextParameter( aParameter, nIndex, rValue ) )
799 : {
800 96 : com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue aAdj;
801 96 : if ( aParameter.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL )
802 : {
803 96 : aAdj.Value <<= aParameter.Value;
804 96 : 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 96 : vAdjustmentValue.push_back( aAdj );
810 96 : }
811 :
812 86 : sal_Int32 nAdjustmentValues = vAdjustmentValue.size();
813 86 : if ( nAdjustmentValues )
814 : {
815 86 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( nAdjustmentValues );
816 86 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aIter = vAdjustmentValue.begin();
817 86 : std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aEnd = vAdjustmentValue.end();
818 86 : com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue* pValues = aAdjustmentValues.getArray();
819 :
820 268 : while ( aIter != aEnd )
821 96 : *pValues++ = *aIter++;
822 :
823 86 : beans::PropertyValue aProp;
824 86 : aProp.Name = EASGet( EAS_AdjustmentValues );
825 86 : aProp.Value <<= aAdjustmentValues;
826 86 : rDest.push_back( aProp );
827 86 : }
828 86 : }
829 :
830 124 : void XMLEnhancedCustomShapeContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
831 : {
832 124 : sal_Int16 nLength = xAttrList->getLength();
833 124 : if ( nLength )
834 : {
835 : sal_Int32 nAttrNumber;
836 842 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
837 : {
838 718 : rtl::OUString aLocalName;
839 718 : const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr );
840 718 : /* sven fixme, this must be checked! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
841 :
842 718 : switch( EASGet( aLocalName ) )
843 : {
844 : case EAS_type :
845 124 : GetString( mrCustomShapeGeometry, rValue, EAS_Type );
846 124 : break;
847 : case EAS_mirror_horizontal :
848 6 : GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredX );
849 6 : break;
850 : case EAS_mirror_vertical :
851 4 : GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredY );
852 4 : break;
853 : case EAS_viewBox :
854 : {
855 122 : SdXMLImExViewBox aViewBox( rValue, GetImport().GetMM100UnitConverter() );
856 122 : awt::Rectangle aRect( aViewBox.GetX(), aViewBox.GetY(), aViewBox.GetWidth(), aViewBox.GetHeight() );
857 122 : beans::PropertyValue aProp;
858 122 : aProp.Name = EASGet( EAS_ViewBox );
859 122 : aProp.Value <<= aRect;
860 122 : mrCustomShapeGeometry.push_back( aProp );
861 : }
862 122 : 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 2 : sal_Int32 nIndex = 0;
884 2 : com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair;
885 2 : com::sun::star::drawing::EnhancedCustomShapeParameter& rDepth = aParameterPair.First;
886 2 : com::sun::star::drawing::EnhancedCustomShapeParameter& rFraction = aParameterPair.Second;
887 2 : 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 2 : rValue, util::MeasureUnit::MM_100TH));
893 :
894 2 : rtl::OUStringBuffer aUnitStr;
895 : double fFactor = ::sax::Converter::GetConversionFactor(
896 2 : aUnitStr, util::MeasureUnit::MM_100TH, eSrcUnit);
897 2 : if ( ( fFactor != 1.0 ) && ( fFactor != 0.0 ) )
898 : {
899 2 : double fDepth(0.0);
900 2 : if ( rDepth.Value >>= fDepth )
901 : {
902 2 : fDepth /= fFactor;
903 2 : rDepth.Value <<= fDepth;
904 : }
905 : }
906 2 : if ( rValue.matchIgnoreAsciiCase( aUnitStr.toString(), nIndex ) )
907 2 : nIndex += aUnitStr.getLength();
908 :
909 : // skipping white spaces
910 6 : while( ( nIndex < rValue.getLength() ) && rValue[ nIndex ] == (sal_Unicode)' ' )
911 2 : nIndex++;
912 :
913 2 : if ( GetNextParameter( rFraction, nIndex, rValue ) )
914 : {
915 2 : beans::PropertyValue aProp;
916 2 : aProp.Name = EASGet( EAS_Depth );
917 2 : aProp.Value <<= aParameterPair;
918 2 : maExtrusion.push_back( aProp );
919 2 : }
920 2 : }
921 : }
922 2 : 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 2 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_Skew );
980 2 : break;
981 : case EAS_extrusion_specularity :
982 0 : GetDoublePercentage( maExtrusion, rValue, EAS_Specularity );
983 0 : break;
984 : case EAS_projection :
985 : {
986 2 : drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PERSPECTIVE );
987 2 : if( IsXMLToken( rValue, XML_PARALLEL ) )
988 0 : eProjectionMode = drawing::ProjectionMode_PARALLEL;
989 :
990 2 : beans::PropertyValue aProp;
991 2 : aProp.Name = EASGet( EAS_ProjectionMode );
992 2 : aProp.Value <<= eProjectionMode;
993 2 : maExtrusion.push_back( aProp );
994 : }
995 2 : break;
996 : case EAS_extrusion_viewpoint :
997 2 : GetPosition3D( maExtrusion, rValue, EAS_ViewPoint, mrUnitConverter );
998 2 : break;
999 : case EAS_extrusion_origin :
1000 2 : GetEnhancedParameterPair( maExtrusion, rValue, EAS_Origin );
1001 2 : break;
1002 : case EAS_extrusion_color :
1003 0 : GetBool( maExtrusion, rValue, EAS_Color );
1004 0 : break;
1005 : case EAS_enhanced_path :
1006 124 : GetEnhancedPath( maPath, rValue );
1007 124 : break;
1008 : case EAS_path_stretchpoint_x :
1009 : {
1010 36 : if (::sax::Converter::convertNumber(nAttrNumber, rValue))
1011 : {
1012 36 : beans::PropertyValue aProp;
1013 36 : aProp.Name = EASGet( EAS_StretchX );
1014 36 : aProp.Value <<= nAttrNumber;
1015 36 : maPath.push_back( aProp );
1016 : }
1017 : }
1018 36 : break;
1019 : case EAS_path_stretchpoint_y :
1020 : {
1021 32 : if (::sax::Converter::convertNumber(nAttrNumber, rValue))
1022 : {
1023 32 : beans::PropertyValue aProp;
1024 32 : aProp.Name = EASGet( EAS_StretchY );
1025 32 : aProp.Value <<= nAttrNumber;
1026 32 : maPath.push_back( aProp );
1027 : }
1028 : }
1029 32 : break;
1030 : case EAS_text_areas :
1031 104 : GetEnhancedRectangleSequence( maPath, rValue, EAS_TextFrames );
1032 104 : break;
1033 : case EAS_glue_points :
1034 : {
1035 66 : sal_Int32 i, nPairs = GetEnhancedParameterPairSequence( maPath, rValue, EAS_GluePoints );
1036 66 : GetImport().GetShapeImport()->moveGluePointMapping( mrxShape, nPairs );
1037 404 : for ( i = 0; i < nPairs; i++ )
1038 338 : GetImport().GetShapeImport()->addGluePointMapping( mrxShape, i + 4, i + 4 );
1039 : }
1040 66 : break;
1041 : case EAS_glue_point_type :
1042 4 : GetEnum( maPath, rValue, EAS_GluePointType, *aXML_GluePointEnumMap );
1043 4 : 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 86 : GetAdjustmentValues( mrCustomShapeGeometry, rValue );
1078 86 : break;
1079 : default:
1080 0 : break;
1081 : }
1082 718 : }
1083 : }
1084 124 : }
1085 :
1086 86 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1087 : const std::vector< beans::PropertyValues >& rElement,
1088 : const rtl::OUString& rElementName )
1089 : {
1090 86 : if ( !rElement.empty() )
1091 : {
1092 86 : uno::Sequence< beans::PropertyValues > aPropSeq( rElement.size() );
1093 86 : std::vector< beans::PropertyValues >::const_iterator aIter = rElement.begin();
1094 86 : std::vector< beans::PropertyValues >::const_iterator aEnd = rElement.end();
1095 86 : beans::PropertyValues* pValues = aPropSeq.getArray();
1096 :
1097 264 : while ( aIter != aEnd )
1098 92 : *pValues++ = *aIter++;
1099 :
1100 86 : beans::PropertyValue aProp;
1101 86 : aProp.Name = rElementName;
1102 86 : aProp.Value <<= aPropSeq;
1103 86 : rPropVec.push_back( aProp );
1104 : }
1105 86 : }
1106 :
1107 124 : void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec,
1108 : const std::vector< rtl::OUString >& rElement,
1109 : const rtl::OUString& rElementName )
1110 : {
1111 124 : if ( !rElement.empty() )
1112 : {
1113 86 : uno::Sequence< rtl::OUString > aPropSeq( rElement.size() );
1114 86 : std::vector< rtl::OUString >::const_iterator aIter = rElement.begin();
1115 86 : std::vector< rtl::OUString >::const_iterator aEnd = rElement.end();
1116 86 : rtl::OUString* pValues = aPropSeq.getArray();
1117 :
1118 1500 : while ( aIter != aEnd )
1119 1328 : *pValues++ = *aIter++;
1120 :
1121 86 : beans::PropertyValue aProp;
1122 86 : aProp.Name = rElementName;
1123 86 : aProp.Value <<= aPropSeq;
1124 86 : rPropVec.push_back( aProp );
1125 : }
1126 124 : }
1127 :
1128 372 : 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 372 : if ( !rElement.empty() )
1133 : {
1134 126 : uno::Sequence< beans::PropertyValue > aPropSeq( rElement.size() );
1135 126 : std::vector< beans::PropertyValue >::const_iterator aIter = rElement.begin();
1136 126 : std::vector< beans::PropertyValue >::const_iterator aEnd = rElement.end();
1137 126 : beans::PropertyValue* pValues = aPropSeq.getArray();
1138 :
1139 752 : while ( aIter != aEnd )
1140 500 : *pValues++ = *aIter++;
1141 :
1142 126 : beans::PropertyValue aProp;
1143 126 : aProp.Name = rElementName;
1144 126 : aProp.Value <<= aPropSeq;
1145 126 : rPropVec.push_back( aProp );
1146 : }
1147 372 : }
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 3944 : void CheckAndResolveEquationParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rPara, EquationHashMap* pH )
1154 : {
1155 3944 : if ( rPara.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION )
1156 : {
1157 2106 : rtl::OUString aEquationName;
1158 2106 : if ( rPara.Value >>= aEquationName )
1159 : {
1160 2106 : sal_Int32 nIndex = 0;
1161 2106 : EquationHashMap::iterator aHashIter( pH->find( aEquationName ) );
1162 2106 : if ( aHashIter != pH->end() )
1163 2106 : nIndex = (*aHashIter).second;
1164 2106 : rPara.Value <<= nIndex;
1165 2106 : }
1166 : }
1167 3944 : }
1168 :
1169 124 : void XMLEnhancedCustomShapeContext::EndElement()
1170 : {
1171 : // resolve properties that are indexing a Equation
1172 124 : if ( !maEquations.empty() )
1173 : {
1174 : // creating hash map containing the name and index of each equation
1175 86 : EquationHashMap* pH = new EquationHashMap;
1176 86 : std::vector< rtl::OUString >::iterator aEquationNameIter = maEquationNames.begin();
1177 86 : std::vector< rtl::OUString >::iterator aEquationNameEnd = maEquationNames.end();
1178 1500 : while( aEquationNameIter != aEquationNameEnd )
1179 : {
1180 1328 : (*pH)[ *aEquationNameIter ] = (sal_Int32)( aEquationNameIter - maEquationNames.begin() );
1181 1328 : ++aEquationNameIter;
1182 : }
1183 :
1184 : // resolve equation
1185 86 : std::vector< rtl::OUString >::iterator aEquationIter = maEquations.begin();
1186 86 : std::vector< rtl::OUString >::iterator aEquationEnd = maEquations.end();
1187 1500 : while( aEquationIter != aEquationEnd )
1188 : {
1189 1328 : sal_Int32 nIndexOf = 0;
1190 2262 : do
1191 : {
1192 2262 : nIndexOf = aEquationIter->indexOf( '?', nIndexOf );
1193 2262 : if ( nIndexOf != -1 )
1194 : {
1195 934 : rtl::OUString aEquationName;
1196 934 : if ( GetEquationName( *aEquationIter, nIndexOf + 1, aEquationName ) )
1197 : {
1198 : // copying first characters inclusive '?'
1199 934 : rtl::OUString aNew( aEquationIter->copy( 0, nIndexOf + 1 ) );
1200 934 : sal_Int32 nIndex = 0;
1201 934 : EquationHashMap::iterator aHashIter( pH->find( aEquationName ) );
1202 934 : if ( aHashIter != pH->end() )
1203 934 : nIndex = (*aHashIter).second;
1204 934 : aNew += rtl::OUString::valueOf( nIndex );
1205 934 : aNew += aEquationIter->copy( nIndexOf + aEquationName.getLength() + 1 );
1206 934 : *aEquationIter = aNew;
1207 : }
1208 934 : nIndexOf++;
1209 : }
1210 : }
1211 : while( nIndexOf != -1 );
1212 1328 : ++aEquationIter;
1213 : }
1214 :
1215 : // Path
1216 : sal_Int32 i;
1217 86 : std::vector< beans::PropertyValue >::iterator aPathIter = maPath.begin();
1218 86 : std::vector< beans::PropertyValue >::iterator aPathEnd = maPath.end();
1219 550 : while ( aPathIter != aPathEnd )
1220 : {
1221 378 : 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 138 : aPathIter->Value.getValue());
1229 1750 : for ( i = 0; i < rSeq.getLength(); i++ )
1230 : {
1231 1612 : CheckAndResolveEquationParameter( rSeq[ i ].First, pH );
1232 1612 : CheckAndResolveEquationParameter( rSeq[ i ].Second, pH );
1233 : }
1234 : }
1235 138 : break;
1236 : case EAS_TextFrames :
1237 : {
1238 : uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >& rSeq =
1239 : *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >*)
1240 82 : aPathIter->Value.getValue());
1241 166 : for ( i = 0; i < rSeq.getLength(); i++ )
1242 : {
1243 84 : CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.First, pH );
1244 84 : CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.Second, pH );
1245 84 : CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.First, pH );
1246 84 : CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.Second, pH );
1247 : }
1248 : }
1249 82 : break;
1250 : default:
1251 158 : break;
1252 : }
1253 378 : ++aPathIter;
1254 : }
1255 86 : std::vector< beans::PropertyValues >::iterator aHandleIter = maHandles.begin();
1256 86 : std::vector< beans::PropertyValues >::iterator aHandleEnd = maHandles.end();
1257 264 : while ( aHandleIter != aHandleEnd )
1258 : {
1259 92 : beans::PropertyValue* pValues = aHandleIter->getArray();
1260 404 : for ( i = 0; i < aHandleIter->getLength(); i++ )
1261 : {
1262 312 : 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 188 : pValues->Value.getValue()), pH );
1273 : }
1274 188 : break;
1275 :
1276 : case EAS_Position :
1277 : case EAS_Polar :
1278 : {
1279 : CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*)
1280 98 : pValues->Value.getValue())).First, pH );
1281 : CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*)
1282 98 : pValues->Value.getValue())).Second, pH );
1283 : }
1284 98 : break;
1285 : default:
1286 26 : break;
1287 : }
1288 312 : pValues++;
1289 : }
1290 92 : ++aHandleIter;
1291 : }
1292 86 : delete pH;
1293 : }
1294 :
1295 124 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maExtrusion, EASGet( EAS_Extrusion ) );
1296 124 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maPath, EASGet( EAS_Path ) );
1297 124 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maTextPath, EASGet( EAS_TextPath ) );
1298 124 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maEquations, EASGet( EAS_Equations ) );
1299 124 : if ( !maHandles.empty() )
1300 86 : SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maHandles, EASGet( EAS_Handles ) );
1301 124 : }
1302 :
1303 1420 : SvXMLImportContext* XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt16 nPrefix,const rtl::OUString& rLocalName,
1304 : const uno::Reference< xml::sax::XAttributeList> & xAttrList )
1305 : {
1306 1420 : EnhancedCustomShapeTokenEnum aTokenEnum = EASGet( rLocalName );
1307 1420 : if ( aTokenEnum == EAS_equation )
1308 : {
1309 1328 : sal_Int16 nLength = xAttrList->getLength();
1310 1328 : if ( nLength )
1311 : {
1312 1328 : rtl::OUString aFormula;
1313 1328 : rtl::OUString aFormulaName;
1314 3984 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
1315 : {
1316 2656 : rtl::OUString aLocalName;
1317 2656 : const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr );
1318 2656 : /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
1319 :
1320 2656 : switch( EASGet( aLocalName ) )
1321 : {
1322 : case EAS_formula :
1323 1328 : aFormula = rValue;
1324 1328 : break;
1325 : case EAS_name :
1326 1328 : aFormulaName = rValue;
1327 1328 : break;
1328 : default:
1329 0 : break;
1330 : }
1331 2656 : }
1332 1328 : if ( !aFormulaName.isEmpty() || !aFormula.isEmpty() )
1333 : {
1334 1328 : maEquations.push_back( aFormula );
1335 1328 : maEquationNames.push_back( aFormulaName );
1336 1328 : }
1337 : }
1338 : }
1339 92 : else if ( aTokenEnum == EAS_handle )
1340 : {
1341 92 : std::vector< com::sun::star::beans::PropertyValue > aHandle;
1342 92 : const sal_Int16 nLength = xAttrList->getLength();
1343 404 : for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
1344 : {
1345 312 : rtl::OUString aLocalName;
1346 312 : const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr );
1347 312 : /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName );
1348 312 : 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 26 : GetBool( aHandle, rValue, EAS_Switched );
1358 26 : break;
1359 : case EAS_handle_position :
1360 92 : GetEnhancedParameterPair( aHandle, rValue, EAS_Position );
1361 92 : break;
1362 : case EAS_handle_range_x_minimum :
1363 54 : GetEnhancedParameter( aHandle, rValue, EAS_RangeXMinimum );
1364 54 : break;
1365 : case EAS_handle_range_x_maximum :
1366 54 : GetEnhancedParameter( aHandle, rValue, EAS_RangeXMaximum );
1367 54 : break;
1368 : case EAS_handle_range_y_minimum :
1369 34 : GetEnhancedParameter( aHandle, rValue, EAS_RangeYMinimum );
1370 34 : break;
1371 : case EAS_handle_range_y_maximum :
1372 34 : GetEnhancedParameter( aHandle, rValue, EAS_RangeYMaximum );
1373 34 : break;
1374 : case EAS_handle_polar :
1375 6 : GetEnhancedParameterPair( aHandle, rValue, EAS_Polar );
1376 6 : break;
1377 : case EAS_handle_radius_range_minimum :
1378 6 : GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMinimum );
1379 6 : break;
1380 : case EAS_handle_radius_range_maximum :
1381 6 : GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMaximum );
1382 6 : break;
1383 : default:
1384 0 : break;
1385 : }
1386 312 : }
1387 92 : beans::PropertyValues aPropSeq( aHandle.size() );
1388 92 : std::vector< beans::PropertyValue >::const_iterator aIter = aHandle.begin();
1389 92 : std::vector< beans::PropertyValue >::const_iterator aEnd = aHandle.end();
1390 92 : beans::PropertyValue* pValues = aPropSeq.getArray();
1391 :
1392 496 : while ( aIter != aEnd )
1393 312 : *pValues++ = *aIter++;
1394 :
1395 92 : maHandles.push_back( aPropSeq );
1396 : }
1397 1420 : return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
1398 : }
1399 :
1400 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|