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