xref: /trunk/main/xmloff/source/draw/shapeexport4.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include <com/sun/star/graphic/XGraphic.hpp>
32 #include <com/sun/star/graphic/XGraphicProvider.hpp>
33 #include <com/sun/star/embed/ElementModes.hpp>
34 #include <com/sun/star/embed/XTransactedObject.hpp>
35 #include <com/sun/star/io/XSeekableInputStream.hpp>
36 #include <com/sun/star/drawing/HomogenMatrix.hpp>
37 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
38 #include <com/sun/star/drawing/ProjectionMode.hpp>
39 #include <com/sun/star/drawing/ShadeMode.hpp>
40 #include <com/sun/star/drawing/Direction3D.hpp>
41 #include <com/sun/star/drawing/Position3D.hpp>
42 #include <com/sun/star/drawing/CameraGeometry.hpp>
43 #include <com/sun/star/drawing/DoubleSequence.hpp>
44 
45 #include <com/sun/star/table/XColumnRowRange.hpp>
46 
47 #ifndef _XMLOFF_SHAPEEXPORT_HXX
48 #include <xmloff/shapeexport.hxx>
49 #endif
50 #include "sdpropls.hxx"
51 #include <tools/debug.hxx>
52 #include <rtl/ustrbuf.hxx>
53 #include <xmloff/xmlexp.hxx>
54 #include <xmloff/xmluconv.hxx>
55 #include "xexptran.hxx"
56 #include <xmloff/xmltoken.hxx>
57 #include "EnhancedCustomShapeToken.hxx"
58 #include <com/sun/star/container/XIdentifierContainer.hpp>
59 #include <com/sun/star/drawing/ShadeMode.hpp>
60 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
61 #ifndef _COM_SUN_STAR_DRAWING_ENHANCEDCUSTOMSHAPEPARAMETERPARI_HPP_
62 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
63 #endif
64 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
65 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
66 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
67 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
68 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
69 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
70 #include <com/sun/star/beans/PropertyValues.hpp>
71 #include <rtl/math.hxx>
72 #include <tools/string.hxx>
73 #include <basegfx/vector/b3dvector.hxx>
74 
75 #include "xmloff/xmlnmspe.hxx"
76 #include "XMLBase64Export.hxx"
77 
78 using ::rtl::OUString;
79 using ::rtl::OUStringBuffer;
80 
81 using namespace ::com::sun::star;
82 using namespace ::com::sun::star::io;
83 using namespace ::xmloff::token;
84 using namespace ::xmloff::EnhancedCustomShapeToken;
85 
86 using ::com::sun::star::embed::XStorage;
87 using ::com::sun::star::uno::UNO_QUERY;
88 using ::com::sun::star::uno::UNO_QUERY_THROW;
89 using ::com::sun::star::uno::Reference;
90 using ::com::sun::star::uno::Sequence;
91 
92 //////////////////////////////////////////////////////////////////////////////
93 
94 void ExportParameter( rtl::OUStringBuffer& rStrBuffer, const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter )
95 {
96     if ( rStrBuffer.getLength() )
97         rStrBuffer.append( (sal_Unicode)' ' );
98     if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
99     {
100         double fNumber = 0.0;
101         rParameter.Value >>= fNumber;
102         ::rtl::math::doubleToUStringBuffer( rStrBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', sal_True );
103     }
104     else
105     {
106         sal_Int32 nValue = 0;
107         rParameter.Value >>= nValue;
108 
109         switch( rParameter.Type )
110         {
111             case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
112             {
113                 rStrBuffer.append( (sal_Unicode)'?' );
114                 rStrBuffer.append( (sal_Unicode)'f' );
115                 rStrBuffer.append( rtl::OUString::valueOf( nValue ) );
116             }
117             break;
118 
119             case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
120             {
121                 rStrBuffer.append( (sal_Unicode)'$' );
122                 rStrBuffer.append( rtl::OUString::valueOf( nValue ) );
123             }
124             break;
125 
126             case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM :
127                 rStrBuffer.append( GetXMLToken( XML_BOTTOM ) ); break;
128             case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT :
129                 rStrBuffer.append( GetXMLToken( XML_RIGHT ) ); break;
130             case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP :
131                 rStrBuffer.append( GetXMLToken( XML_TOP ) ); break;
132             case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT :
133                 rStrBuffer.append( GetXMLToken( XML_LEFT ) ); break;
134             case com::sun::star::drawing::EnhancedCustomShapeParameterType::XSTRETCH :
135                 rStrBuffer.append( GetXMLToken( XML_XSTRETCH ) ); break;
136             case com::sun::star::drawing::EnhancedCustomShapeParameterType::YSTRETCH :
137                 rStrBuffer.append( GetXMLToken( XML_YSTRETCH ) ); break;
138             case com::sun::star::drawing::EnhancedCustomShapeParameterType::HASSTROKE :
139                 rStrBuffer.append( GetXMLToken( XML_HASSTROKE ) ); break;
140             case com::sun::star::drawing::EnhancedCustomShapeParameterType::HASFILL :
141                 rStrBuffer.append( GetXMLToken( XML_HASFILL ) ); break;
142             case com::sun::star::drawing::EnhancedCustomShapeParameterType::WIDTH :
143                 rStrBuffer.append( GetXMLToken( XML_WIDTH ) ); break;
144             case com::sun::star::drawing::EnhancedCustomShapeParameterType::HEIGHT :
145                 rStrBuffer.append( GetXMLToken( XML_HEIGHT ) ); break;
146             case com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGWIDTH :
147                 rStrBuffer.append( GetXMLToken( XML_LOGWIDTH ) ); break;
148             case com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT :
149                 rStrBuffer.append( GetXMLToken( XML_LOGHEIGHT ) ); break;
150             default :
151                 rStrBuffer.append( rtl::OUString::valueOf( nValue ) );
152         }
153     }
154 }
155 
156 void ImpExportEquations( SvXMLExport& rExport, const uno::Sequence< rtl::OUString >& rEquations )
157 {
158     sal_Int32 i;
159     for ( i = 0; i < rEquations.getLength(); i++ )
160     {
161         rtl::OUString aStr( String( 'f' ) );
162         aStr += rtl::OUString::valueOf( i );
163         rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aStr );
164 
165         aStr = rEquations[ i ];
166         sal_Int32 nIndex = 0;
167         do
168         {
169             nIndex = aStr.indexOf( (sal_Unicode)'?', nIndex );
170             if ( nIndex != -1 )
171             {
172                 rtl::OUString aNew( aStr.copy( 0, nIndex + 1 ) );
173                 aNew += String( 'f' );
174                 aNew += aStr.copy( nIndex + 1, ( aStr.getLength() - nIndex ) - 1 );
175                 aStr = aNew;
176                 nIndex++;
177             }
178         } while( nIndex != -1 );
179         rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FORMULA, aStr );
180         SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_EQUATION, sal_True, sal_True );
181     }
182 }
183 
184 void ImpExportHandles( SvXMLExport& rExport, const uno::Sequence< beans::PropertyValues >& rHandles )
185 {
186     sal_uInt32 i, j, nElements = rHandles.getLength();
187     if ( nElements )
188     {
189         rtl::OUString       aStr;
190         rtl::OUStringBuffer aStrBuffer;
191 
192         for ( i = 0; i < nElements; i++ )
193         {
194             sal_Bool bPosition = sal_False;
195             const uno::Sequence< beans::PropertyValue >& rPropSeq = rHandles[ i ];
196             for ( j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
197             {
198                 const beans::PropertyValue& rPropVal = rPropSeq[ j ];
199                 switch( EASGet( rPropVal.Name ) )
200                 {
201                     case EAS_Position :
202                     {
203                         com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
204                         if ( rPropVal.Value >>= aPosition )
205                         {
206                             ExportParameter( aStrBuffer, aPosition.First );
207                             ExportParameter( aStrBuffer, aPosition.Second );
208                             aStr = aStrBuffer.makeStringAndClear();
209                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POSITION, aStr );
210                             bPosition = sal_True;
211                         }
212                     }
213                     break;
214                     case EAS_MirroredX :
215                     {
216                         sal_Bool bMirroredX = sal_Bool();
217                         if ( rPropVal.Value >>= bMirroredX )
218                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_HORIZONTAL,
219                                 bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
220                     }
221                     break;
222                     case EAS_MirroredY :
223                     {
224                         sal_Bool bMirroredY = sal_Bool();
225                         if ( rPropVal.Value >>= bMirroredY )
226                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_VERTICAL,
227                                 bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
228                     }
229                     break;
230                     case EAS_Switched :
231                     {
232                         sal_Bool bSwitched = sal_Bool();
233                         if ( rPropVal.Value >>= bSwitched )
234                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_SWITCHED,
235                                 bSwitched ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
236                     }
237                     break;
238                     case EAS_Polar :
239                     {
240                         com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar;
241                         if ( rPropVal.Value >>= aPolar )
242                         {
243                             ExportParameter( aStrBuffer, aPolar.First );
244                             ExportParameter( aStrBuffer, aPolar.Second );
245                             aStr = aStrBuffer.makeStringAndClear();
246                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POLAR, aStr );
247                         }
248                     }
249                     break;
250                     case EAS_RadiusRangeMinimum :
251                     {
252                         com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
253                         if ( rPropVal.Value >>= aRadiusRangeMinimum )
254                         {
255                             ExportParameter( aStrBuffer, aRadiusRangeMinimum );
256                             aStr = aStrBuffer.makeStringAndClear();
257                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MINIMUM, aStr );
258                         }
259                     }
260                     break;
261                     case EAS_RadiusRangeMaximum :
262                     {
263                         com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
264                         if ( rPropVal.Value >>= aRadiusRangeMaximum )
265                         {
266                             ExportParameter( aStrBuffer, aRadiusRangeMaximum );
267                             aStr = aStrBuffer.makeStringAndClear();
268                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MAXIMUM, aStr );
269                         }
270                     }
271                     break;
272                     case EAS_RangeXMinimum :
273                     {
274                         com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
275                         if ( rPropVal.Value >>= aXRangeMinimum )
276                         {
277                             ExportParameter( aStrBuffer, aXRangeMinimum );
278                             aStr = aStrBuffer.makeStringAndClear();
279                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MINIMUM, aStr );
280                         }
281                     }
282                     break;
283                     case EAS_RangeXMaximum :
284                     {
285                         com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
286                         if ( rPropVal.Value >>= aXRangeMaximum )
287                         {
288                             ExportParameter( aStrBuffer, aXRangeMaximum );
289                             aStr = aStrBuffer.makeStringAndClear();
290                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MAXIMUM, aStr );
291                         }
292                     }
293                     break;
294                     case EAS_RangeYMinimum :
295                     {
296                         com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
297                         if ( rPropVal.Value >>= aYRangeMinimum )
298                         {
299                             ExportParameter( aStrBuffer, aYRangeMinimum );
300                             aStr = aStrBuffer.makeStringAndClear();
301                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MINIMUM, aStr );
302                         }
303                     }
304                     break;
305                     case EAS_RangeYMaximum :
306                     {
307                         com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
308                         if ( rPropVal.Value >>= aYRangeMaximum )
309                         {
310                             ExportParameter( aStrBuffer, aYRangeMaximum );
311                             aStr = aStrBuffer.makeStringAndClear();
312                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MAXIMUM, aStr );
313                         }
314                     }
315                     break;
316                     default:
317                         break;
318                 }
319             }
320             if ( bPosition )
321                 SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_HANDLE, sal_True, sal_True );
322             else
323                 rExport.ClearAttrList();
324         }
325     }
326 }
327 
328 void ImpExportEnhancedPath( SvXMLExport& rExport,
329     const uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rCoordinates,
330         const uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments )
331 {
332 
333     rtl::OUString       aStr;
334     rtl::OUStringBuffer aStrBuffer;
335 
336     sal_Int32 i, j, k, l;
337 
338     sal_Int32 nCoords = rCoordinates.getLength();
339     sal_Int32 nSegments = rSegments.getLength();
340     sal_Bool bSimpleSegments = nSegments == 0;
341     if ( bSimpleSegments )
342         nSegments = 4;
343     for ( j = i = 0; j < nSegments; j++ )
344     {
345         com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
346         if ( bSimpleSegments )
347         {
348             // if there are not enough segments we will default them
349             switch( j )
350             {
351                 case 0 :
352                 {
353                     aSegment.Count = 1;
354                     aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
355                 }
356                 break;
357                 case 1 :
358                 {
359                     aSegment.Count = (sal_Int16)Min( nCoords - 1, (sal_Int32)32767 );
360                     aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
361                 }
362                 break;
363                 case 2 :
364                 {
365                     aSegment.Count = 1;
366                     aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
367                 }
368                 break;
369                 case 3 :
370                 {
371                     aSegment.Count = 1;
372                     aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
373                 }
374                 break;
375             }
376         }
377         else
378             aSegment = rSegments[ j ];
379 
380         if ( aStrBuffer.getLength() )
381             aStrBuffer.append( (sal_Unicode)' ' );
382 
383         sal_Int32 nParameter = 0;
384         switch( aSegment.Command )
385         {
386             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
387                 aStrBuffer.append( (sal_Unicode)'Z' ); break;
388             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
389                 aStrBuffer.append( (sal_Unicode)'N' ); break;
390             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
391                 aStrBuffer.append( (sal_Unicode)'F' ); break;
392             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
393                 aStrBuffer.append( (sal_Unicode)'S' ); break;
394 
395             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
396                 aStrBuffer.append( (sal_Unicode)'M' ); nParameter = 1; break;
397             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO :
398                 aStrBuffer.append( (sal_Unicode)'L' ); nParameter = 1; break;
399             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
400                 aStrBuffer.append( (sal_Unicode)'C' ); nParameter = 3; break;
401             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
402                 aStrBuffer.append( (sal_Unicode)'T' ); nParameter = 3; break;
403             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
404                 aStrBuffer.append( (sal_Unicode)'U' ); nParameter = 3; break;
405             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
406                 aStrBuffer.append( (sal_Unicode)'A' ); nParameter = 4; break;
407             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC :
408                 aStrBuffer.append( (sal_Unicode)'B' ); nParameter = 4; break;
409             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
410                 aStrBuffer.append( (sal_Unicode)'W' ); nParameter = 4; break;
411             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
412                 aStrBuffer.append( (sal_Unicode)'V' ); nParameter = 4; break;
413             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
414                 aStrBuffer.append( (sal_Unicode)'X' ); nParameter = 1; break;
415             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
416                 aStrBuffer.append( (sal_Unicode)'Y' ); nParameter = 1; break;
417             case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
418                 aStrBuffer.append( (sal_Unicode)'Q' ); nParameter = 2; break;
419 
420             default : // ups, seems to be something wrong
421             {
422                 aSegment.Count = 1;
423                 aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
424             }
425             break;
426         }
427         if ( nParameter )
428         {
429             for ( k = 0; k < aSegment.Count; k++ )
430             {
431                 if ( ( i + nParameter ) <= nCoords )
432                 {
433                     for ( l = 0; l < nParameter; l++ )
434                     {
435                         ExportParameter( aStrBuffer, rCoordinates[ i ].First );
436                         ExportParameter( aStrBuffer, rCoordinates[ i++ ].Second );
437                     }
438                 }
439                 else
440                 {
441                     j = nSegments;  // error -> exiting
442                     break;
443                 }
444             }
445         }
446     }
447     aStr = aStrBuffer.makeStringAndClear();
448     rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ENHANCED_PATH, aStr );
449 }
450 
451 void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Reference< beans::XPropertySet >& xPropSet )
452 {
453     sal_Bool bEquations = sal_False;
454     uno::Sequence< rtl::OUString > aEquations;
455 
456     sal_Bool bHandles = sal_False;
457     uno::Sequence< beans::PropertyValues > aHandles;
458 
459     sal_Bool bCoordinates = sal_False;
460     uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
461     uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
462 
463     uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues;
464 
465     rtl::OUString       aStr;
466     rtl::OUStringBuffer aStrBuffer;
467     SvXMLUnitConverter& rUnitConverter = rExport.GetMM100UnitConverter();
468 
469     uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
470 
471     // geometry
472     const rtl::OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) );
473     if ( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( sCustomShapeGeometry ) )
474     {
475         uno::Any aGeoPropSet( xPropSet->getPropertyValue( sCustomShapeGeometry ) );
476         uno::Sequence< beans::PropertyValue > aGeoPropSeq;
477 
478         if ( aGeoPropSet >>= aGeoPropSeq )
479         {
480             const rtl::OUString sCustomShapeType( RTL_CONSTASCII_USTRINGPARAM( "NonPrimitive" ) );
481             rtl::OUString aCustomShapeType( sCustomShapeType );
482 
483             sal_Int32 j, nGeoPropCount = aGeoPropSeq.getLength();
484             for ( j = 0; j < nGeoPropCount; j++ )
485             {
486                 const beans::PropertyValue& rGeoProp = aGeoPropSeq[ j ];
487                 switch( EASGet( rGeoProp.Name ) )
488                 {
489                     case EAS_Type :
490                     {
491                         rGeoProp.Value >>= aCustomShapeType;
492                     }
493                     break;
494                     case EAS_MirroredX :
495                     {
496                         sal_Bool bMirroredX = sal_Bool();
497                         if ( rGeoProp.Value >>= bMirroredX )
498                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_HORIZONTAL,
499                                 bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
500                     }
501                     break;
502                     case EAS_MirroredY :
503                     {
504                         sal_Bool bMirroredY = sal_Bool();
505                         if ( rGeoProp.Value >>= bMirroredY )
506                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_VERTICAL,
507                                 bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
508                     }
509                     break;
510                     case EAS_ViewBox :
511                     {
512                         awt::Rectangle aRect;
513                         if ( rGeoProp.Value >>= aRect )
514                         {
515                             SdXMLImExViewBox aViewBox( aRect.X, aRect.Y, aRect.Width, aRect.Height );
516                             rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() );
517                         }
518                     }
519                     break;
520                     case EAS_TextRotateAngle :
521                     {
522                         double fTextRotateAngle = 0;
523                         if ( rGeoProp.Value >>= fTextRotateAngle )
524                         {
525                             rUnitConverter.convertDouble( aStrBuffer, fTextRotateAngle );
526                             aStr = aStrBuffer.makeStringAndClear();
527                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_ROTATE_ANGLE, aStr );
528                         }
529                     }
530                     break;
531                     case EAS_Extrusion :
532                     {
533                         uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
534                         if ( rGeoProp.Value >>= aExtrusionPropSeq )
535                         {
536                             sal_Int32 i, nCount = aExtrusionPropSeq.getLength();
537                             for ( i = 0; i < nCount; i++ )
538                             {
539                                 const beans::PropertyValue& rProp = aExtrusionPropSeq[ i ];
540                                 switch( EASGet( rProp.Name ) )
541                                 {
542                                     case EAS_Extrusion :
543                                     {
544                                         sal_Bool bExtrusionOn = sal_Bool();
545                                         if ( rProp.Value >>= bExtrusionOn )
546                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION,
547                                                 bExtrusionOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
548                                     }
549                                     break;
550                                     case EAS_Brightness :
551                                     {
552                                         double fExtrusionBrightness = 0;
553                                         if ( rProp.Value >>= fExtrusionBrightness )
554                                         {
555                                             rUnitConverter.convertDouble( aStrBuffer, fExtrusionBrightness, sal_False, MAP_RELATIVE, MAP_RELATIVE );
556                                             aStrBuffer.append( (sal_Unicode)'%' );
557                                             aStr = aStrBuffer.makeStringAndClear();
558                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_BRIGHTNESS, aStr );
559                                         }
560                                     }
561                                     break;
562                                     case EAS_Depth :
563                                     {
564                                         com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
565                                         if ( rProp.Value >>= aDepthParaPair )
566                                         {
567                                             double fDepth = 0;
568                                             if ( aDepthParaPair.First.Value >>= fDepth )
569                                             {
570                                                 rExport.GetMM100UnitConverter().convertDouble( aStrBuffer, fDepth, sal_True );
571                                                 ExportParameter( aStrBuffer, aDepthParaPair.Second );
572                                                 aStr = aStrBuffer.makeStringAndClear();
573                                                 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DEPTH, aStr );
574                                             }
575                                         }
576                                     }
577                                     break;
578                                     case EAS_Diffusion :
579                                     {
580                                         double fExtrusionDiffusion = 0;
581                                         if ( rProp.Value >>= fExtrusionDiffusion )
582                                         {
583                                             rUnitConverter.convertDouble( aStrBuffer, fExtrusionDiffusion, sal_False, MAP_RELATIVE, MAP_RELATIVE );
584                                             aStrBuffer.append( (sal_Unicode)'%' );
585                                             aStr = aStrBuffer.makeStringAndClear();
586                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DIFFUSION, aStr );
587                                         }
588                                     }
589                                     break;
590                                     case EAS_NumberOfLineSegments :
591                                     {
592                                         sal_Int32 nExtrusionNumberOfLineSegments = 0;
593                                         if ( rProp.Value >>= nExtrusionNumberOfLineSegments )
594                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS, rtl::OUString::valueOf( nExtrusionNumberOfLineSegments ) );
595                                     }
596                                     break;
597                                     case EAS_LightFace :
598                                     {
599                                         sal_Bool bExtrusionLightFace = sal_Bool();
600                                         if ( rProp.Value >>= bExtrusionLightFace )
601                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_LIGHT_FACE,
602                                                 bExtrusionLightFace ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
603                                     }
604                                     break;
605                                     case EAS_FirstLightHarsh :
606                                     {
607                                         sal_Bool bExtrusionFirstLightHarsh = sal_Bool();
608                                         if ( rProp.Value >>= bExtrusionFirstLightHarsh )
609                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_HARSH,
610                                                 bExtrusionFirstLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
611                                     }
612                                     break;
613                                     case EAS_SecondLightHarsh :
614                                     {
615                                         sal_Bool bExtrusionSecondLightHarsh = sal_Bool();
616                                         if ( rProp.Value >>= bExtrusionSecondLightHarsh )
617                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_HARSH,
618                                                 bExtrusionSecondLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
619                                     }
620                                     break;
621                                     case EAS_FirstLightLevel :
622                                     {
623                                         double fExtrusionFirstLightLevel = 0;
624                                         if ( rProp.Value >>= fExtrusionFirstLightLevel )
625                                         {
626                                             rUnitConverter.convertDouble( aStrBuffer, fExtrusionFirstLightLevel, sal_False, MAP_RELATIVE, MAP_RELATIVE );
627                                             aStrBuffer.append( (sal_Unicode)'%' );
628                                             aStr = aStrBuffer.makeStringAndClear();
629                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_LEVEL, aStr );
630                                         }
631                                     }
632                                     break;
633                                     case EAS_SecondLightLevel :
634                                     {
635                                         double fExtrusionSecondLightLevel = 0;
636                                         if ( rProp.Value >>= fExtrusionSecondLightLevel )
637                                         {
638                                             rUnitConverter.convertDouble( aStrBuffer, fExtrusionSecondLightLevel, sal_False, MAP_RELATIVE, MAP_RELATIVE );
639                                             aStrBuffer.append( (sal_Unicode)'%' );
640                                             aStr = aStrBuffer.makeStringAndClear();
641                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_LEVEL, aStr );
642                                         }
643                                     }
644                                     break;
645                                     case EAS_FirstLightDirection :
646                                     {
647                                         drawing::Direction3D aExtrusionFirstLightDirection;
648                                         if ( rProp.Value >>= aExtrusionFirstLightDirection )
649                                         {
650                                             ::basegfx::B3DVector aVec3D( aExtrusionFirstLightDirection.DirectionX, aExtrusionFirstLightDirection.DirectionY,
651                                                 aExtrusionFirstLightDirection.DirectionZ );
652                                             rUnitConverter.convertB3DVector( aStrBuffer, aVec3D );
653                                             aStr = aStrBuffer.makeStringAndClear();
654                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_DIRECTION, aStr );
655                                         }
656                                     }
657                                     break;
658                                     case EAS_SecondLightDirection :
659                                     {
660                                         drawing::Direction3D aExtrusionSecondLightDirection;
661                                         if ( rProp.Value >>= aExtrusionSecondLightDirection )
662                                         {
663                                             ::basegfx::B3DVector aVec3D( aExtrusionSecondLightDirection.DirectionX, aExtrusionSecondLightDirection.DirectionY,
664                                                 aExtrusionSecondLightDirection.DirectionZ );
665                                             rUnitConverter.convertB3DVector( aStrBuffer, aVec3D );
666                                             aStr = aStrBuffer.makeStringAndClear();
667                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_DIRECTION, aStr );
668                                         }
669                                     }
670                                     break;
671                                     case EAS_Metal :
672                                     {
673                                         sal_Bool bExtrusionMetal = sal_Bool();
674                                         if ( rProp.Value >>= bExtrusionMetal )
675                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_METAL,
676                                                 bExtrusionMetal ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
677                                     }
678                                     break;
679                                     case EAS_ShadeMode :
680                                     {
681                                         // shadeMode
682                                         drawing::ShadeMode eShadeMode;
683                                         if( rProp.Value >>= eShadeMode )
684                                         {
685                                             if( eShadeMode == drawing::ShadeMode_FLAT )
686                                                 aStr = GetXMLToken( XML_FLAT );
687                                             else if( eShadeMode == drawing::ShadeMode_PHONG )
688                                                 aStr = GetXMLToken( XML_PHONG );
689                                             else if( eShadeMode == drawing::ShadeMode_SMOOTH )
690                                                 aStr = GetXMLToken( XML_GOURAUD );
691                                             else
692                                                 aStr = GetXMLToken( XML_DRAFT );
693                                         }
694                                         else
695                                         {
696                                             // ShadeMode enum not there, write default
697                                             aStr = GetXMLToken( XML_FLAT);
698                                         }
699                                         rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr );
700                                     }
701                                     break;
702                                     case EAS_RotateAngle :
703                                     {
704                                         com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair;
705                                         if ( rProp.Value >>= aRotateAngleParaPair )
706                                         {
707                                             ExportParameter( aStrBuffer, aRotateAngleParaPair.First );
708                                             ExportParameter( aStrBuffer, aRotateAngleParaPair.Second );
709                                             aStr = aStrBuffer.makeStringAndClear();
710                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_ANGLE, aStr );
711                                         }
712                                     }
713                                     break;
714                                     case EAS_RotationCenter :
715                                     {
716                                         drawing::Direction3D aExtrusionRotationCenter;
717                                         if ( rProp.Value >>= aExtrusionRotationCenter )
718                                         {
719                                             ::basegfx::B3DVector aVec3D( aExtrusionRotationCenter.DirectionX, aExtrusionRotationCenter.DirectionY,
720                                                 aExtrusionRotationCenter.DirectionZ );
721                                             rUnitConverter.convertB3DVector( aStrBuffer, aVec3D );
722                                             aStr = aStrBuffer.makeStringAndClear();
723                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_CENTER, aStr );
724                                         }
725                                     }
726                                     break;
727                                     case EAS_Shininess :
728                                     {
729                                         double fExtrusionShininess = 0;
730                                         if ( rProp.Value >>= fExtrusionShininess )
731                                         {
732                                             rUnitConverter.convertDouble( aStrBuffer, fExtrusionShininess, sal_False, MAP_RELATIVE, MAP_RELATIVE );
733                                             aStrBuffer.append( (sal_Unicode)'%' );
734                                             aStr = aStrBuffer.makeStringAndClear();
735                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SHININESS, aStr );
736                                         }
737                                     }
738                                     break;
739                                     case EAS_Skew :
740                                     {
741                                         com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
742                                         if ( rProp.Value >>= aSkewParaPair )
743                                         {
744                                             ExportParameter( aStrBuffer, aSkewParaPair.First );
745                                             ExportParameter( aStrBuffer, aSkewParaPair.Second );
746                                             aStr = aStrBuffer.makeStringAndClear();
747                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SKEW, aStr );
748                                         }
749                                     }
750                                     break;
751                                     case EAS_Specularity :
752                                     {
753                                         double fExtrusionSpecularity = 0;
754                                         if ( rProp.Value >>= fExtrusionSpecularity )
755                                         {
756                                             rUnitConverter.convertDouble( aStrBuffer, fExtrusionSpecularity, sal_False, MAP_RELATIVE, MAP_RELATIVE );
757                                             aStrBuffer.append( (sal_Unicode)'%' );
758                                             aStr = aStrBuffer.makeStringAndClear();
759                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SPECULARITY, aStr );
760                                         }
761                                     }
762                                     break;
763                                     case EAS_ProjectionMode :
764                                     {
765                                         drawing::ProjectionMode eProjectionMode;
766                                         if ( rProp.Value >>= eProjectionMode )
767                                             rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_PROJECTION,
768                                                 eProjectionMode == drawing::ProjectionMode_PARALLEL ? GetXMLToken( XML_PARALLEL ) : GetXMLToken( XML_PERSPECTIVE ) );
769                                     }
770                                     break;
771                                     case EAS_ViewPoint :
772                                     {
773                                         drawing::Position3D aExtrusionViewPoint;
774                                         if ( rProp.Value >>= aExtrusionViewPoint )
775                                         {
776                                             rUnitConverter.convertPosition3D( aStrBuffer, aExtrusionViewPoint );
777                                             aStr = aStrBuffer.makeStringAndClear();
778                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_VIEWPOINT, aStr );
779                                         }
780                                     }
781                                     break;
782                                     case EAS_Origin :
783                                     {
784                                         com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginParaPair;
785                                         if ( rProp.Value >>= aOriginParaPair )
786                                         {
787                                             ExportParameter( aStrBuffer, aOriginParaPair.First );
788                                             ExportParameter( aStrBuffer, aOriginParaPair.Second );
789                                             aStr = aStrBuffer.makeStringAndClear();
790                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ORIGIN, aStr );
791                                         }
792                                     }
793                                     break;
794                                     case EAS_Color :
795                                     {
796                                         sal_Bool bExtrusionColor = sal_Bool();
797                                         if ( rProp.Value >>= bExtrusionColor )
798                                         {
799                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_COLOR,
800                                                 bExtrusionColor ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
801                                         }
802                                     }
803                                     break;
804                                     default:
805                                         break;
806                                 }
807                             }
808                         }
809                     }
810                     break;
811                     case EAS_TextPath :
812                     {
813                         uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
814                         if ( rGeoProp.Value >>= aTextPathPropSeq )
815                         {
816                             sal_Int32 i, nCount = aTextPathPropSeq.getLength();
817                             for ( i = 0; i < nCount; i++ )
818                             {
819                                 const beans::PropertyValue& rProp = aTextPathPropSeq[ i ];
820                                 switch( EASGet( rProp.Name ) )
821                                 {
822                                     case EAS_TextPath :
823                                     {
824                                         sal_Bool bTextPathOn = sal_Bool();
825                                         if ( rProp.Value >>= bTextPathOn )
826                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH,
827                                                 bTextPathOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
828                                     }
829                                     break;
830                                     case EAS_TextPathMode :
831                                     {
832                                         com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
833                                         if ( rProp.Value >>= eTextPathMode )
834                                         {
835                                             switch ( eTextPathMode )
836                                             {
837                                                 case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL: aStr = GetXMLToken( XML_NORMAL ); break;
838                                                 case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH  : aStr = GetXMLToken( XML_PATH );   break;
839                                                 case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE : aStr = GetXMLToken( XML_SHAPE );  break;
840                                                 default:
841                                                     break;
842                                             }
843                                             if ( aStr.getLength() )
844                                                 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_MODE, aStr );
845                                         }
846                                     }
847                                     break;
848                                     case EAS_ScaleX :
849                                     {
850                                         sal_Bool bScaleX = sal_Bool();
851                                         if ( rProp.Value >>= bScaleX )
852                                         {
853                                             aStr = bScaleX ? GetXMLToken( XML_SHAPE ) : GetXMLToken( XML_PATH );
854                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SCALE, aStr );
855                                         }
856                                     }
857                                     break;
858                                     case EAS_SameLetterHeights :
859                                     {
860                                         sal_Bool bSameLetterHeights = sal_Bool();
861                                         if ( rProp.Value >>= bSameLetterHeights )
862                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SAME_LETTER_HEIGHTS,
863                                                 bSameLetterHeights ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
864                                     }
865                                     break;
866                                     default:
867                                         break;
868                                 }
869                             }
870                         }
871                     }
872                     break;
873                     case EAS_Path :
874                     {
875                         uno::Sequence< beans::PropertyValue > aPathPropSeq;
876                         if ( rGeoProp.Value >>= aPathPropSeq )
877                         {
878                             sal_Int32 i, nCount = aPathPropSeq.getLength();
879                             for ( i = 0; i < nCount; i++ )
880                             {
881                                 const beans::PropertyValue& rProp = aPathPropSeq[ i ];
882                                 switch( EASGet( rProp.Name ) )
883                                 {
884                                     case EAS_ExtrusionAllowed :
885                                     {
886                                         sal_Bool bExtrusionAllowed = sal_Bool();
887                                         if ( rProp.Value >>= bExtrusionAllowed )
888                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ALLOWED,
889                                                 bExtrusionAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
890                                     }
891                                     break;
892                                     case EAS_ConcentricGradientFillAllowed :
893                                     {
894                                         sal_Bool bConcentricGradientFillAllowed = sal_Bool();
895                                         if ( rProp.Value >>= bConcentricGradientFillAllowed )
896                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONCENTRIC_GRADIENT_FILL_ALLOWED,
897                                                 bConcentricGradientFillAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
898                                     }
899                                     break;
900                                     case EAS_TextPathAllowed  :
901                                     {
902                                         sal_Bool bTextPathAllowed = sal_Bool();
903                                         if ( rProp.Value >>= bTextPathAllowed )
904                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_ALLOWED,
905                                                 bTextPathAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
906                                     }
907                                     break;
908                                     case EAS_GluePoints :
909                                     {
910                                         com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
911                                         if ( rProp.Value >>= aGluePoints )
912                                         {
913                                             sal_Int32 k, nElements = aGluePoints.getLength();
914                                             if ( nElements )
915                                             {
916                                                 for( k = 0; k < nElements; k++ )
917                                                 {
918                                                     ExportParameter( aStrBuffer, aGluePoints[ k ].First );
919                                                     ExportParameter( aStrBuffer, aGluePoints[ k ].Second );
920                                                 }
921                                                 aStr = aStrBuffer.makeStringAndClear();
922                                             }
923                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINTS, aStr );
924                                         }
925                                     }
926                                     break;
927                                     case EAS_GluePointType :
928                                     {
929                                         sal_Int16 nGluePointType = sal_Int16();
930                                         if ( rProp.Value >>= nGluePointType )
931                                         {
932                                             switch ( nGluePointType )
933                                             {
934                                                 case com::sun::star::drawing::EnhancedCustomShapeGluePointType::NONE     : aStr = GetXMLToken( XML_NONE );    break;
935                                                 case com::sun::star::drawing::EnhancedCustomShapeGluePointType::SEGMENTS : aStr = GetXMLToken( XML_SEGMENTS ); break;
936                                                 case com::sun::star::drawing::EnhancedCustomShapeGluePointType::RECT     : aStr = GetXMLToken( XML_RECTANGLE ); break;
937                                             }
938                                             if ( aStr.getLength() )
939                                                 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINT_TYPE, aStr );
940                                         }
941                                     }
942                                     break;
943                                     case EAS_Coordinates :
944                                     {
945                                         bCoordinates = ( rProp.Value >>= aCoordinates );
946                                     }
947                                     break;
948                                     case EAS_Segments :
949                                     {
950                                         rProp.Value >>= aSegments;
951                                     }
952                                     break;
953                                     case EAS_StretchX :
954                                     {
955                                         sal_Int32 nStretchPoint = 0;
956                                         if ( rProp.Value >>= nStretchPoint )
957                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_X, rtl::OUString::valueOf( nStretchPoint ) );
958                                     }
959                                     break;
960                                     case EAS_StretchY :
961                                     {
962                                         sal_Int32 nStretchPoint = 0;
963                                         if ( rProp.Value >>= nStretchPoint )
964                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_Y, rtl::OUString::valueOf( nStretchPoint ) );
965                                     }
966                                     break;
967                                     case EAS_TextFrames :
968                                     {
969                                         com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
970                                         if ( rProp.Value >>= aPathTextFrames )
971                                         {
972                                             if ( (sal_uInt16)aPathTextFrames.getLength() )
973                                             {
974                                                 sal_uInt16 k, nElements = (sal_uInt16)aPathTextFrames.getLength();
975                                                 for ( k = 0; k < nElements; k++ )
976                                                 {
977                                                     ExportParameter( aStrBuffer, aPathTextFrames[ k ].TopLeft.First );
978                                                     ExportParameter( aStrBuffer, aPathTextFrames[ k ].TopLeft.Second );
979                                                     ExportParameter( aStrBuffer, aPathTextFrames[ k ].BottomRight.First );
980                                                     ExportParameter( aStrBuffer, aPathTextFrames[ k ].BottomRight.Second );
981                                                 }
982                                                 aStr = aStrBuffer.makeStringAndClear();
983                                             }
984                                             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_AREAS, aStr );
985                                         }
986                                     }
987                                     break;
988                                     default:
989                                         break;
990                                 }
991                             }
992                         }
993                     }
994                     break;
995                     case EAS_Equations :
996                     {
997                         bEquations = ( rGeoProp.Value >>= aEquations );
998                     }
999                     break;
1000                     case EAS_Handles :
1001                     {
1002                         bHandles = ( rGeoProp.Value >>= aHandles );
1003                     }
1004                     break;
1005                     case EAS_AdjustmentValues :
1006                     {
1007                         rGeoProp.Value >>= aAdjustmentValues;
1008                     }
1009                     break;
1010                     default:
1011                         break;
1012                 }
1013             }   // for
1014             rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TYPE, aCustomShapeType );
1015 
1016             // adjustments
1017             sal_Int32 nAdjustmentValues = aAdjustmentValues.getLength();
1018             if ( nAdjustmentValues )
1019             {
1020                 sal_Int32 i, nValue = 0;
1021                 for ( i = 0; i < nAdjustmentValues; i++ )
1022                 {
1023                     if ( i )
1024                         aStrBuffer.append( (sal_Unicode)' ' );
1025 
1026                     const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue& rAdj = aAdjustmentValues[ i ];
1027                     if ( rAdj.State == beans::PropertyState_DIRECT_VALUE )
1028                     {
1029                         if ( rAdj.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
1030                         {
1031                             double fValue = 0.0;
1032                             rAdj.Value >>= fValue;
1033                             rUnitConverter.convertDouble( aStrBuffer, fValue );
1034                         }
1035                         else
1036                         {
1037                             rAdj.Value >>= nValue;
1038                             rUnitConverter.convertNumber( aStrBuffer, nValue );
1039                         }
1040                     }
1041                     else
1042                         rUnitConverter.convertNumber( aStrBuffer, 0 );          // this should not be, but better than setting nothing
1043                 }
1044                 aStr = aStrBuffer.makeStringAndClear();
1045                 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MODIFIERS, aStr );
1046             }
1047             if ( bCoordinates )
1048                 ImpExportEnhancedPath( rExport, aCoordinates, aSegments );
1049         }
1050     }
1051     SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_ENHANCED_GEOMETRY, sal_True, sal_True );
1052     if ( bEquations )
1053         ImpExportEquations( rExport, aEquations );
1054     if ( bHandles )
1055         ImpExportHandles( rExport, aHandles );
1056 }
1057 
1058 void XMLShapeExport::ImpExportCustomShape(
1059     const uno::Reference< drawing::XShape >& xShape,
1060     XmlShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint )
1061 {
1062     const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1063     if ( xPropSet.is() )
1064     {
1065         rtl::OUString aStr;
1066         uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1067 
1068         // Transformation
1069         ImpExportNewTrans( xPropSet, nFeatures, pRefPoint );
1070 
1071         if ( xPropSetInfo.is() )
1072         {
1073             const rtl::OUString sCustomShapeEngine( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeEngine" ) );
1074             if ( xPropSetInfo->hasPropertyByName( sCustomShapeEngine ) )
1075             {
1076                 uno::Any aEngine( xPropSet->getPropertyValue( sCustomShapeEngine ) );
1077                 if ( ( aEngine >>= aStr ) && aStr.getLength() )
1078                     mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ENGINE, aStr );
1079             }
1080             const rtl::OUString sCustomShapeData( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeData" ) );
1081             if ( xPropSetInfo->hasPropertyByName( sCustomShapeData ) )
1082             {
1083                 uno::Any aData( xPropSet->getPropertyValue( sCustomShapeData ) );
1084                 if ( ( aData >>= aStr ) && aStr.getLength() )
1085                     mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DATA, aStr );
1086             }
1087         }
1088         sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1089         SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, bCreateNewline, sal_True );
1090         ImpExportDescription( xShape ); // #i68101#
1091         ImpExportEvents( xShape );
1092         ImpExportGluePoints( xShape );
1093         ImpExportText( xShape );
1094         ImpExportEnhancedGeometry( mrExport, xPropSet );
1095     }
1096 }
1097 
1098 void XMLShapeExport::ImpExportTableShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint )
1099 {
1100     uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1101     uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
1102 
1103     DBG_ASSERT( xPropSet.is() && xNamed.is(), "xmloff::XMLShapeExport::ImpExportTableShape(), tabe shape is not implementing needed interfaces");
1104     if(xPropSet.is() && xNamed.is()) try
1105     {
1106         // Transformation
1107         ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1108 
1109         sal_Bool bIsEmptyPresObj = sal_False;
1110 
1111         // presentation settings
1112         if(eShapeType == XmlShapeTypePresTableShape)
1113             bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_TABLE) );
1114 
1115         const bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 );
1116         const bool bExportEmbedded(0 != (mrExport.getExportFlags() & EXPORT_EMBEDDED));
1117 
1118         SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW, XML_FRAME, bCreateNewline, sal_True );
1119 
1120         // do not export in ODF 1.1 or older
1121         if( mrExport.getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
1122         {
1123             if( !bIsEmptyPresObj )
1124             {
1125                 uno::Reference< container::XNamed > xTemplate( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TableTemplate" ) ) ), uno::UNO_QUERY );
1126                 if( xTemplate.is() )
1127                 {
1128                     const OUString sTemplate( xTemplate->getName() );
1129                     if( sTemplate.getLength() )
1130                     {
1131                         mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TEMPLATE_NAME, sTemplate );
1132 
1133                         for( const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0]; pEntry->msApiName; pEntry++ )
1134                         {
1135                             try
1136                             {
1137                                 sal_Bool bBool = sal_False;
1138                                 const OUString sAPIPropertyName( OUString(pEntry->msApiName, pEntry->nApiNameLength, RTL_TEXTENCODING_ASCII_US ) );
1139 
1140                                 xPropSet->getPropertyValue( sAPIPropertyName ) >>= bBool;
1141                                 if( bBool )
1142                                     mrExport.AddAttribute(pEntry->mnNameSpace, pEntry->meXMLName, XML_TRUE );
1143                             }
1144                             catch( uno::Exception& )
1145                             {
1146                                 DBG_ERROR("XMLShapeExport::ImpExportTableShape(), exception caught!");
1147                             }
1148                         }
1149                     }
1150                 }
1151 
1152 
1153                 uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( msModel ), uno::UNO_QUERY_THROW );
1154                 GetShapeTableExport()->exportTable( xRange );
1155             }
1156         }
1157 
1158         if( !bIsEmptyPresObj )
1159         {
1160             uno::Reference< graphic::XGraphic > xGraphic( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ReplacementGraphic" ) ) ), uno::UNO_QUERY );
1161             if( xGraphic.is() ) try
1162             {
1163                 Reference< lang::XMultiServiceFactory > xSM( GetExport().getServiceFactory(), UNO_QUERY_THROW );
1164 
1165                 uno::Reference< embed::XStorage > xPictureStorage;
1166                 uno::Reference< embed::XStorage > xStorage;
1167                 uno::Reference< io::XStream > xPictureStream;
1168 
1169                 OUString sPictureName;
1170                 if( bExportEmbedded )
1171                 {
1172                     xPictureStream.set( xSM->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.MemoryStream" ) ) ), UNO_QUERY_THROW );
1173                 }
1174                 else
1175                 {
1176                     xStorage.set( GetExport().GetTargetStorage(), UNO_QUERY_THROW );
1177 
1178                     xPictureStorage.set( xStorage->openStorageElement( OUString( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ), ::embed::ElementModes::READWRITE ), uno::UNO_QUERY_THROW );
1179                     const OUString sPrefix( RTL_CONSTASCII_USTRINGPARAM("TablePreview") );
1180                     const OUString sSuffix( RTL_CONSTASCII_USTRINGPARAM(".svm") );
1181 
1182                     sal_Int32 nIndex = 0;
1183                     do
1184                     {
1185                         sPictureName = sPrefix;
1186                         sPictureName += OUString::valueOf( ++nIndex );
1187                         sPictureName += sSuffix;
1188                     }
1189                     while( xPictureStorage->hasByName( sPictureName ) );
1190 
1191                     xPictureStream.set( xPictureStorage->openStreamElement( sPictureName, ::embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
1192                 }
1193 
1194                 Reference< graphic::XGraphicProvider > xProvider( xSM->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW );
1195                 Sequence< beans::PropertyValue > aArgs( 2 );
1196                 aArgs[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) );
1197                 aArgs[ 0 ].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "image/x-vclgraphic" ) );
1198                 aArgs[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
1199                 aArgs[ 1 ].Value <<= xPictureStream->getOutputStream();
1200                 xProvider->storeGraphic( xGraphic, aArgs );
1201 
1202                 if( xPictureStorage.is() )
1203                 {
1204                     Reference< embed::XTransactedObject > xTrans( xPictureStorage, UNO_QUERY );
1205                     if( xTrans.is() )
1206                         xTrans->commit();
1207                 }
1208 
1209                 if( !bExportEmbedded )
1210                 {
1211                     OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "Pictures/" ) );
1212                     sURL += sPictureName;
1213                     mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL );
1214                     mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1215                     mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1216                     mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1217                 }
1218 
1219                 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, sal_False, sal_True );
1220 
1221                 if( bExportEmbedded )
1222                 {
1223                     Reference< XSeekableInputStream > xSeekable( xPictureStream, UNO_QUERY_THROW );
1224                     xSeekable->seek(0);
1225 
1226                     XMLBase64Export aBase64Exp( GetExport() );
1227                     aBase64Exp.exportOfficeBinaryDataElement( Reference < XInputStream >( xPictureStream, UNO_QUERY_THROW ) );
1228                 }
1229             }
1230             catch( uno::Exception& )
1231             {
1232                 DBG_ERROR("xmloff::XMLShapeExport::ImpExportTableShape(), exception caught!");
1233             }
1234         }
1235 
1236         ImpExportEvents( xShape );
1237         ImpExportGluePoints( xShape );
1238         ImpExportDescription( xShape ); // #i68101#
1239     }
1240     catch( uno::Exception& )
1241     {
1242         DBG_ERROR( "xmloff::XMLShapeExport::ImpExportTableShape(), exception caught!" );
1243     }
1244 }
1245