1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 #include "oox/core/xmlfilterbase.hxx"
33 #include "oox/export/drawingml.hxx"
34 #include "oox/export/utils.hxx"
37 #include <com/sun/star/awt/CharSet.hpp>
38 #include <com/sun/star/awt/FontDescriptor.hpp>
39 #include <com/sun/star/awt/FontSlant.hpp>
40 #include <com/sun/star/awt/FontWeight.hpp>
41 #include <com/sun/star/awt/FontUnderline.hpp>
42 #include <com/sun/star/awt/Gradient.hpp>
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 #include <com/sun/star/beans/XPropertyState.hpp>
45 #include <com/sun/star/container/XEnumerationAccess.hpp>
46 #include <com/sun/star/drawing/BitmapMode.hpp>
47 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
48 #include <com/sun/star/drawing/LineDash.hpp>
49 #include <com/sun/star/drawing/LineJoint.hpp>
50 #include <com/sun/star/drawing/LineStyle.hpp>
51 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
52 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
53 #include <com/sun/star/i18n/ScriptType.hpp>
54 #include <com/sun/star/io/XOutputStream.hpp>
55 #include <com/sun/star/style/ParagraphAdjust.hpp>
56 #include <com/sun/star/text/XText.hpp>
57 #include <com/sun/star/text/XTextContent.hpp>
58 #include <com/sun/star/text/XTextField.hpp>
59 #include <com/sun/star/text/XTextRange.hpp>
60 #include <tools/stream.hxx>
61 #include <tools/string.hxx>
62 #include <vcl/cvtgrf.hxx>
63 #include <vcl/fontcvt.hxx>
64 #include <vcl/graph.hxx>
65 #include <goodies/grfmgr.hxx>
66 #include <rtl/strbuf.hxx>
67 #include <sfx2/app.hxx>
68 #include <svtools/languageoptions.hxx>
69 #include <svx/escherex.hxx>
70 #include <svx/svxenum.hxx>
72 using namespace ::com::sun::star
;
73 using namespace ::com::sun::star::uno
;
74 using namespace ::com::sun::star::drawing
;
75 using namespace ::com::sun::star::i18n
;
76 using ::com::sun::star::beans::PropertyState
;
77 using ::com::sun::star::beans::PropertyValue
;
78 using ::com::sun::star::beans::XPropertySet
;
79 using ::com::sun::star::beans::XPropertyState
;
80 using ::com::sun::star::container::XEnumeration
;
81 using ::com::sun::star::container::XEnumerationAccess
;
82 using ::com::sun::star::container::XIndexAccess
;
83 using ::com::sun::star::io::XOutputStream
;
84 using ::com::sun::star::text::XText
;
85 using ::com::sun::star::text::XTextContent
;
86 using ::com::sun::star::text::XTextField
;
87 using ::com::sun::star::text::XTextRange
;
89 using ::rtl::OStringBuffer
;
90 using ::rtl::OUString
;
91 using ::rtl::OUStringBuffer
;
92 using ::sax_fastparser::FSHelperPtr
;
94 DBG(extern void dump_pset(Reference
< XPropertySet
> rXPropSet
));
99 #define GETA(propName) \
100 GetProperty( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ) )
102 #define GETAD(propName) \
103 ( GetPropertyAndState( rXPropSet, rXPropState, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
105 #define GET(variable, propName) \
106 if ( GETA(propName) ) \
110 int DrawingML::mnImageCounter
= 1;
112 void DrawingML::ResetCounters()
117 bool DrawingML::GetProperty( Reference
< XPropertySet
> rXPropSet
, String aName
)
119 bool bRetValue
= false;
122 mAny
= rXPropSet
->getPropertyValue( aName
);
123 if ( mAny
.hasValue() )
125 } catch( Exception
& ) { /* printf ("exception when trying to get value of property: %s\n", ST(aName)); */ }
130 bool DrawingML::GetPropertyAndState( Reference
< XPropertySet
> rXPropSet
, Reference
< XPropertyState
> rXPropState
, String aName
, PropertyState
& eState
)
132 bool bRetValue
= false;
135 mAny
= rXPropSet
->getPropertyValue( aName
);
136 if ( mAny
.hasValue() ) {
138 eState
= rXPropState
->getPropertyState( aName
);
140 } catch( Exception
& ) { /* printf ("exception when trying to get value of property: %s\n", ST(aName)); */ }
145 void DrawingML::WriteColor( sal_uInt32 nColor
)
147 OString sColor
= OString::valueOf( ( sal_Int64
) nColor
, 16 );
148 if( sColor
.getLength() < 6 ) {
149 OStringBuffer
sBuf( "0" );
150 int remains
= 5 - sColor
.getLength();
152 while( remains
> 0 ) {
157 sBuf
.append( sColor
);
159 sColor
= sBuf
.getStr();
161 mpFS
->singleElementNS( XML_a
, XML_srgbClr
, XML_val
, sColor
.getStr(), FSEND
);
164 void DrawingML::WriteSolidFill( sal_uInt32 nColor
)
166 mpFS
->startElementNS( XML_a
, XML_solidFill
, FSEND
);
167 WriteColor( nColor
);
168 mpFS
->endElementNS( XML_a
, XML_solidFill
);
171 void DrawingML::WriteSolidFill( Reference
< XPropertySet
> rXPropSet
)
173 if ( GetProperty( rXPropSet
, S( "FillColor" ) ) )
174 WriteSolidFill( *((sal_uInt32
*) mAny
.getValue()) & 0xffffff );
177 void DrawingML::WriteGradientStop( sal_uInt16 nStop
, sal_uInt32 nColor
)
179 mpFS
->startElementNS( XML_a
, XML_gs
,
180 XML_pos
, I32S( nStop
* 1000 ),
182 WriteColor( nColor
);
183 mpFS
->endElementNS( XML_a
, XML_gs
);
186 sal_uInt32
DrawingML::ColorWithIntensity( sal_uInt32 nColor
, sal_uInt32 nIntensity
)
188 return ( ( ( nColor
& 0xff ) * nIntensity
) / 100 )
189 | ( ( ( ( ( nColor
& 0xff00 ) >> 8 ) * nIntensity
) / 100 ) << 8 )
190 | ( ( ( ( ( nColor
& 0xff0000 ) >> 8 ) * nIntensity
) / 100 ) << 8 );
193 void DrawingML::WriteGradientFill( Reference
< XPropertySet
> rXPropSet
)
195 awt::Gradient aGradient
;
196 if( GETA( FillGradient
) ) {
197 aGradient
= *static_cast< const awt::Gradient
* >( mAny
.getValue() );
199 mpFS
->startElementNS( XML_a
, XML_gradFill
, FSEND
);
201 switch( aGradient
.Style
) {
203 case GradientStyle_LINEAR
:
204 mpFS
->startElementNS( XML_a
, XML_gsLst
, FSEND
);
205 WriteGradientStop( 0, ColorWithIntensity( aGradient
.StartColor
, aGradient
.StartIntensity
) );
206 WriteGradientStop( 100, ColorWithIntensity( aGradient
.EndColor
, aGradient
.EndIntensity
) );
207 mpFS
->endElementNS( XML_a
, XML_gsLst
);
208 mpFS
->singleElementNS( XML_a
, XML_lin
,
209 XML_ang
, I32S( ( ( ( 3600 - aGradient
.Angle
+ 900 ) * 6000 ) % 21600000 ) ),
213 case GradientStyle_AXIAL
:
214 mpFS
->startElementNS( XML_a
, XML_gsLst
, FSEND
);
215 WriteGradientStop( 0, ColorWithIntensity( aGradient
.EndColor
, aGradient
.EndIntensity
) );
216 WriteGradientStop( 50, ColorWithIntensity( aGradient
.StartColor
, aGradient
.StartIntensity
) );
217 WriteGradientStop( 100, ColorWithIntensity( aGradient
.EndColor
, aGradient
.EndIntensity
) );
218 mpFS
->endElementNS( XML_a
, XML_gsLst
);
219 mpFS
->singleElementNS( XML_a
, XML_lin
,
220 XML_ang
, I32S( ( ( ( 3600 - aGradient
.Angle
+ 900 ) * 6000 ) % 21600000 ) ),
224 /* I don't see how to apply transformation to gradients, so
225 * elliptical will end as radial and square as
226 * rectangular. also position offsets are not applied */
227 case GradientStyle_RADIAL
:
228 case GradientStyle_ELLIPTICAL
:
229 case GradientStyle_RECT
:
230 case GradientStyle_SQUARE
:
231 mpFS
->startElementNS( XML_a
, XML_gsLst
, FSEND
);
232 WriteGradientStop( 0, ColorWithIntensity( aGradient
.EndColor
, aGradient
.EndIntensity
) );
233 WriteGradientStop( 100, ColorWithIntensity( aGradient
.StartColor
, aGradient
.StartIntensity
) );
234 mpFS
->endElementNS( XML_a
, XML_gsLst
);
235 mpFS
->singleElementNS( XML_a
, XML_path
,
236 XML_path
, ( aGradient
.Style
== awt::GradientStyle_RADIAL
|| aGradient
.Style
== awt::GradientStyle_ELLIPTICAL
) ? "circle" : "rect",
241 mpFS
->endElementNS( XML_a
, XML_gradFill
);
246 void DrawingML::WriteLineArrow( Reference
< XPropertySet
> rXPropSet
, sal_Bool bLineStart
)
248 ESCHER_LineEnd eLineEnd
;
249 sal_Int32 nArrowLength
;
250 sal_Int32 nArrowWidth
;
252 if ( EscherPropertyContainer::GetLineArrow( bLineStart
, rXPropSet
, eLineEnd
, nArrowLength
, nArrowWidth
) ) {
257 switch( nArrowLength
) {
258 case ESCHER_LineShortArrow
:
262 case ESCHER_LineMediumLenArrow
:
265 case ESCHER_LineLongArrow
:
272 case ESCHER_LineNoEnd
:
275 case ESCHER_LineArrowEnd
:
278 case ESCHER_LineArrowStealthEnd
:
281 case ESCHER_LineArrowDiamondEnd
:
284 case ESCHER_LineArrowOvalEnd
:
287 case ESCHER_LineArrowOpenEnd
:
292 switch( nArrowWidth
) {
293 case ESCHER_LineNarrowArrow
:
297 case ESCHER_LineMediumWidthArrow
:
300 case ESCHER_LineWideArrow
:
305 mpFS
->singleElementNS( XML_a
, bLineStart
? XML_headEnd
: XML_tailEnd
,
313 void DrawingML::WriteOutline( Reference
< XPropertySet
> rXPropSet
)
315 drawing::LineStyle
aLineStyle( drawing::LineStyle_NONE
);
317 GET( aLineStyle
, LineStyle
);
319 if( aLineStyle
== drawing::LineStyle_NONE
)
322 sal_uInt32 nLineWidth
= 0;
323 sal_uInt32 nColor
= 0;
324 sal_Bool bColorSet
= FALSE
;
325 const char* cap
= NULL
;
326 drawing::LineDash aLineDash
;
327 sal_Bool bDashSet
= FALSE
;
329 GET( nLineWidth
, LineWidth
);
331 switch( aLineStyle
) {
332 case drawing::LineStyle_DASH
:
333 if( GETA( LineDash
) ) {
334 aLineDash
= *(drawing::LineDash
*) mAny
.getValue();
336 if( aLineDash
.Style
== DashStyle_ROUND
|| aLineDash
.Style
== DashStyle_ROUNDRELATIVE
)
339 DBG(printf("dash dots: %d dashes: %d dotlen: %d dashlen: %d distance: %d\n",
340 int( aLineDash
.Dots
), int( aLineDash
.Dashes
), int( aLineDash
.DotLen
), int( aLineDash
.DashLen
), int( aLineDash
.Distance
)));
342 /* fallthru intended */
343 case drawing::LineStyle_SOLID
:
345 if ( GETA( LineColor
) ) {
346 nColor
= *((sal_uInt32
*) mAny
.getValue()) & 0xffffff;
352 mpFS
->startElementNS( XML_a
, XML_ln
,
354 XML_w
, nLineWidth
> 1 ? I64S( MM100toEMU( nLineWidth
) ) : NULL
,
357 WriteSolidFill( nColor
);
360 mpFS
->startElementNS( XML_a
, XML_custDash
, FSEND
);
362 for( i
= 0; i
< aLineDash
.Dots
; i
++ )
363 mpFS
->singleElementNS( XML_a
, XML_ds
,
364 XML_d
, aLineDash
.DotLen
? I64S( aLineDash
.DotLen
*1000 ) : "100000",
365 XML_sp
, I64S( aLineDash
.Distance
*1000 ),
367 for( i
= 0; i
< aLineDash
.Dashes
; i
++ )
368 mpFS
->singleElementNS( XML_a
, XML_ds
,
369 XML_d
, aLineDash
.DashLen
? I64S( aLineDash
.DashLen
*1000 ) : "100000",
370 XML_sp
, I64S( aLineDash
.Distance
*1000 ),
372 mpFS
->endElementNS( XML_a
, XML_custDash
);
375 if( nLineWidth
> 1 && GETA( LineJoint
) ) {
376 LineJoint eLineJoint
;
379 switch( eLineJoint
) {
381 case LineJoint_MIDDLE
:
382 case LineJoint_BEVEL
:
383 mpFS
->singleElementNS( XML_a
, XML_bevel
, FSEND
);
386 case LineJoint_MITER
:
387 mpFS
->singleElementNS( XML_a
, XML_miter
, FSEND
);
389 case LineJoint_ROUND
:
390 mpFS
->singleElementNS( XML_a
, XML_round
, FSEND
);
395 WriteLineArrow( rXPropSet
, sal_True
);
396 WriteLineArrow( rXPropSet
, sal_False
);
398 mpFS
->endElementNS( XML_a
, XML_ln
);
401 OUString
DrawingML::WriteImage( const OUString
& rURL
)
403 ByteString
aURLBS( UniString( rURL
), RTL_TEXTENCODING_UTF8
);
405 const char aURLBegin
[] = "vnd.sun.star.GraphicObject:";
406 int index
= aURLBS
.Search( aURLBegin
);
408 if ( index
!= STRING_NOTFOUND
) {
409 DBG(printf ("begin: %ld %s\n", long( sizeof( aURLBegin
) ), USS( rURL
) + sizeof( aURLBegin
) - 1 ));
410 aURLBS
.Erase( 0, sizeof( aURLBegin
) - 1 );
411 Graphic aGraphic
= GraphicObject( aURLBS
).GetTransformedGraphic ();
413 return WriteImage( aGraphic
);
415 // add link to relations
421 OUString
DrawingML::WriteImage( const Graphic
& rGraphic
)
423 GfxLink aLink
= rGraphic
.GetLink ();
425 const char* sExtension
= NULL
;
428 SvMemoryStream aStream
;
429 const void* aData
= aLink
.GetData();
430 sal_Size nDataSize
= aLink
.GetDataSize();
432 switch ( aLink
.GetType() ) {
433 case GFX_LINK_TYPE_NATIVE_GIF
:
434 sMediaType
= US( "image/gif" );
437 case GFX_LINK_TYPE_NATIVE_JPG
:
438 sMediaType
= US( "image/jpeg" );
439 sExtension
= ".jpeg";
441 case GFX_LINK_TYPE_NATIVE_PNG
:
442 sMediaType
= US( "image/png" );
445 case GFX_LINK_TYPE_NATIVE_TIF
:
446 sMediaType
= US( "image/tiff" );
447 sExtension
= ".tiff";
449 case GFX_LINK_TYPE_NATIVE_WMF
:
450 sMediaType
= US( "image/x-wmf" );
453 case GFX_LINK_TYPE_NATIVE_MET
:
454 sMediaType
= US( "image/x-met" );
457 case GFX_LINK_TYPE_NATIVE_PCT
:
458 sMediaType
= US( "image/x-pict" );
462 GraphicType aType
= rGraphic
.GetType();
463 if ( aType
== GRAPHIC_BITMAP
) {
464 GraphicConverter::Export( aStream
, rGraphic
, CVT_PNG
);
465 sMediaType
= US( "image/png" );
467 } else if ( aType
== GRAPHIC_GDIMETAFILE
) {
468 GraphicConverter::Export( aStream
, rGraphic
, CVT_EMF
);
469 sMediaType
= US( "image/x-emf" );
472 OSL_TRACE( "unhandled graphic type" );
476 aData
= aStream
.GetData();
477 nDataSize
= aStream
.GetSize();
482 const char *pComponent
= NULL
;
483 switch ( meDocumentType
)
485 case DOCUMENT_DOCX
: pComponent
= "word"; break;
486 case DOCUMENT_PPTX
: pComponent
= "ppt"; break;
487 case DOCUMENT_XLSX
: pComponent
= "xl"; break;
490 Reference
< XOutputStream
> xOutStream
= mpFB
->openOutputStream( OUStringBuffer()
491 .appendAscii( pComponent
)
492 .appendAscii( "/media/image" )
493 .append( (sal_Int32
) mnImageCounter
)
494 .appendAscii( sExtension
)
495 .makeStringAndClear(),
497 xOutStream
->writeBytes( Sequence
< sal_Int8
>( (const sal_Int8
*) aData
, nDataSize
) );
498 xOutStream
->closeOutput();
500 const char *pImagePrefix
= NULL
;
501 switch ( meDocumentType
)
504 pImagePrefix
= "media/image";
508 pImagePrefix
= "../media/image";
512 sRelId
= mpFB
->addRelation( mpFS
->getOutputStream(),
513 US( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ),
515 .appendAscii( pImagePrefix
)
516 .append( (sal_Int32
) mnImageCounter
++ )
517 .appendAscii( sExtension
)
518 .makeStringAndClear() );
523 OUString
DrawingML::WriteBlip( OUString
& rURL
)
525 OUString sRelId
= WriteImage( rURL
);
527 mpFS
->singleElementNS( XML_a
, XML_blip
,
528 FSNS( XML_r
, XML_embed
), OUStringToOString( sRelId
, RTL_TEXTENCODING_UTF8
).getStr(),
534 void DrawingML::WriteBlipMode( Reference
< XPropertySet
> rXPropSet
)
536 BitmapMode
eBitmapMode( BitmapMode_NO_REPEAT
);
537 if (GetProperty( rXPropSet
, S( "FillBitmapMode" ) ) )
538 mAny
>>= eBitmapMode
;
540 DBG(printf("fill bitmap mode: %d\n", eBitmapMode
));
542 switch (eBitmapMode
) {
543 case BitmapMode_REPEAT
:
544 mpFS
->singleElementNS( XML_a
, XML_tile
, FSEND
);
551 void DrawingML::WriteBlipFill( Reference
< XPropertySet
> rXPropSet
, String sURLPropName
)
553 WriteBlipFill( rXPropSet
, sURLPropName
, XML_a
);
556 void DrawingML::WriteBlipFill( Reference
< XPropertySet
> rXPropSet
, String sURLPropName
, sal_Int32 nXmlNamespace
)
558 if ( GetProperty( rXPropSet
, sURLPropName
) ) {
562 DBG(printf ("URL: %s\n", OUStringToOString( aURL
, RTL_TEXTENCODING_UTF8
).getStr() ));
564 if( !aURL
.getLength() )
567 mpFS
->startElementNS( nXmlNamespace
, XML_blipFill
, FSEND
);
571 if( sURLPropName
== S( "FillBitmapURL" ) )
572 WriteBlipMode( rXPropSet
);
573 else if( GetProperty( rXPropSet
, S( "FillBitmapStretch" ) ) ) {
574 bool bStretch
= false;
581 mpFS
->endElementNS( nXmlNamespace
, XML_blipFill
);
585 void DrawingML::WriteStretch()
587 mpFS
->startElementNS( XML_a
, XML_stretch
, FSEND
);
588 mpFS
->singleElementNS( XML_a
, XML_fillRect
, FSEND
);
589 mpFS
->endElementNS( XML_a
, XML_stretch
);
592 void DrawingML::WriteTransformation( const Rectangle
& rRect
,
593 sal_Bool bFlipH
, sal_Bool bFlipV
, sal_Int32 nRotation
)
595 mpFS
->startElementNS( XML_a
, XML_xfrm
,
596 XML_flipH
, bFlipH
? "1" : NULL
,
597 XML_flipV
, bFlipV
? "1" : NULL
,
598 XML_rot
, nRotation
? I32S( nRotation
) : NULL
,
601 mpFS
->singleElementNS( XML_a
, XML_off
, XML_x
, IS( MM100toEMU( rRect
.Left() ) ), XML_y
, IS( MM100toEMU( rRect
.Top() ) ), FSEND
);
602 mpFS
->singleElementNS( XML_a
, XML_ext
, XML_cx
, IS( MM100toEMU( rRect
.GetWidth() ) ), XML_cy
, IS( MM100toEMU( rRect
.GetHeight() ) ), FSEND
);
604 mpFS
->endElementNS( XML_a
, XML_xfrm
);
607 void DrawingML::WriteShapeTransformation( Reference
< XShape
> rXShape
, sal_Bool bFlipH
, sal_Bool bFlipV
, sal_Int32 nRotation
)
609 DBG(printf( "write shape transformation\n" ));
611 awt::Point aPos
= rXShape
->getPosition();
612 awt::Size aSize
= rXShape
->getSize();
614 WriteTransformation( Rectangle( Point( aPos
.X
, aPos
.Y
), Size( aSize
.Width
, aSize
.Height
) ), bFlipH
, bFlipV
, nRotation
);
617 void DrawingML::WriteRunProperties( Reference
< XTextRange
> rRun
)
619 Reference
< XPropertySet
> rXPropSet( rRun
, UNO_QUERY
);
620 Reference
< XPropertyState
> rXPropState( rRun
, UNO_QUERY
);
622 PropertyState eState
;
623 sal_Int16 nScriptType
= SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
624 sal_Bool bComplex
= ( nScriptType
== ScriptType::COMPLEX
);
625 const char* bold
= NULL
;
626 const char* italic
= NULL
;
627 const char* underline
= NULL
;
628 sal_Int32 nSize
= 1800;
630 if( GETAD( CharHeight
) )
631 nSize
= (sal_Int32
) (100*(*((float*) mAny
.getValue())));
633 if ( ( bComplex
&& GETAD( CharWeightComplex
) ) || GETAD( CharWeight
) )
634 if ( *((float*) mAny
.getValue()) >= awt::FontWeight::SEMIBOLD
)
637 if ( ( bComplex
&& GETAD( CharPostureComplex
) ) || GETAD( CharPosture
) )
638 switch ( *((awt::FontSlant
*) mAny
.getValue()) )
640 case awt::FontSlant_OBLIQUE
:
641 case awt::FontSlant_ITALIC
:
648 if ( GETAD( CharUnderline
) )
649 switch ( *((sal_Int16
*) mAny
.getValue()) )
651 case awt::FontUnderline::SINGLE
:
654 case awt::FontUnderline::DOUBLE
:
657 case awt::FontUnderline::DOTTED
:
658 underline
= "dotted";
660 case awt::FontUnderline::DASH
:
663 case awt::FontUnderline::LONGDASH
:
664 underline
= "dashLong";
666 case awt::FontUnderline::DASHDOT
:
667 underline
= "dotDash";
669 case awt::FontUnderline::DASHDOTDOT
:
670 underline
= "dotDotDash";
672 case awt::FontUnderline::WAVE
:
675 case awt::FontUnderline::DOUBLEWAVE
:
676 underline
= "wavyDbl";
678 case awt::FontUnderline::BOLD
:
681 case awt::FontUnderline::BOLDDOTTED
:
682 underline
= "dottedHeavy";
684 case awt::FontUnderline::BOLDDASH
:
685 underline
= "dashHeavy";
687 case awt::FontUnderline::BOLDLONGDASH
:
688 underline
= "dashLongHeavy";
690 case awt::FontUnderline::BOLDDASHDOT
:
691 underline
= "dotDashHeavy";
693 case awt::FontUnderline::BOLDDASHDOTDOT
:
694 underline
= "dotDotDashHeavy";
696 case awt::FontUnderline::BOLDWAVE
:
697 underline
= "wavyHeavy";
701 if( GETA( CharLocale
) ) {
702 com::sun::star::lang::Locale eLocale
;
705 OUStringBuffer usLanguageBuffer
= eLocale
.Language
;
706 if( eLocale
.Country
.getLength() ) {
707 usLanguageBuffer
.appendAscii( "-" );
708 usLanguageBuffer
.append( eLocale
.Country
);
711 if( usLanguageBuffer
.getLength() )
712 usLanguage
= usLanguageBuffer
.makeStringAndClear();
715 mpFS
->startElementNS( XML_a
, XML_rPr
,
718 XML_lang
, usLanguage
.getLength() ? USS( usLanguage
) : NULL
,
719 XML_sz
, nSize
== 1800 ? NULL
: IS( nSize
),
723 // mso doesn't like text color to be placed after typeface
724 if( GETAD( CharColor
) ) {
725 sal_uInt32 color
= *((sal_uInt32
*) mAny
.getValue());
726 DBG(printf("run color: %x auto: %x\n", static_cast<unsigned int>( color
), static_cast<unsigned int>( COL_AUTO
)));
728 if( color
== COL_AUTO
) { // nCharColor depends to the background color
729 sal_Bool bIsDark
= sal_False
;
730 GET( bIsDark
, IsBackgroundDark
);
731 color
= bIsDark
? 0xffffff : 0x000000;
735 // TODO: special handle embossed/engraved
737 WriteSolidFill( color
);
740 if( GETAD( CharFontName
) ) {
741 const char* typeface
= NULL
;
742 const char* pitch
= NULL
;
743 const char* charset
= NULL
;
744 OUString usTypeface
, usPitch
, usCharset
;
747 String
aSubstName( GetSubsFontName( usTypeface
, SUBSFONT_ONLYONE
| SUBSFONT_MS
) );
748 if( aSubstName
.Len() )
749 typeface
= ST( aSubstName
);
751 typeface
= USS( usTypeface
);
755 mpFS
->singleElementNS( XML_a
, XML_latin
,
756 XML_typeface
, typeface
,
757 XML_pitchFamily
, pitch
,
758 XML_charset
, charset
,
762 if( ( bComplex
&& GETAD( CharFontNameComplex
) ) || ( !bComplex
&& GETAD( CharFontNameAsian
) ) ) {
763 const char* typeface
= NULL
;
764 const char* pitch
= NULL
;
765 const char* charset
= NULL
;
766 OUString usTypeface
, usPitch
, usCharset
;
769 String
aSubstName( GetSubsFontName( usTypeface
, SUBSFONT_ONLYONE
| SUBSFONT_MS
) );
770 if( aSubstName
.Len() )
771 typeface
= ST( aSubstName
);
773 typeface
= USS( usTypeface
);
775 mpFS
->singleElementNS( XML_a
, bComplex
? XML_cs
: XML_ea
,
776 XML_typeface
, typeface
,
777 XML_pitchFamily
, pitch
,
778 XML_charset
, charset
,
782 mpFS
->endElementNS( XML_a
, XML_rPr
);
785 const char* DrawingML::GetFieldType( ::com::sun::star::uno::Reference
< ::com::sun::star::text::XTextRange
> rRun
)
787 const char* sType
= NULL
;
788 Reference
< XPropertySet
> rXPropSet( rRun
, UNO_QUERY
);
791 if( GETA( TextPortionType
) ) {
792 aFieldType
= String( *(::rtl::OUString
*)mAny
.getValue() );
793 DBG(printf ("field type: %s\n", ST(aFieldType
) ));
796 if( aFieldType
== S( "TextField" ) ) {
797 Reference
< XTextField
> rXTextField
;
798 GET( rXTextField
, TextField
);
799 if( rXTextField
.is() ) {
800 rXPropSet
.set( rXTextField
, UNO_QUERY
);
801 if( rXPropSet
.is() ) {
802 String
aFieldKind( rXTextField
->getPresentation( TRUE
) );
803 DBG(printf ("field kind: %s\n", ST(aFieldKind
) ));
804 if( aFieldKind
== S( "Page" ) ) {
814 void DrawingML::GetUUID( OStringBuffer
& rBuffer
)
816 Sequence
< sal_uInt8
> aSeq( 16 );
817 static char cDigits
[17] = "0123456789ABCDEF";
818 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
821 rBuffer
.append( '{' );
822 for( i
= 0; i
< 4; i
++ ) {
823 rBuffer
.append( cDigits
[ aSeq
[i
] >> 4 ] );
824 rBuffer
.append( cDigits
[ aSeq
[i
] && 0xf ] );
826 rBuffer
.append( '-' );
827 for( ; i
< 6; i
++ ) {
828 rBuffer
.append( cDigits
[ aSeq
[i
] >> 4 ] );
829 rBuffer
.append( cDigits
[ aSeq
[i
] && 0xf ] );
831 rBuffer
.append( '-' );
832 for( ; i
< 8; i
++ ) {
833 rBuffer
.append( cDigits
[ aSeq
[i
] >> 4 ] );
834 rBuffer
.append( cDigits
[ aSeq
[i
] && 0xf ] );
836 rBuffer
.append( '-' );
837 for( ; i
< 10; i
++ ) {
838 rBuffer
.append( cDigits
[ aSeq
[i
] >> 4 ] );
839 rBuffer
.append( cDigits
[ aSeq
[i
] && 0xf ] );
841 rBuffer
.append( '-' );
842 for( ; i
< 16; i
++ ) {
843 rBuffer
.append( cDigits
[ aSeq
[i
] >> 4 ] );
844 rBuffer
.append( cDigits
[ aSeq
[i
] && 0xf ] );
846 rBuffer
.append( '}' );
849 void DrawingML::WriteRun( Reference
< XTextRange
> rRun
)
851 const char* sFieldType
;
852 bool bIsField
= false;
853 OUString sText
= rRun
->getString();
855 if( sText
.getLength() < 1)
858 if( ( sFieldType
= GetFieldType( rRun
) ) ) {
859 OStringBuffer
sUUID(39);
862 mpFS
->startElementNS( XML_a
, XML_fld
,
863 XML_id
, sUUID
.getStr(),
864 XML_type
, sFieldType
,
868 mpFS
->startElementNS( XML_a
, XML_r
, FSEND
);
870 WriteRunProperties( rRun
);
872 mpFS
->startElementNS( XML_a
, XML_t
, FSEND
);
873 mpFS
->writeEscaped( sText
);
874 mpFS
->endElementNS( XML_a
, XML_t
);
877 mpFS
->endElementNS( XML_a
, XML_fld
);
879 mpFS
->endElementNS( XML_a
, XML_r
);
884 pAutoNumType = #x "ParenBoth"; \
885 else if( bPBehind ) \
886 pAutoNumType = #x "ParenR"; \
888 pAutoNumType = #x "Period";
891 inline static const char* GetAutoNumType( sal_Int16 nNumberingType
, bool bSDot
, bool bPBehind
, bool bPBoth
)
893 const char* pAutoNumType
= NULL
;
895 switch( (SvxExtNumType
)nNumberingType
)
897 case SVX_NUM_CHARS_UPPER_LETTER_N
:
898 case SVX_NUM_CHARS_UPPER_LETTER
:
901 case SVX_NUM_CHARS_LOWER_LETTER_N
:
902 case SVX_NUM_CHARS_LOWER_LETTER
:
905 case SVX_NUM_ROMAN_UPPER
:
908 case SVX_NUM_ROMAN_LOWER
:
911 case SVX_NUM_ARABIC
:
914 pAutoNumType
= "arabicPlain";
923 void DrawingML::WriteParagraphNumbering( Reference
< XPropertySet
> rXPropSet
, sal_Int16 nLevel
)
925 if( nLevel
>= 0 && GETA( NumberingRules
) )
927 Reference
< XIndexAccess
> rXIndexAccess
;
929 if ( ( mAny
>>= rXIndexAccess
) && nLevel
< rXIndexAccess
->getCount() )
931 DBG(printf ("numbering rules\n"));
933 Sequence
< PropertyValue
> aPropertySequence
;
934 rXIndexAccess
->getByIndex( nLevel
) >>= aPropertySequence
;
937 const PropertyValue
* pPropValue
= aPropertySequence
.getArray();
939 sal_Int32 nPropertyCount
= aPropertySequence
.getLength();
941 if ( nPropertyCount
) {
943 sal_Int16 nNumberingType
= -1;
945 bool bPBehind
= false;
947 sal_Unicode aBulletChar
= 0x2022; // a bullet
948 awt::FontDescriptor aFontDesc
;
949 bool bHasFontDesc
= false;
950 OUString aGraphicURL
;
951 sal_Int16 nBulletRelSize
= 0;
953 for ( sal_Int32 i
= 0; i
< nPropertyCount
; i
++ ) {
954 const void* pValue
= pPropValue
[ i
].Value
.getValue();
956 OUString
aPropName( pPropValue
[ i
].Name
);
957 DBG(printf ("pro name: %s\n", OUStringToOString( aPropName
, RTL_TEXTENCODING_UTF8
).getStr()));
958 if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "NumberingType" ) ) )
959 nNumberingType
= *( (sal_Int16
*)pValue
);
960 else if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Prefix" ) ) ) {
961 if( *(OUString
*)pValue
== US( ")" ) )
963 } else if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Suffix" ) ) ) {
964 if( *(OUString
*)pValue
== US( "." ) )
966 else if( *(OUString
*)pValue
== US( ")" ) )
968 } else if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletChar" ) ) )
970 aBulletChar
= String ( *( (String
*)pValue
) ).GetChar( 0 );
971 //printf ("bullet char: %d\n", aBulletChar.getStr());
973 else if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletFont" ) ) )
975 aFontDesc
= *( (awt::FontDescriptor
*)pValue
);
978 // Our numbullet dialog has set the wrong textencoding for our "StarSymbol" font,
979 // instead of a Unicode encoding the encoding RTL_TEXTENCODING_SYMBOL was used.
980 // Because there might exist a lot of damaged documemts I added this two lines
981 // which fixes the bullet problem for the export.
982 if ( aFontDesc
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StarSymbol" ) ) )
983 aFontDesc
.CharSet
= RTL_TEXTENCODING_MS_1252
;
985 } else if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletRelSize" ) ) ) {
986 nBulletRelSize
= *( (sal_Int16
*)pValue
);
987 } else if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicURL" ) ) ) {
988 aGraphicURL
= ( *(OUString
*)pValue
);
989 DBG(printf ("graphic url: %s\n", OUStringToOString( aGraphicURL
, RTL_TEXTENCODING_UTF8
).getStr()));
990 } else if ( aPropName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicSize" ) ) )
992 if ( pPropValue
[ i
].Value
.getValueType() == ::getCppuType( (awt::Size
*)0) )
994 // don't cast awt::Size to Size as on 64-bits they are not the same.
995 ::com::sun::star::awt::Size aSize
;
996 pPropValue
[ i
].Value
>>= aSize
;
997 //aBuGraSize.nA = aSize.Width;
998 //aBuGraSize.nB = aSize.Height;
999 DBG(printf("graphic size: %dx%d\n", int( aSize
.Width
), int( aSize
.Height
)));
1005 const char* pAutoNumType
= GetAutoNumType( nNumberingType
, bSDot
, bPBehind
, bPBoth
);
1008 if( aGraphicURL
.getLength() > 0 ) {
1009 OUString sRelId
= WriteImage( aGraphicURL
);
1011 mpFS
->startElementNS( XML_a
, XML_buBlip
, FSEND
);
1012 mpFS
->singleElementNS( XML_a
, XML_blip
, FSNS( XML_r
, XML_embed
), USS( sRelId
), FSEND
);
1013 mpFS
->endElementNS( XML_a
, XML_buBlip
);
1015 if( nBulletRelSize
&& nBulletRelSize
!= 100 )
1016 mpFS
->singleElementNS( XML_a
, XML_buSzPct
,
1017 XML_val
, IS( 1000*( (sal_Int32
)nBulletRelSize
) ), FSEND
);
1019 mpFS
->singleElementNS( XML_a
, XML_buFont
,
1020 XML_typeface
, OUStringToOString( aFontDesc
.Name
, RTL_TEXTENCODING_UTF8
).getStr(),
1021 XML_charset
, (aFontDesc
.CharSet
== awt::CharSet::SYMBOL
) ? "2" : NULL
,
1025 mpFS
->singleElementNS( XML_a
, XML_buAutoNum
, XML_type
, pAutoNumType
, FSEND
);
1027 aBulletChar
= SubstituteBullet( aBulletChar
, aFontDesc
);
1028 mpFS
->singleElementNS( XML_a
, XML_buChar
, XML_char
, USS( OUString( aBulletChar
) ), FSEND
);
1037 const char* DrawingML::GetAlignment( sal_Int32 nAlignment
)
1039 const char* sAlignment
= NULL
;
1041 switch( nAlignment
) {
1042 case style::ParagraphAdjust_CENTER
:
1045 case style::ParagraphAdjust_RIGHT
:
1048 case style::ParagraphAdjust_BLOCK
:
1049 sAlignment
= "just";
1058 void DrawingML::WriteParagraphProperties( Reference
< XTextContent
> rParagraph
)
1060 Reference
< XPropertySet
> rXPropSet( rParagraph
, UNO_QUERY
);
1061 Reference
< XPropertyState
> rXPropState( rParagraph
, UNO_QUERY
);
1063 if( !rXPropSet
.is() || !rXPropState
.is() )
1066 sal_Int16 nLevel
= -1;
1067 GET( nLevel
, NumberingLevel
);
1069 sal_Int32 nLeftMargin
= 0;
1071 //GET( nLeftMargin, ParaLeftMargin );
1073 sal_Int16
nAlignment( style::ParagraphAdjust_LEFT
);
1074 GET( nAlignment
, ParaAdjust
);
1078 || nAlignment
!= style::ParagraphAdjust_LEFT
) {
1079 mpFS
->startElementNS( XML_a
, XML_pPr
,
1080 XML_lvl
, nLevel
> 0 ? I32S( nLevel
) : NULL
,
1081 XML_marL
, nLeftMargin
> 0 ? IS( nLeftMargin
) : NULL
,
1082 XML_algn
, GetAlignment( nAlignment
),
1085 WriteParagraphNumbering( rXPropSet
, nLevel
);
1087 mpFS
->endElementNS( XML_a
, XML_pPr
);
1091 void DrawingML::WriteParagraph( Reference
< XTextContent
> rParagraph
)
1093 Reference
< XEnumerationAccess
> access( rParagraph
, UNO_QUERY
);
1097 Reference
< XEnumeration
> enumeration( access
->createEnumeration() );
1098 if( !enumeration
.is() )
1101 mpFS
->startElementNS( XML_a
, XML_p
, FSEND
);
1103 sal_Bool bPropertiesWritten
= FALSE
;
1104 while( enumeration
->hasMoreElements() ) {
1105 Reference
< XTextRange
> run
;
1106 Any
any ( enumeration
->nextElement() );
1109 if( !bPropertiesWritten
&& run
->getString().getLength() ) {
1110 WriteParagraphProperties( rParagraph
);
1111 bPropertiesWritten
= TRUE
;
1116 mpFS
->singleElementNS( XML_a
, XML_endParaRPr
, FSEND
);
1118 mpFS
->endElementNS( XML_a
, XML_p
);
1121 void DrawingML::WriteText( Reference
< XShape
> rXShape
)
1123 Reference
< XText
> xXText( rXShape
, UNO_QUERY
);
1124 Reference
< XPropertySet
> rXPropSet( rXShape
, UNO_QUERY
);
1129 #define DEFLRINS 254
1130 #define DEFTBINS 127
1131 sal_Int32 nLeft
, nRight
, nTop
, nBottom
;
1132 nLeft
= nRight
= DEFLRINS
;
1133 nTop
= nBottom
= DEFTBINS
;
1135 // top inset looks a bit different compared to ppt export
1136 // check if something related doesn't work as expected
1137 GET( nLeft
, TextLeftDistance
);
1138 GET( nRight
, TextRightDistance
);
1139 GET( nTop
, TextUpperDistance
);
1140 GET( nBottom
, TextLowerDistance
);
1142 TextVerticalAdjust
eVerticalAlignment( TextVerticalAdjust_TOP
);
1143 const char* sVerticalAlignment
= NULL
;
1144 GET( eVerticalAlignment
, TextVerticalAdjust
);
1145 switch( eVerticalAlignment
) {
1146 case TextVerticalAdjust_BOTTOM
:
1147 sVerticalAlignment
= "b";
1149 case TextVerticalAdjust_CENTER
:
1150 sVerticalAlignment
= "ctr";
1152 case TextVerticalAdjust_TOP
:
1157 TextHorizontalAdjust
eHorizontalAlignment( TextHorizontalAdjust_CENTER
);
1158 bool bHorizontalCenter
= false;
1159 GET( eHorizontalAlignment
, TextHorizontalAdjust
);
1160 if( eHorizontalAlignment
== TextHorizontalAdjust_CENTER
)
1161 bHorizontalCenter
= true;
1163 sal_Bool bHasWrap
= FALSE
;
1164 sal_Bool bWrap
= FALSE
;
1165 if( GETA( TextWordWrap
) ) {
1168 //DBG(printf("wrap: %d\n", bWrap));
1171 mpFS
->singleElementNS( XML_a
, XML_bodyPr
,
1172 XML_wrap
, bHasWrap
&& !bWrap
? "none" : NULL
,
1173 XML_lIns
, (nLeft
!= DEFLRINS
) ? IS( MM100toEMU( nLeft
) ) : NULL
,
1174 XML_rIns
, (nRight
!= DEFLRINS
) ? IS( MM100toEMU( nRight
) ) : NULL
,
1175 XML_tIns
, (nTop
!= DEFTBINS
) ? IS( MM100toEMU( nTop
) ) : NULL
,
1176 XML_bIns
, (nBottom
!= DEFTBINS
) ? IS( MM100toEMU( nBottom
) ) : NULL
,
1177 XML_anchor
, sVerticalAlignment
,
1178 XML_anchorCtr
, bHorizontalCenter
? "1" : NULL
,
1181 Reference
< XEnumerationAccess
> access( xXText
, UNO_QUERY
);
1185 Reference
< XEnumeration
> enumeration( access
->createEnumeration() );
1186 if( !enumeration
.is() )
1189 while( enumeration
->hasMoreElements() ) {
1190 Reference
< XTextContent
> paragraph
;
1191 Any
any ( enumeration
->nextElement() );
1193 if( any
>>= paragraph
)
1194 WriteParagraph( paragraph
);
1199 void DrawingML::WritePresetShape( const char* pShape
)
1201 mpFS
->startElementNS( XML_a
, XML_prstGeom
,
1204 mpFS
->singleElementNS( XML_a
, XML_avLst
, FSEND
);
1205 mpFS
->endElementNS( XML_a
, XML_prstGeom
);
1208 void DrawingML::WritePresetShape( const char* pShape
, MSO_SPT eShapeType
, sal_Bool bPredefinedHandlesUsed
, sal_Int32 nAdjustmentsWhichNeedsToBeConverted
, const PropertyValue
& rProp
)
1210 mpFS
->startElementNS( XML_a
, XML_prstGeom
,
1213 mpFS
->startElementNS( XML_a
, XML_avLst
, FSEND
);
1215 Sequence
< drawing::EnhancedCustomShapeAdjustmentValue
> aAdjustmentSeq
;
1216 if ( rProp
.Value
>>= aAdjustmentSeq
) {
1217 DBG(printf("adj seq len: %d\n", int( aAdjustmentSeq
.getLength() )));
1218 if ( bPredefinedHandlesUsed
)
1219 EscherPropertyContainer::LookForPolarHandles( eShapeType
, nAdjustmentsWhichNeedsToBeConverted
);
1221 sal_Int32 nValue
, nLength
= aAdjustmentSeq
.getLength();
1222 for( sal_Int32 i
=0; i
< nLength
; i
++ )
1223 if( EscherPropertyContainer::GetAdjustmentValue( aAdjustmentSeq
[ i
], i
, nAdjustmentsWhichNeedsToBeConverted
, nValue
) )
1224 mpFS
->singleElementNS( XML_a
, XML_gd
,
1225 XML_name
, nLength
> 1 ? ( OString( "adj" ) + OString::valueOf( i
+ 1 ) ).getStr() : "adj",
1226 XML_fmla
, (OString("val ") + OString::valueOf( nValue
)).getStr(),
1230 mpFS
->endElementNS( XML_a
, XML_avLst
);
1231 mpFS
->endElementNS( XML_a
, XML_prstGeom
);
1234 void DrawingML::WritePolyPolygon( const PolyPolygon
& rPolyPolygon
)
1236 if( rPolyPolygon
.Count() < 1 )
1239 mpFS
->startElementNS( XML_a
, XML_custGeom
, FSEND
);
1240 mpFS
->singleElementNS( XML_a
, XML_avLst
, FSEND
);
1241 mpFS
->singleElementNS( XML_a
, XML_gdLst
, FSEND
);
1242 mpFS
->singleElementNS( XML_a
, XML_ahLst
, FSEND
);
1243 mpFS
->singleElementNS( XML_a
, XML_rect
,
1250 mpFS
->startElementNS( XML_a
, XML_pathLst
, FSEND
);
1252 for( USHORT i
= 0; i
< rPolyPolygon
.Count(); i
++ ) {
1254 const Polygon
& rPoly
= rPolyPolygon
[ i
];
1255 Rectangle
aRect( rPoly
.GetBoundRect() );
1256 sal_Bool bBezier
= FALSE
;
1258 mpFS
->startElementNS( XML_a
, XML_path
,
1259 XML_w
, I64S( aRect
.GetWidth() ),
1260 XML_h
, I64S( aRect
.GetHeight() ),
1263 if( rPoly
.GetSize() > 0 )
1265 mpFS
->startElementNS( XML_a
, XML_moveTo
, FSEND
);
1267 mpFS
->singleElementNS( XML_a
, XML_pt
,
1268 XML_x
, I64S( rPoly
[ 0 ].X() - aRect
.Left() ),
1269 XML_y
, I64S( rPoly
[ 0 ].Y() - aRect
.Top() ),
1272 mpFS
->endElementNS( XML_a
, XML_moveTo
);
1275 for( USHORT j
= 1; j
< rPoly
.GetSize(); j
++ )
1277 enum PolyFlags flags
= rPoly
.GetFlags(j
);
1278 if( flags
== POLY_CONTROL
&& !bBezier
)
1280 mpFS
->startElementNS( XML_a
, XML_cubicBezTo
, FSEND
);
1283 else if( flags
== POLY_NORMAL
&& !bBezier
)
1284 mpFS
->startElementNS( XML_a
, XML_lnTo
, FSEND
);
1286 mpFS
->singleElementNS( XML_a
, XML_pt
,
1287 XML_x
, I64S( rPoly
[j
].X() - aRect
.Left() ),
1288 XML_y
, I64S( rPoly
[j
].Y() - aRect
.Top() ),
1291 if( ( flags
== POLY_NORMAL
|| flags
== POLY_SYMMTR
) && bBezier
)
1293 mpFS
->endElementNS( XML_a
, XML_cubicBezTo
);
1296 else if( flags
== POLY_NORMAL
&& !bBezier
)
1297 mpFS
->endElementNS( XML_a
, XML_lnTo
);
1298 else if( bBezier
&& ( j
% 3 ) == 0 )
1300 // //a:cubicBezTo can only contain 3 //a:pt elements, so we
1301 // need to break things up...
1302 mpFS
->endElementNS( XML_a
, XML_cubicBezTo
);
1303 mpFS
->startElementNS( XML_a
, XML_cubicBezTo
, FSEND
);
1305 // switch( rPoly.GetFlags(j) ) {
1306 // case POLY_NORMAL:
1307 // DBG(printf("normal\n"));
1309 // case POLY_SMOOTH:
1310 // DBG(printf("smooth\n"));
1312 // case POLY_CONTROL:
1313 // DBG(printf("control\n"));
1315 // case POLY_SYMMTR:
1316 // DBG(printf("symmtr\n"));
1319 // DBG(printf("point %ld %ld\n", rPoly[j].X() - aRect.Left(), rPoly[j].Y() - aRect.Top()));
1322 mpFS
->endElementNS( XML_a
, XML_path
);
1325 mpFS
->endElementNS( XML_a
, XML_pathLst
);
1327 mpFS
->endElementNS( XML_a
, XML_custGeom
);
1330 void DrawingML::WriteConnectorConnections( EscherConnectorListEntry
& rConnectorEntry
, sal_Int32 nStartID
, sal_Int32 nEndID
)
1332 mpFS
->singleElementNS( XML_a
, XML_stCxn
,
1333 XML_id
, I32S( nStartID
),
1334 XML_idx
, I64S( rConnectorEntry
.GetConnectorRule( TRUE
) ),
1336 mpFS
->singleElementNS( XML_a
, XML_endCxn
,
1337 XML_id
, I32S( nEndID
),
1338 XML_idx
, I64S( rConnectorEntry
.GetConnectorRule( FALSE
) ),
1342 // from sw/source/filter/ww8/wrtw8num.cxx for default bullets to export to MS intact
1343 static void lcl_SubstituteBullet(String
& rNumStr
, rtl_TextEncoding
& rChrSet
, String
& rFontName
)
1345 StarSymbolToMSMultiFont
*pConvert
= 0;
1346 FontFamily eFamily
= FAMILY_DECORATIVE
;
1350 pConvert
= CreateStarSymbolToMSMultiFont();
1352 sal_Unicode cChar
= rNumStr
.GetChar(0);
1353 String sFont
= pConvert
->ConvertChar(cChar
);
1356 rNumStr
= static_cast< sal_Unicode
>(cChar
| 0xF000);
1358 rChrSet
= RTL_TEXTENCODING_SYMBOL
;
1360 else if ( (rNumStr
.GetChar(0) < 0xE000 || rNumStr
.GetChar(0) > 0xF8FF) )
1363 Ok we can't fit into a known windows unicode font, but
1364 we are not in the private area, so we are a
1365 standardized symbol, so turn off the symbol bit and
1366 let words own font substitution kick in
1368 rChrSet
= RTL_TEXTENCODING_UNICODE
;
1369 eFamily
= FAMILY_SWISS
;
1370 rFontName
= ::GetFontToken(rFontName
, 0);
1375 Well we don't have an available substition, and we're
1376 in our private area, so give up and show a standard
1379 rFontName
.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Wingdings"));
1380 rNumStr
= static_cast< sal_Unicode
>(0x6C);
1385 sal_Unicode
DrawingML::SubstituteBullet( sal_Unicode cBulletId
, ::com::sun::star::awt::FontDescriptor
& rFontDesc
)
1387 String sNumStr
= cBulletId
;
1389 if ( rFontDesc
.Name
.equalsIgnoreAsciiCaseAscii("starsymbol") ||
1390 rFontDesc
.Name
.equalsIgnoreAsciiCaseAscii("opensymbol") ) {
1391 String sFontName
= rFontDesc
.Name
;
1392 rtl_TextEncoding aCharSet
= rFontDesc
.CharSet
;
1394 lcl_SubstituteBullet( sNumStr
, aCharSet
, sFontName
);
1396 rFontDesc
.Name
= sFontName
;
1397 rFontDesc
.CharSet
= aCharSet
;
1400 return sNumStr
.GetChar( 0 );