xref: /trunk/main/oox/source/export/drawingml.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "oox/core/xmlfilterbase.hxx"
29*cdf0e10cSrcweir #include "oox/export/drawingml.hxx"
30*cdf0e10cSrcweir #include "oox/export/utils.hxx"
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include <cstdio>
33*cdf0e10cSrcweir #include <com/sun/star/awt/CharSet.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/awt/FontDescriptor.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/awt/FontSlant.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/awt/FontWeight.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/awt/FontUnderline.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/awt/Gradient.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertyState.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/container/XEnumerationAccess.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/drawing/BitmapMode.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/drawing/LineDash.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/drawing/LineJoint.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/drawing/LineStyle.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/i18n/ScriptType.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/style/ParagraphAdjust.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/text/XText.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/text/XTextContent.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/text/XTextField.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/text/XTextRange.hpp>
56*cdf0e10cSrcweir #include <tools/stream.hxx>
57*cdf0e10cSrcweir #include <tools/string.hxx>
58*cdf0e10cSrcweir #include <vcl/cvtgrf.hxx>
59*cdf0e10cSrcweir #include <unotools/fontcvt.hxx>
60*cdf0e10cSrcweir #include <vcl/graph.hxx>
61*cdf0e10cSrcweir #include <svtools/grfmgr.hxx>
62*cdf0e10cSrcweir #include <rtl/strbuf.hxx>
63*cdf0e10cSrcweir #include <sfx2/app.hxx>
64*cdf0e10cSrcweir #include <svl/languageoptions.hxx>
65*cdf0e10cSrcweir #include <svx/escherex.hxx>
66*cdf0e10cSrcweir #include <svx/svxenum.hxx>
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir using namespace ::com::sun::star;
69*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
70*cdf0e10cSrcweir using namespace ::com::sun::star::drawing;
71*cdf0e10cSrcweir using namespace ::com::sun::star::i18n;
72*cdf0e10cSrcweir using ::com::sun::star::beans::PropertyState;
73*cdf0e10cSrcweir using ::com::sun::star::beans::PropertyValue;
74*cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySet;
75*cdf0e10cSrcweir using ::com::sun::star::beans::XPropertyState;
76*cdf0e10cSrcweir using ::com::sun::star::container::XEnumeration;
77*cdf0e10cSrcweir using ::com::sun::star::container::XEnumerationAccess;
78*cdf0e10cSrcweir using ::com::sun::star::container::XIndexAccess;
79*cdf0e10cSrcweir using ::com::sun::star::io::XOutputStream;
80*cdf0e10cSrcweir using ::com::sun::star::text::XText;
81*cdf0e10cSrcweir using ::com::sun::star::text::XTextContent;
82*cdf0e10cSrcweir using ::com::sun::star::text::XTextField;
83*cdf0e10cSrcweir using ::com::sun::star::text::XTextRange;
84*cdf0e10cSrcweir using ::rtl::OString;
85*cdf0e10cSrcweir using ::rtl::OStringBuffer;
86*cdf0e10cSrcweir using ::rtl::OUString;
87*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
88*cdf0e10cSrcweir using ::sax_fastparser::FSHelperPtr;
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir namespace oox {
93*cdf0e10cSrcweir namespace drawingml {
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir #define GETA(propName) \
96*cdf0e10cSrcweir     GetProperty( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ) )
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir #define GETAD(propName) \
99*cdf0e10cSrcweir     ( GetPropertyAndState( rXPropSet, rXPropState, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir #define GET(variable, propName) \
102*cdf0e10cSrcweir     if ( GETA(propName) ) \
103*cdf0e10cSrcweir         mAny >>= variable;
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir // not thread safe
106*cdf0e10cSrcweir int DrawingML::mnImageCounter = 1;
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir void DrawingML::ResetCounters()
109*cdf0e10cSrcweir {
110*cdf0e10cSrcweir     mnImageCounter = 1;
111*cdf0e10cSrcweir }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir bool DrawingML::GetProperty( Reference< XPropertySet > rXPropSet, String aName )
114*cdf0e10cSrcweir {
115*cdf0e10cSrcweir     bool bRetValue = false;
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir     try {
118*cdf0e10cSrcweir         mAny = rXPropSet->getPropertyValue( aName );
119*cdf0e10cSrcweir         if ( mAny.hasValue() )
120*cdf0e10cSrcweir             bRetValue = true;
121*cdf0e10cSrcweir     } catch( Exception& ) { /* printf ("exception when trying to get value of property: %s\n", ST(aName)); */ }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir     return bRetValue;
124*cdf0e10cSrcweir }
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir bool DrawingML::GetPropertyAndState( Reference< XPropertySet > rXPropSet, Reference< XPropertyState > rXPropState, String aName, PropertyState& eState )
127*cdf0e10cSrcweir {
128*cdf0e10cSrcweir     bool bRetValue = false;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir     try {
131*cdf0e10cSrcweir         mAny = rXPropSet->getPropertyValue( aName );
132*cdf0e10cSrcweir         if ( mAny.hasValue() ) {
133*cdf0e10cSrcweir             bRetValue = true;
134*cdf0e10cSrcweir             eState = rXPropState->getPropertyState( aName );
135*cdf0e10cSrcweir         }
136*cdf0e10cSrcweir     } catch( Exception& ) { /* printf ("exception when trying to get value of property: %s\n", ST(aName)); */ }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir     return bRetValue;
139*cdf0e10cSrcweir }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir void DrawingML::WriteColor( sal_uInt32 nColor )
142*cdf0e10cSrcweir {
143*cdf0e10cSrcweir     OString sColor = OString::valueOf( ( sal_Int64 ) nColor, 16 );
144*cdf0e10cSrcweir     if( sColor.getLength() < 6 ) {
145*cdf0e10cSrcweir         OStringBuffer sBuf( "0" );
146*cdf0e10cSrcweir         int remains = 5 - sColor.getLength();
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir         while( remains > 0 ) {
149*cdf0e10cSrcweir             sBuf.append( "0" );
150*cdf0e10cSrcweir             remains--;
151*cdf0e10cSrcweir         }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir         sBuf.append( sColor );
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir         sColor = sBuf.getStr();
156*cdf0e10cSrcweir     }
157*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_srgbClr, XML_val, sColor.getStr(), FSEND );
158*cdf0e10cSrcweir }
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir void DrawingML::WriteSolidFill( sal_uInt32 nColor )
161*cdf0e10cSrcweir {
162*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_solidFill, FSEND );
163*cdf0e10cSrcweir     WriteColor( nColor );
164*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_solidFill );
165*cdf0e10cSrcweir }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir void DrawingML::WriteSolidFill( Reference< XPropertySet > rXPropSet )
168*cdf0e10cSrcweir {
169*cdf0e10cSrcweir     if ( GetProperty( rXPropSet, S( "FillColor" ) ) )
170*cdf0e10cSrcweir         WriteSolidFill( *((sal_uInt32*) mAny.getValue()) & 0xffffff );
171*cdf0e10cSrcweir }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir void DrawingML::WriteGradientStop( sal_uInt16 nStop, sal_uInt32 nColor )
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_gs,
176*cdf0e10cSrcweir                           XML_pos, I32S( nStop * 1000 ),
177*cdf0e10cSrcweir                           FSEND );
178*cdf0e10cSrcweir     WriteColor( nColor );
179*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_gs );
180*cdf0e10cSrcweir }
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir sal_uInt32 DrawingML::ColorWithIntensity( sal_uInt32 nColor, sal_uInt32 nIntensity )
183*cdf0e10cSrcweir {
184*cdf0e10cSrcweir     return ( ( ( nColor & 0xff ) * nIntensity ) / 100 )
185*cdf0e10cSrcweir         | ( ( ( ( ( nColor & 0xff00 ) >> 8 ) * nIntensity ) / 100 ) << 8 )
186*cdf0e10cSrcweir         | ( ( ( ( ( nColor & 0xff0000 ) >> 8 ) * nIntensity ) / 100 ) << 8 );
187*cdf0e10cSrcweir }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir void DrawingML::WriteGradientFill( Reference< XPropertySet > rXPropSet )
190*cdf0e10cSrcweir {
191*cdf0e10cSrcweir     awt::Gradient aGradient;
192*cdf0e10cSrcweir     if( GETA( FillGradient ) ) {
193*cdf0e10cSrcweir         aGradient = *static_cast< const awt::Gradient* >( mAny.getValue() );
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir         mpFS->startElementNS( XML_a, XML_gradFill, FSEND );
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir         switch( aGradient.Style ) {
198*cdf0e10cSrcweir             default:
199*cdf0e10cSrcweir             case GradientStyle_LINEAR:
200*cdf0e10cSrcweir                 mpFS->startElementNS( XML_a, XML_gsLst, FSEND );
201*cdf0e10cSrcweir                 WriteGradientStop( 0, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) );
202*cdf0e10cSrcweir                 WriteGradientStop( 100, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
203*cdf0e10cSrcweir                 mpFS->endElementNS( XML_a, XML_gsLst );
204*cdf0e10cSrcweir                 mpFS->singleElementNS( XML_a, XML_lin,
205*cdf0e10cSrcweir                                        XML_ang, I32S( ( ( ( 3600 - aGradient.Angle + 900 ) * 6000 ) % 21600000 ) ),
206*cdf0e10cSrcweir                                        FSEND );
207*cdf0e10cSrcweir                 break;
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir             case GradientStyle_AXIAL:
210*cdf0e10cSrcweir                 mpFS->startElementNS( XML_a, XML_gsLst, FSEND );
211*cdf0e10cSrcweir                 WriteGradientStop( 0, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
212*cdf0e10cSrcweir                 WriteGradientStop( 50, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) );
213*cdf0e10cSrcweir                 WriteGradientStop( 100, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
214*cdf0e10cSrcweir                 mpFS->endElementNS( XML_a, XML_gsLst );
215*cdf0e10cSrcweir                 mpFS->singleElementNS( XML_a, XML_lin,
216*cdf0e10cSrcweir                                        XML_ang, I32S( ( ( ( 3600 - aGradient.Angle + 900 ) * 6000 ) % 21600000 ) ),
217*cdf0e10cSrcweir                                        FSEND );
218*cdf0e10cSrcweir                 break;
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir                 /* I don't see how to apply transformation to gradients, so
221*cdf0e10cSrcweir                  * elliptical will end as radial and square as
222*cdf0e10cSrcweir                  * rectangular. also position offsets are not applied */
223*cdf0e10cSrcweir             case GradientStyle_RADIAL:
224*cdf0e10cSrcweir             case GradientStyle_ELLIPTICAL:
225*cdf0e10cSrcweir             case GradientStyle_RECT:
226*cdf0e10cSrcweir             case GradientStyle_SQUARE:
227*cdf0e10cSrcweir                 mpFS->startElementNS( XML_a, XML_gsLst, FSEND );
228*cdf0e10cSrcweir                 WriteGradientStop( 0, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
229*cdf0e10cSrcweir                 WriteGradientStop( 100, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) );
230*cdf0e10cSrcweir                 mpFS->endElementNS( XML_a, XML_gsLst );
231*cdf0e10cSrcweir                 mpFS->singleElementNS( XML_a, XML_path,
232*cdf0e10cSrcweir                                        XML_path, ( aGradient.Style == awt::GradientStyle_RADIAL || aGradient.Style == awt::GradientStyle_ELLIPTICAL ) ? "circle" : "rect",
233*cdf0e10cSrcweir                                        FSEND );
234*cdf0e10cSrcweir                 break;
235*cdf0e10cSrcweir         }
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir         mpFS->endElementNS( XML_a, XML_gradFill );
238*cdf0e10cSrcweir     }
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir }
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir void DrawingML::WriteLineArrow( Reference< XPropertySet > rXPropSet, sal_Bool bLineStart )
243*cdf0e10cSrcweir {
244*cdf0e10cSrcweir     ESCHER_LineEnd eLineEnd;
245*cdf0e10cSrcweir     sal_Int32 nArrowLength;
246*cdf0e10cSrcweir     sal_Int32 nArrowWidth;
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir     if ( EscherPropertyContainer::GetLineArrow( bLineStart, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) ) {
249*cdf0e10cSrcweir         const char* len;
250*cdf0e10cSrcweir         const char* type;
251*cdf0e10cSrcweir         const char* width;
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir         switch( nArrowLength ) {
254*cdf0e10cSrcweir             case ESCHER_LineShortArrow:
255*cdf0e10cSrcweir                 len = "sm";
256*cdf0e10cSrcweir                 break;
257*cdf0e10cSrcweir             default:
258*cdf0e10cSrcweir             case ESCHER_LineMediumLenArrow:
259*cdf0e10cSrcweir                 len = "med";
260*cdf0e10cSrcweir                 break;
261*cdf0e10cSrcweir             case ESCHER_LineLongArrow:
262*cdf0e10cSrcweir                 len = "lg";
263*cdf0e10cSrcweir                 break;
264*cdf0e10cSrcweir         }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir         switch( eLineEnd ) {
267*cdf0e10cSrcweir             default:
268*cdf0e10cSrcweir             case ESCHER_LineNoEnd:
269*cdf0e10cSrcweir                 type = "none";
270*cdf0e10cSrcweir                 break;
271*cdf0e10cSrcweir             case ESCHER_LineArrowEnd:
272*cdf0e10cSrcweir                 type = "triangle";
273*cdf0e10cSrcweir                 break;
274*cdf0e10cSrcweir             case ESCHER_LineArrowStealthEnd:
275*cdf0e10cSrcweir                 type = "stealth";
276*cdf0e10cSrcweir                 break;
277*cdf0e10cSrcweir             case ESCHER_LineArrowDiamondEnd:
278*cdf0e10cSrcweir                 type = "diamond";
279*cdf0e10cSrcweir                 break;
280*cdf0e10cSrcweir             case ESCHER_LineArrowOvalEnd:
281*cdf0e10cSrcweir                 type = "oval";
282*cdf0e10cSrcweir                 break;
283*cdf0e10cSrcweir             case ESCHER_LineArrowOpenEnd:
284*cdf0e10cSrcweir                 type = "arrow";
285*cdf0e10cSrcweir                 break;
286*cdf0e10cSrcweir         }
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir         switch( nArrowWidth ) {
289*cdf0e10cSrcweir             case ESCHER_LineNarrowArrow:
290*cdf0e10cSrcweir                 width = "sm";
291*cdf0e10cSrcweir                 break;
292*cdf0e10cSrcweir             default:
293*cdf0e10cSrcweir             case ESCHER_LineMediumWidthArrow:
294*cdf0e10cSrcweir                 width = "med";
295*cdf0e10cSrcweir                 break;
296*cdf0e10cSrcweir             case ESCHER_LineWideArrow:
297*cdf0e10cSrcweir                 width = "lg";
298*cdf0e10cSrcweir                 break;
299*cdf0e10cSrcweir         }
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir         mpFS->singleElementNS( XML_a, bLineStart ? XML_headEnd : XML_tailEnd,
302*cdf0e10cSrcweir                                XML_len, len,
303*cdf0e10cSrcweir                                XML_type, type,
304*cdf0e10cSrcweir                                XML_w, width,
305*cdf0e10cSrcweir                                FSEND );
306*cdf0e10cSrcweir     }
307*cdf0e10cSrcweir }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir void DrawingML::WriteOutline( Reference< XPropertySet > rXPropSet )
310*cdf0e10cSrcweir {
311*cdf0e10cSrcweir     drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir     GET( aLineStyle, LineStyle );
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir     if( aLineStyle == drawing::LineStyle_NONE )
316*cdf0e10cSrcweir         return;
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir     sal_uInt32 nLineWidth = 0;
319*cdf0e10cSrcweir     sal_uInt32 nColor = 0;
320*cdf0e10cSrcweir     sal_Bool bColorSet = FALSE;
321*cdf0e10cSrcweir     const char* cap = NULL;
322*cdf0e10cSrcweir     drawing::LineDash aLineDash;
323*cdf0e10cSrcweir     sal_Bool bDashSet = FALSE;
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     GET( nLineWidth, LineWidth );
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir     switch( aLineStyle ) {
328*cdf0e10cSrcweir         case drawing::LineStyle_DASH:
329*cdf0e10cSrcweir             if( GETA( LineDash ) ) {
330*cdf0e10cSrcweir                 aLineDash = *(drawing::LineDash*) mAny.getValue();
331*cdf0e10cSrcweir                 bDashSet = TRUE;
332*cdf0e10cSrcweir                 if( aLineDash.Style == DashStyle_ROUND || aLineDash.Style == DashStyle_ROUNDRELATIVE )
333*cdf0e10cSrcweir                     cap = "rnd";
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir                 DBG(printf("dash dots: %d dashes: %d dotlen: %d dashlen: %d distance: %d\n",
336*cdf0e10cSrcweir                             int( aLineDash.Dots ), int( aLineDash.Dashes ), int( aLineDash.DotLen ), int( aLineDash.DashLen ), int( aLineDash.Distance )));
337*cdf0e10cSrcweir             }
338*cdf0e10cSrcweir             /* fallthru intended */
339*cdf0e10cSrcweir         case drawing::LineStyle_SOLID:
340*cdf0e10cSrcweir         default:
341*cdf0e10cSrcweir             if ( GETA( LineColor ) ) {
342*cdf0e10cSrcweir                 nColor = *((sal_uInt32*) mAny.getValue()) & 0xffffff;
343*cdf0e10cSrcweir                 bColorSet = TRUE;
344*cdf0e10cSrcweir             }
345*cdf0e10cSrcweir             break;
346*cdf0e10cSrcweir     }
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_ln,
349*cdf0e10cSrcweir                           XML_cap, cap,
350*cdf0e10cSrcweir                           XML_w, nLineWidth > 1 ? I64S( MM100toEMU( nLineWidth ) ) : NULL,
351*cdf0e10cSrcweir                           FSEND );
352*cdf0e10cSrcweir     if( bColorSet )
353*cdf0e10cSrcweir         WriteSolidFill( nColor );
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir     if( bDashSet ) {
356*cdf0e10cSrcweir         mpFS->startElementNS( XML_a, XML_custDash, FSEND );
357*cdf0e10cSrcweir         int i;
358*cdf0e10cSrcweir         for( i = 0; i < aLineDash.Dots; i ++ )
359*cdf0e10cSrcweir             mpFS->singleElementNS( XML_a, XML_ds,
360*cdf0e10cSrcweir                                    XML_d, aLineDash.DotLen ? I64S( aLineDash.DotLen*1000 ) : "100000",
361*cdf0e10cSrcweir                                    XML_sp, I64S( aLineDash.Distance*1000 ),
362*cdf0e10cSrcweir                                    FSEND );
363*cdf0e10cSrcweir         for( i = 0; i < aLineDash.Dashes; i ++ )
364*cdf0e10cSrcweir             mpFS->singleElementNS( XML_a, XML_ds,
365*cdf0e10cSrcweir                                    XML_d, aLineDash.DashLen ? I64S( aLineDash.DashLen*1000 ) : "100000",
366*cdf0e10cSrcweir                                    XML_sp, I64S( aLineDash.Distance*1000 ),
367*cdf0e10cSrcweir                                    FSEND );
368*cdf0e10cSrcweir         mpFS->endElementNS( XML_a, XML_custDash );
369*cdf0e10cSrcweir     }
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir     if( nLineWidth > 1 && GETA( LineJoint ) ) {
372*cdf0e10cSrcweir         LineJoint eLineJoint;
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir         mAny >>= eLineJoint;
375*cdf0e10cSrcweir         switch( eLineJoint ) {
376*cdf0e10cSrcweir             case LineJoint_NONE:
377*cdf0e10cSrcweir             case LineJoint_MIDDLE:
378*cdf0e10cSrcweir             case LineJoint_BEVEL:
379*cdf0e10cSrcweir                 mpFS->singleElementNS( XML_a, XML_bevel, FSEND );
380*cdf0e10cSrcweir                 break;
381*cdf0e10cSrcweir             default:
382*cdf0e10cSrcweir             case LineJoint_MITER:
383*cdf0e10cSrcweir                 mpFS->singleElementNS( XML_a, XML_miter, FSEND );
384*cdf0e10cSrcweir                 break;
385*cdf0e10cSrcweir             case LineJoint_ROUND:
386*cdf0e10cSrcweir                 mpFS->singleElementNS( XML_a, XML_round, FSEND );
387*cdf0e10cSrcweir                 break;
388*cdf0e10cSrcweir         }
389*cdf0e10cSrcweir     }
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir     WriteLineArrow( rXPropSet, sal_True );
392*cdf0e10cSrcweir     WriteLineArrow( rXPropSet, sal_False );
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_ln );
395*cdf0e10cSrcweir }
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir OUString DrawingML::WriteImage( const OUString& rURL )
398*cdf0e10cSrcweir {
399*cdf0e10cSrcweir     ByteString aURLBS( UniString( rURL ), RTL_TEXTENCODING_UTF8 );
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir     const char aURLBegin[] = "vnd.sun.star.GraphicObject:";
402*cdf0e10cSrcweir     int index = aURLBS.Search( aURLBegin );
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir     if ( index != STRING_NOTFOUND ) {
405*cdf0e10cSrcweir         DBG(printf ("begin: %ld %s\n", long( sizeof( aURLBegin ) ), USS( rURL ) + sizeof( aURLBegin ) - 1 ));
406*cdf0e10cSrcweir         aURLBS.Erase( 0, sizeof( aURLBegin ) - 1 );
407*cdf0e10cSrcweir         Graphic aGraphic = GraphicObject( aURLBS ).GetTransformedGraphic ();
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir         return WriteImage( aGraphic );
410*cdf0e10cSrcweir     } else {
411*cdf0e10cSrcweir         // add link to relations
412*cdf0e10cSrcweir     }
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir     return OUString();
415*cdf0e10cSrcweir }
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir OUString DrawingML::WriteImage( const Graphic& rGraphic )
418*cdf0e10cSrcweir {
419*cdf0e10cSrcweir     GfxLink aLink = rGraphic.GetLink ();
420*cdf0e10cSrcweir     OUString sMediaType;
421*cdf0e10cSrcweir     const char* sExtension = NULL;
422*cdf0e10cSrcweir     OUString sRelId;
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir     SvMemoryStream aStream;
425*cdf0e10cSrcweir     const void* aData = aLink.GetData();
426*cdf0e10cSrcweir     sal_Size nDataSize = aLink.GetDataSize();
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir     switch ( aLink.GetType() ) {
429*cdf0e10cSrcweir         case GFX_LINK_TYPE_NATIVE_GIF:
430*cdf0e10cSrcweir             sMediaType = US( "image/gif" );
431*cdf0e10cSrcweir             sExtension = ".gif";
432*cdf0e10cSrcweir             break;
433*cdf0e10cSrcweir         case GFX_LINK_TYPE_NATIVE_JPG:
434*cdf0e10cSrcweir             sMediaType = US( "image/jpeg" );
435*cdf0e10cSrcweir             sExtension = ".jpeg";
436*cdf0e10cSrcweir             break;
437*cdf0e10cSrcweir         case GFX_LINK_TYPE_NATIVE_PNG:
438*cdf0e10cSrcweir             sMediaType = US( "image/png" );
439*cdf0e10cSrcweir             sExtension = ".png";
440*cdf0e10cSrcweir             break;
441*cdf0e10cSrcweir         case GFX_LINK_TYPE_NATIVE_TIF:
442*cdf0e10cSrcweir             sMediaType = US( "image/tiff" );
443*cdf0e10cSrcweir             sExtension = ".tiff";
444*cdf0e10cSrcweir             break;
445*cdf0e10cSrcweir         case GFX_LINK_TYPE_NATIVE_WMF:
446*cdf0e10cSrcweir             sMediaType = US( "image/x-wmf" );
447*cdf0e10cSrcweir             sExtension = ".wmf";
448*cdf0e10cSrcweir             break;
449*cdf0e10cSrcweir         case GFX_LINK_TYPE_NATIVE_MET:
450*cdf0e10cSrcweir             sMediaType = US( "image/x-met" );
451*cdf0e10cSrcweir             sExtension = ".met";
452*cdf0e10cSrcweir             break;
453*cdf0e10cSrcweir         case GFX_LINK_TYPE_NATIVE_PCT:
454*cdf0e10cSrcweir             sMediaType = US( "image/x-pict" );
455*cdf0e10cSrcweir             sExtension = ".pct";
456*cdf0e10cSrcweir             break;
457*cdf0e10cSrcweir         default: {
458*cdf0e10cSrcweir             GraphicType aType = rGraphic.GetType();
459*cdf0e10cSrcweir             if ( aType == GRAPHIC_BITMAP ) {
460*cdf0e10cSrcweir                 GraphicConverter::Export( aStream, rGraphic, CVT_PNG );
461*cdf0e10cSrcweir                 sMediaType = US( "image/png" );
462*cdf0e10cSrcweir                 sExtension = ".png";
463*cdf0e10cSrcweir             } else if ( aType == GRAPHIC_GDIMETAFILE ) {
464*cdf0e10cSrcweir                 GraphicConverter::Export( aStream, rGraphic, CVT_EMF );
465*cdf0e10cSrcweir                 sMediaType = US( "image/x-emf" );
466*cdf0e10cSrcweir                 sExtension = ".emf";
467*cdf0e10cSrcweir             } else {
468*cdf0e10cSrcweir                 OSL_TRACE( "unhandled graphic type" );
469*cdf0e10cSrcweir                 break;
470*cdf0e10cSrcweir             }
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir             aData = aStream.GetData();
473*cdf0e10cSrcweir             nDataSize = aStream.GetSize();
474*cdf0e10cSrcweir             break;
475*cdf0e10cSrcweir             }
476*cdf0e10cSrcweir     }
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir     const char *pComponent = NULL;
479*cdf0e10cSrcweir     switch ( meDocumentType )
480*cdf0e10cSrcweir     {
481*cdf0e10cSrcweir         case DOCUMENT_DOCX: pComponent = "word"; break;
482*cdf0e10cSrcweir         case DOCUMENT_PPTX: pComponent = "ppt"; break;
483*cdf0e10cSrcweir         case DOCUMENT_XLSX: pComponent = "xl"; break;
484*cdf0e10cSrcweir     }
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir     Reference< XOutputStream > xOutStream = mpFB->openOutputStream( OUStringBuffer()
487*cdf0e10cSrcweir                                                                     .appendAscii( pComponent )
488*cdf0e10cSrcweir                                                                     .appendAscii( "/media/image" )
489*cdf0e10cSrcweir                                                                     .append( (sal_Int32) mnImageCounter )
490*cdf0e10cSrcweir                                                                     .appendAscii( sExtension )
491*cdf0e10cSrcweir                                                                     .makeStringAndClear(),
492*cdf0e10cSrcweir                                                                     sMediaType );
493*cdf0e10cSrcweir     xOutStream->writeBytes( Sequence< sal_Int8 >( (const sal_Int8*) aData, nDataSize ) );
494*cdf0e10cSrcweir     xOutStream->closeOutput();
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir     const char *pImagePrefix = NULL;
497*cdf0e10cSrcweir     switch ( meDocumentType )
498*cdf0e10cSrcweir     {
499*cdf0e10cSrcweir         case DOCUMENT_DOCX:
500*cdf0e10cSrcweir             pImagePrefix = "media/image";
501*cdf0e10cSrcweir             break;
502*cdf0e10cSrcweir         case DOCUMENT_PPTX:
503*cdf0e10cSrcweir         case DOCUMENT_XLSX:
504*cdf0e10cSrcweir             pImagePrefix = "../media/image";
505*cdf0e10cSrcweir             break;
506*cdf0e10cSrcweir     }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir     sRelId = mpFB->addRelation( mpFS->getOutputStream(),
509*cdf0e10cSrcweir                                 US( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ),
510*cdf0e10cSrcweir                                 OUStringBuffer()
511*cdf0e10cSrcweir                                 .appendAscii( pImagePrefix )
512*cdf0e10cSrcweir                                 .append( (sal_Int32) mnImageCounter ++ )
513*cdf0e10cSrcweir                                 .appendAscii( sExtension )
514*cdf0e10cSrcweir                                 .makeStringAndClear() );
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir     return sRelId;
517*cdf0e10cSrcweir }
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir OUString DrawingML::WriteBlip( OUString& rURL )
520*cdf0e10cSrcweir {
521*cdf0e10cSrcweir         OUString sRelId = WriteImage( rURL );
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir         mpFS->singleElementNS( XML_a, XML_blip,
524*cdf0e10cSrcweir                                FSNS( XML_r, XML_embed), OUStringToOString( sRelId, RTL_TEXTENCODING_UTF8 ).getStr(),
525*cdf0e10cSrcweir                                FSEND );
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir         return sRelId;
528*cdf0e10cSrcweir }
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir void DrawingML::WriteBlipMode( Reference< XPropertySet > rXPropSet )
531*cdf0e10cSrcweir {
532*cdf0e10cSrcweir     BitmapMode eBitmapMode( BitmapMode_NO_REPEAT );
533*cdf0e10cSrcweir     if (GetProperty( rXPropSet, S( "FillBitmapMode" ) ) )
534*cdf0e10cSrcweir         mAny >>= eBitmapMode;
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir     DBG(printf("fill bitmap mode: %d\n", eBitmapMode));
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir     switch (eBitmapMode) {
539*cdf0e10cSrcweir     case BitmapMode_REPEAT:
540*cdf0e10cSrcweir         mpFS->singleElementNS( XML_a, XML_tile, FSEND );
541*cdf0e10cSrcweir         break;
542*cdf0e10cSrcweir     default:
543*cdf0e10cSrcweir         ;
544*cdf0e10cSrcweir     }
545*cdf0e10cSrcweir }
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir void DrawingML::WriteBlipFill( Reference< XPropertySet > rXPropSet, String sURLPropName )
548*cdf0e10cSrcweir {
549*cdf0e10cSrcweir     WriteBlipFill( rXPropSet, sURLPropName, XML_a );
550*cdf0e10cSrcweir }
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir void DrawingML::WriteBlipFill( Reference< XPropertySet > rXPropSet, String sURLPropName, sal_Int32 nXmlNamespace )
553*cdf0e10cSrcweir {
554*cdf0e10cSrcweir     if ( GetProperty( rXPropSet, sURLPropName ) ) {
555*cdf0e10cSrcweir         OUString aURL;
556*cdf0e10cSrcweir         mAny >>= aURL;
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir         DBG(printf ("URL: %s\n", OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr() ));
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir         if( !aURL.getLength() )
561*cdf0e10cSrcweir             return;
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir         mpFS->startElementNS( nXmlNamespace , XML_blipFill, FSEND );
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir         WriteBlip( aURL );
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir         if( sURLPropName == S( "FillBitmapURL" ) )
568*cdf0e10cSrcweir             WriteBlipMode( rXPropSet );
569*cdf0e10cSrcweir         else if( GetProperty( rXPropSet, S( "FillBitmapStretch" ) ) ) {
570*cdf0e10cSrcweir                 bool bStretch = false;
571*cdf0e10cSrcweir                 mAny >>= bStretch;
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir                 if( bStretch )
574*cdf0e10cSrcweir                     WriteStretch();
575*cdf0e10cSrcweir         }
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir         mpFS->endElementNS( nXmlNamespace, XML_blipFill );
578*cdf0e10cSrcweir     }
579*cdf0e10cSrcweir }
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir void DrawingML::WriteStretch()
582*cdf0e10cSrcweir {
583*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_stretch, FSEND );
584*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_fillRect, FSEND );
585*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_stretch );
586*cdf0e10cSrcweir }
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir void DrawingML::WriteTransformation( const Rectangle& rRect,
589*cdf0e10cSrcweir         sal_Bool bFlipH, sal_Bool bFlipV, sal_Int32 nRotation )
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_xfrm,
592*cdf0e10cSrcweir                           XML_flipH, bFlipH ? "1" : NULL,
593*cdf0e10cSrcweir                           XML_flipV, bFlipV ? "1" : NULL,
594*cdf0e10cSrcweir                           XML_rot, nRotation ? I32S( nRotation ) : NULL,
595*cdf0e10cSrcweir                           FSEND );
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_off, XML_x, IS( MM100toEMU( rRect.Left() ) ), XML_y, IS( MM100toEMU( rRect.Top() ) ), FSEND );
598*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_ext, XML_cx, IS( MM100toEMU( rRect.GetWidth() ) ), XML_cy, IS( MM100toEMU( rRect.GetHeight() ) ), FSEND );
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_xfrm );
601*cdf0e10cSrcweir }
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir void DrawingML::WriteShapeTransformation( Reference< XShape > rXShape, sal_Bool bFlipH, sal_Bool bFlipV, sal_Int32 nRotation )
604*cdf0e10cSrcweir {
605*cdf0e10cSrcweir     DBG(printf( "write shape transformation\n" ));
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir     awt::Point aPos = rXShape->getPosition();
608*cdf0e10cSrcweir     awt::Size aSize = rXShape->getSize();
609*cdf0e10cSrcweir 
610*cdf0e10cSrcweir     WriteTransformation( Rectangle( Point( aPos.X, aPos.Y ), Size( aSize.Width, aSize.Height ) ), bFlipH, bFlipV, nRotation );
611*cdf0e10cSrcweir }
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir void DrawingML::WriteRunProperties( Reference< XTextRange > rRun )
614*cdf0e10cSrcweir {
615*cdf0e10cSrcweir     Reference< XPropertySet > rXPropSet( rRun, UNO_QUERY );
616*cdf0e10cSrcweir     Reference< XPropertyState > rXPropState( rRun, UNO_QUERY );
617*cdf0e10cSrcweir     OUString usLanguage;
618*cdf0e10cSrcweir     PropertyState eState;
619*cdf0e10cSrcweir     sal_Int16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
620*cdf0e10cSrcweir     sal_Bool bComplex = ( nScriptType == ScriptType::COMPLEX );
621*cdf0e10cSrcweir     const char* bold = NULL;
622*cdf0e10cSrcweir     const char* italic = NULL;
623*cdf0e10cSrcweir     const char* underline = NULL;
624*cdf0e10cSrcweir     sal_Int32 nSize = 1800;
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir     if( GETAD( CharHeight ) )
627*cdf0e10cSrcweir         nSize = (sal_Int32) (100*(*((float*) mAny.getValue())));
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir     if ( ( bComplex && GETAD( CharWeightComplex ) ) || GETAD( CharWeight ) )
630*cdf0e10cSrcweir         if ( *((float*) mAny.getValue()) >= awt::FontWeight::SEMIBOLD )
631*cdf0e10cSrcweir             bold = "1";
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir     if ( ( bComplex && GETAD( CharPostureComplex ) ) || GETAD( CharPosture ) )
634*cdf0e10cSrcweir         switch ( *((awt::FontSlant*) mAny.getValue()) )
635*cdf0e10cSrcweir         {
636*cdf0e10cSrcweir             case awt::FontSlant_OBLIQUE :
637*cdf0e10cSrcweir             case awt::FontSlant_ITALIC :
638*cdf0e10cSrcweir                 italic = "1";
639*cdf0e10cSrcweir                 break;
640*cdf0e10cSrcweir             default:
641*cdf0e10cSrcweir                 break;
642*cdf0e10cSrcweir         }
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir     if ( GETAD( CharUnderline ) )
645*cdf0e10cSrcweir         switch ( *((sal_Int16*) mAny.getValue()) )
646*cdf0e10cSrcweir         {
647*cdf0e10cSrcweir             case awt::FontUnderline::SINGLE :
648*cdf0e10cSrcweir                 underline = "sng";
649*cdf0e10cSrcweir                 break;
650*cdf0e10cSrcweir             case awt::FontUnderline::DOUBLE :
651*cdf0e10cSrcweir                 underline = "dbl";
652*cdf0e10cSrcweir                 break;
653*cdf0e10cSrcweir             case awt::FontUnderline::DOTTED :
654*cdf0e10cSrcweir                 underline = "dotted";
655*cdf0e10cSrcweir                 break;
656*cdf0e10cSrcweir             case awt::FontUnderline::DASH :
657*cdf0e10cSrcweir                 underline = "dash";
658*cdf0e10cSrcweir                 break;
659*cdf0e10cSrcweir             case awt::FontUnderline::LONGDASH :
660*cdf0e10cSrcweir                 underline = "dashLong";
661*cdf0e10cSrcweir                 break;
662*cdf0e10cSrcweir             case awt::FontUnderline::DASHDOT :
663*cdf0e10cSrcweir                 underline = "dotDash";
664*cdf0e10cSrcweir                 break;
665*cdf0e10cSrcweir             case awt::FontUnderline::DASHDOTDOT :
666*cdf0e10cSrcweir                 underline = "dotDotDash";
667*cdf0e10cSrcweir                 break;
668*cdf0e10cSrcweir             case awt::FontUnderline::WAVE :
669*cdf0e10cSrcweir                 underline = "wavy";
670*cdf0e10cSrcweir                 break;
671*cdf0e10cSrcweir             case awt::FontUnderline::DOUBLEWAVE :
672*cdf0e10cSrcweir                 underline = "wavyDbl";
673*cdf0e10cSrcweir                 break;
674*cdf0e10cSrcweir             case awt::FontUnderline::BOLD :
675*cdf0e10cSrcweir                 underline = "heavy";
676*cdf0e10cSrcweir                 break;
677*cdf0e10cSrcweir             case awt::FontUnderline::BOLDDOTTED :
678*cdf0e10cSrcweir                 underline = "dottedHeavy";
679*cdf0e10cSrcweir                 break;
680*cdf0e10cSrcweir             case awt::FontUnderline::BOLDDASH :
681*cdf0e10cSrcweir                 underline = "dashHeavy";
682*cdf0e10cSrcweir                 break;
683*cdf0e10cSrcweir             case awt::FontUnderline::BOLDLONGDASH :
684*cdf0e10cSrcweir                 underline = "dashLongHeavy";
685*cdf0e10cSrcweir                 break;
686*cdf0e10cSrcweir             case awt::FontUnderline::BOLDDASHDOT :
687*cdf0e10cSrcweir                 underline = "dotDashHeavy";
688*cdf0e10cSrcweir                 break;
689*cdf0e10cSrcweir             case awt::FontUnderline::BOLDDASHDOTDOT :
690*cdf0e10cSrcweir                 underline = "dotDotDashHeavy";
691*cdf0e10cSrcweir                 break;
692*cdf0e10cSrcweir             case awt::FontUnderline::BOLDWAVE :
693*cdf0e10cSrcweir                 underline = "wavyHeavy";
694*cdf0e10cSrcweir                 break;
695*cdf0e10cSrcweir         }
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir     if( GETA( CharLocale ) ) {
698*cdf0e10cSrcweir         com::sun::star::lang::Locale eLocale;
699*cdf0e10cSrcweir         mAny >>= eLocale;
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir         OUStringBuffer usLanguageBuffer = eLocale.Language;
702*cdf0e10cSrcweir         if( eLocale.Country.getLength() ) {
703*cdf0e10cSrcweir             usLanguageBuffer.appendAscii( "-" );
704*cdf0e10cSrcweir             usLanguageBuffer.append( eLocale.Country );
705*cdf0e10cSrcweir         }
706*cdf0e10cSrcweir 
707*cdf0e10cSrcweir         if( usLanguageBuffer.getLength() )
708*cdf0e10cSrcweir             usLanguage = usLanguageBuffer.makeStringAndClear();
709*cdf0e10cSrcweir     }
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_rPr,
712*cdf0e10cSrcweir                           XML_b, bold,
713*cdf0e10cSrcweir                           XML_i, italic,
714*cdf0e10cSrcweir                           XML_lang, usLanguage.getLength() ? USS( usLanguage ) : NULL,
715*cdf0e10cSrcweir                           XML_sz, nSize == 1800 ? NULL : IS( nSize ),
716*cdf0e10cSrcweir                           XML_u, underline,
717*cdf0e10cSrcweir                           FSEND );
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir     // mso doesn't like text color to be placed after typeface
720*cdf0e10cSrcweir     if( GETAD( CharColor ) ) {
721*cdf0e10cSrcweir         sal_uInt32 color = *((sal_uInt32*) mAny.getValue());
722*cdf0e10cSrcweir         DBG(printf("run color: %x auto: %x\n", static_cast<unsigned int>( color ), static_cast<unsigned int>( COL_AUTO )));
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir         if( color == COL_AUTO ) { // nCharColor depends to the background color
725*cdf0e10cSrcweir             sal_Bool bIsDark = sal_False;
726*cdf0e10cSrcweir             GET( bIsDark, IsBackgroundDark );
727*cdf0e10cSrcweir             color = bIsDark ? 0xffffff : 0x000000;
728*cdf0e10cSrcweir         }
729*cdf0e10cSrcweir         color &= 0xffffff;
730*cdf0e10cSrcweir 
731*cdf0e10cSrcweir         // TODO: special handle embossed/engraved
732*cdf0e10cSrcweir 
733*cdf0e10cSrcweir         WriteSolidFill( color );
734*cdf0e10cSrcweir     }
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir     if( GETAD( CharFontName ) ) {
737*cdf0e10cSrcweir         const char* typeface = NULL;
738*cdf0e10cSrcweir         const char* pitch = NULL;
739*cdf0e10cSrcweir         const char* charset = NULL;
740*cdf0e10cSrcweir         OUString usTypeface, usPitch, usCharset;
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir         mAny >>= usTypeface;
743*cdf0e10cSrcweir         String aSubstName( GetSubsFontName( usTypeface, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
744*cdf0e10cSrcweir         if( aSubstName.Len() )
745*cdf0e10cSrcweir             typeface = ST( aSubstName );
746*cdf0e10cSrcweir         else
747*cdf0e10cSrcweir             typeface = USS( usTypeface );
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir         mpFS->singleElementNS( XML_a, XML_latin,
752*cdf0e10cSrcweir                                XML_typeface, typeface,
753*cdf0e10cSrcweir                                XML_pitchFamily, pitch,
754*cdf0e10cSrcweir                                XML_charset, charset,
755*cdf0e10cSrcweir                                FSEND );
756*cdf0e10cSrcweir     }
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir     if( ( bComplex && GETAD( CharFontNameComplex ) ) || ( !bComplex && GETAD( CharFontNameAsian ) ) ) {
759*cdf0e10cSrcweir         const char* typeface = NULL;
760*cdf0e10cSrcweir         const char* pitch = NULL;
761*cdf0e10cSrcweir         const char* charset = NULL;
762*cdf0e10cSrcweir         OUString usTypeface, usPitch, usCharset;
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir         mAny >>= usTypeface;
765*cdf0e10cSrcweir         String aSubstName( GetSubsFontName( usTypeface, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
766*cdf0e10cSrcweir         if( aSubstName.Len() )
767*cdf0e10cSrcweir             typeface = ST( aSubstName );
768*cdf0e10cSrcweir         else
769*cdf0e10cSrcweir             typeface = USS( usTypeface );
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir         mpFS->singleElementNS( XML_a, bComplex ? XML_cs : XML_ea,
772*cdf0e10cSrcweir                                XML_typeface, typeface,
773*cdf0e10cSrcweir                                XML_pitchFamily, pitch,
774*cdf0e10cSrcweir                                XML_charset, charset,
775*cdf0e10cSrcweir                                FSEND );
776*cdf0e10cSrcweir     }
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_rPr );
779*cdf0e10cSrcweir }
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir const char* DrawingML::GetFieldType( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun )
782*cdf0e10cSrcweir {
783*cdf0e10cSrcweir     const char* sType = NULL;
784*cdf0e10cSrcweir     Reference< XPropertySet > rXPropSet( rRun, UNO_QUERY );
785*cdf0e10cSrcweir     String aFieldType;
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir     if( GETA( TextPortionType ) ) {
788*cdf0e10cSrcweir         aFieldType = String( *(::rtl::OUString*)mAny.getValue() );
789*cdf0e10cSrcweir         DBG(printf ("field type: %s\n", ST(aFieldType) ));
790*cdf0e10cSrcweir     }
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir     if( aFieldType == S( "TextField" ) ) {
793*cdf0e10cSrcweir         Reference< XTextField > rXTextField;
794*cdf0e10cSrcweir         GET( rXTextField, TextField );
795*cdf0e10cSrcweir         if( rXTextField.is() ) {
796*cdf0e10cSrcweir             rXPropSet.set( rXTextField, UNO_QUERY );
797*cdf0e10cSrcweir             if( rXPropSet.is() ) {
798*cdf0e10cSrcweir                 String aFieldKind( rXTextField->getPresentation( TRUE ) );
799*cdf0e10cSrcweir                 DBG(printf ("field kind: %s\n", ST(aFieldKind) ));
800*cdf0e10cSrcweir                 if( aFieldKind == S( "Page" ) ) {
801*cdf0e10cSrcweir                     return "slidenum";
802*cdf0e10cSrcweir                 }
803*cdf0e10cSrcweir             }
804*cdf0e10cSrcweir         }
805*cdf0e10cSrcweir     }
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir     return sType;
808*cdf0e10cSrcweir }
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir void DrawingML::GetUUID( OStringBuffer& rBuffer )
811*cdf0e10cSrcweir {
812*cdf0e10cSrcweir     Sequence< sal_uInt8 > aSeq( 16 );
813*cdf0e10cSrcweir     static char cDigits[17] = "0123456789ABCDEF";
814*cdf0e10cSrcweir     rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
815*cdf0e10cSrcweir     int i;
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir     rBuffer.append( '{' );
818*cdf0e10cSrcweir     for( i = 0; i < 4; i++ ) {
819*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
820*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
821*cdf0e10cSrcweir     }
822*cdf0e10cSrcweir     rBuffer.append( '-' );
823*cdf0e10cSrcweir     for( ; i < 6; i++ ) {
824*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
825*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
826*cdf0e10cSrcweir     }
827*cdf0e10cSrcweir     rBuffer.append( '-' );
828*cdf0e10cSrcweir     for( ; i < 8; i++ ) {
829*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
830*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
831*cdf0e10cSrcweir     }
832*cdf0e10cSrcweir     rBuffer.append( '-' );
833*cdf0e10cSrcweir     for( ; i < 10; i++ ) {
834*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
835*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
836*cdf0e10cSrcweir     }
837*cdf0e10cSrcweir     rBuffer.append( '-' );
838*cdf0e10cSrcweir     for( ; i < 16; i++ ) {
839*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
840*cdf0e10cSrcweir         rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
841*cdf0e10cSrcweir     }
842*cdf0e10cSrcweir     rBuffer.append( '}' );
843*cdf0e10cSrcweir }
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir void DrawingML::WriteRun( Reference< XTextRange > rRun )
846*cdf0e10cSrcweir {
847*cdf0e10cSrcweir     const char* sFieldType;
848*cdf0e10cSrcweir     bool bIsField = false;
849*cdf0e10cSrcweir     OUString sText = rRun->getString();
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir     if( sText.getLength() < 1)
852*cdf0e10cSrcweir         return;
853*cdf0e10cSrcweir 
854*cdf0e10cSrcweir     if( ( sFieldType = GetFieldType( rRun ) ) ) {
855*cdf0e10cSrcweir         OStringBuffer sUUID(39);
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir         GetUUID( sUUID );
858*cdf0e10cSrcweir         mpFS->startElementNS( XML_a, XML_fld,
859*cdf0e10cSrcweir                               XML_id, sUUID.getStr(),
860*cdf0e10cSrcweir                               XML_type, sFieldType,
861*cdf0e10cSrcweir                               FSEND );
862*cdf0e10cSrcweir         bIsField = true;
863*cdf0e10cSrcweir     } else
864*cdf0e10cSrcweir         mpFS->startElementNS( XML_a, XML_r, FSEND );
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir     WriteRunProperties( rRun );
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_t, FSEND );
869*cdf0e10cSrcweir     mpFS->writeEscaped( sText );
870*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_t );
871*cdf0e10cSrcweir 
872*cdf0e10cSrcweir     if( bIsField )
873*cdf0e10cSrcweir         mpFS->endElementNS( XML_a, XML_fld );
874*cdf0e10cSrcweir     else
875*cdf0e10cSrcweir         mpFS->endElementNS( XML_a, XML_r );
876*cdf0e10cSrcweir }
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir #define AUTONUM(x) \
879*cdf0e10cSrcweir                         if( bPBoth ) \
880*cdf0e10cSrcweir                             pAutoNumType = #x "ParenBoth"; \
881*cdf0e10cSrcweir                         else if( bPBehind ) \
882*cdf0e10cSrcweir                             pAutoNumType = #x "ParenR"; \
883*cdf0e10cSrcweir                         else if( bSDot ) \
884*cdf0e10cSrcweir                             pAutoNumType = #x "Period";
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir 
887*cdf0e10cSrcweir inline static const char* GetAutoNumType( sal_Int16 nNumberingType, bool bSDot, bool bPBehind, bool bPBoth )
888*cdf0e10cSrcweir {
889*cdf0e10cSrcweir     const char* pAutoNumType = NULL;
890*cdf0e10cSrcweir 
891*cdf0e10cSrcweir     switch( (SvxExtNumType)nNumberingType )
892*cdf0e10cSrcweir         {
893*cdf0e10cSrcweir         case SVX_NUM_CHARS_UPPER_LETTER_N :
894*cdf0e10cSrcweir         case SVX_NUM_CHARS_UPPER_LETTER :
895*cdf0e10cSrcweir             AUTONUM( alphaUc );
896*cdf0e10cSrcweir             break;
897*cdf0e10cSrcweir         case SVX_NUM_CHARS_LOWER_LETTER_N :
898*cdf0e10cSrcweir         case SVX_NUM_CHARS_LOWER_LETTER :
899*cdf0e10cSrcweir             AUTONUM( alphaLc );
900*cdf0e10cSrcweir             break;
901*cdf0e10cSrcweir         case SVX_NUM_ROMAN_UPPER :
902*cdf0e10cSrcweir             AUTONUM( romanUc );
903*cdf0e10cSrcweir             break;
904*cdf0e10cSrcweir         case SVX_NUM_ROMAN_LOWER :
905*cdf0e10cSrcweir             AUTONUM( romanLc );
906*cdf0e10cSrcweir             break;
907*cdf0e10cSrcweir         case SVX_NUM_ARABIC :
908*cdf0e10cSrcweir             AUTONUM( arabic )
909*cdf0e10cSrcweir             else
910*cdf0e10cSrcweir                 pAutoNumType = "arabicPlain";
911*cdf0e10cSrcweir                         break;
912*cdf0e10cSrcweir         default:
913*cdf0e10cSrcweir             break;
914*cdf0e10cSrcweir         }
915*cdf0e10cSrcweir 
916*cdf0e10cSrcweir     return pAutoNumType;
917*cdf0e10cSrcweir }
918*cdf0e10cSrcweir 
919*cdf0e10cSrcweir void DrawingML::WriteParagraphNumbering( Reference< XPropertySet > rXPropSet, sal_Int16 nLevel )
920*cdf0e10cSrcweir {
921*cdf0e10cSrcweir     if( nLevel >= 0 && GETA( NumberingRules ) )
922*cdf0e10cSrcweir     {
923*cdf0e10cSrcweir         Reference< XIndexAccess > rXIndexAccess;
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir         if ( ( mAny >>= rXIndexAccess ) && nLevel < rXIndexAccess->getCount() )
926*cdf0e10cSrcweir         {
927*cdf0e10cSrcweir             DBG(printf ("numbering rules\n"));
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir             Sequence< PropertyValue > aPropertySequence;
930*cdf0e10cSrcweir             rXIndexAccess->getByIndex( nLevel ) >>= aPropertySequence;
931*cdf0e10cSrcweir 
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir             const PropertyValue* pPropValue = aPropertySequence.getArray();
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir             sal_Int32 nPropertyCount = aPropertySequence.getLength();
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir             if ( nPropertyCount ) {
938*cdf0e10cSrcweir 
939*cdf0e10cSrcweir                 sal_Int16 nNumberingType = -1;
940*cdf0e10cSrcweir                 bool bSDot = false;
941*cdf0e10cSrcweir                 bool bPBehind = false;
942*cdf0e10cSrcweir                 bool bPBoth = false;
943*cdf0e10cSrcweir                 sal_Unicode aBulletChar = 0x2022; // a bullet
944*cdf0e10cSrcweir                 awt::FontDescriptor aFontDesc;
945*cdf0e10cSrcweir                 bool bHasFontDesc = false;
946*cdf0e10cSrcweir                 OUString aGraphicURL;
947*cdf0e10cSrcweir                 sal_Int16 nBulletRelSize = 0;
948*cdf0e10cSrcweir 
949*cdf0e10cSrcweir                 for ( sal_Int32 i = 0; i < nPropertyCount; i++ ) {
950*cdf0e10cSrcweir                     const void* pValue = pPropValue[ i ].Value.getValue();
951*cdf0e10cSrcweir                     if ( pValue ) {
952*cdf0e10cSrcweir                         OUString aPropName( pPropValue[ i ].Name );
953*cdf0e10cSrcweir                         DBG(printf ("pro name: %s\n", OUStringToOString( aPropName, RTL_TEXTENCODING_UTF8 ).getStr()));
954*cdf0e10cSrcweir                         if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "NumberingType" ) ) )
955*cdf0e10cSrcweir                             nNumberingType = *( (sal_Int16*)pValue );
956*cdf0e10cSrcweir                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Prefix" ) ) ) {
957*cdf0e10cSrcweir                             if( *(OUString*)pValue == US( ")" ) )
958*cdf0e10cSrcweir                                 bPBoth = true;
959*cdf0e10cSrcweir                         } else if  ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Suffix" ) ) ) {
960*cdf0e10cSrcweir                             if( *(OUString*)pValue == US( "." ) )
961*cdf0e10cSrcweir                                 bSDot = true;
962*cdf0e10cSrcweir                             else if( *(OUString*)pValue == US( ")" ) )
963*cdf0e10cSrcweir                                 bPBehind = true;
964*cdf0e10cSrcweir                         } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletChar" ) ) )
965*cdf0e10cSrcweir                         {
966*cdf0e10cSrcweir                             aBulletChar = String ( *( (String*)pValue ) ).GetChar( 0 );
967*cdf0e10cSrcweir                             //printf ("bullet char: %d\n", aBulletChar.getStr());
968*cdf0e10cSrcweir                         }
969*cdf0e10cSrcweir                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletFont" ) ) )
970*cdf0e10cSrcweir                         {
971*cdf0e10cSrcweir                             aFontDesc = *( (awt::FontDescriptor*)pValue );
972*cdf0e10cSrcweir                             bHasFontDesc = true;
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir                             // Our numbullet dialog has set the wrong textencoding for our "StarSymbol" font,
975*cdf0e10cSrcweir                             // instead of a Unicode encoding the encoding RTL_TEXTENCODING_SYMBOL was used.
976*cdf0e10cSrcweir                             // Because there might exist a lot of damaged documemts I added this two lines
977*cdf0e10cSrcweir                             // which fixes the bullet problem for the export.
978*cdf0e10cSrcweir                             if ( aFontDesc.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StarSymbol" ) ) )
979*cdf0e10cSrcweir                                 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir                         } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletRelSize" ) ) ) {
982*cdf0e10cSrcweir                             nBulletRelSize = *( (sal_Int16*)pValue );
983*cdf0e10cSrcweir                         } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicURL" ) ) ) {
984*cdf0e10cSrcweir                             aGraphicURL = ( *(OUString*)pValue );
985*cdf0e10cSrcweir                             DBG(printf ("graphic url: %s\n", OUStringToOString( aGraphicURL, RTL_TEXTENCODING_UTF8 ).getStr()));
986*cdf0e10cSrcweir                         } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicSize" ) ) )
987*cdf0e10cSrcweir                         {
988*cdf0e10cSrcweir                             if ( pPropValue[ i ].Value.getValueType() == ::getCppuType( (awt::Size*)0) )
989*cdf0e10cSrcweir                             {
990*cdf0e10cSrcweir                                 // don't cast awt::Size to Size as on 64-bits they are not the same.
991*cdf0e10cSrcweir                                 ::com::sun::star::awt::Size aSize;
992*cdf0e10cSrcweir                                 pPropValue[ i ].Value >>= aSize;
993*cdf0e10cSrcweir                                 //aBuGraSize.nA = aSize.Width;
994*cdf0e10cSrcweir                                 //aBuGraSize.nB = aSize.Height;
995*cdf0e10cSrcweir                                 DBG(printf("graphic size: %dx%d\n", int( aSize.Width ), int( aSize.Height )));
996*cdf0e10cSrcweir                             }
997*cdf0e10cSrcweir                         }
998*cdf0e10cSrcweir                     }
999*cdf0e10cSrcweir                 }
1000*cdf0e10cSrcweir 
1001*cdf0e10cSrcweir                 const char* pAutoNumType = GetAutoNumType( nNumberingType, bSDot, bPBehind, bPBoth );
1002*cdf0e10cSrcweir 
1003*cdf0e10cSrcweir                 if( nLevel >= 0 ) {
1004*cdf0e10cSrcweir                     if( aGraphicURL.getLength() > 0 ) {
1005*cdf0e10cSrcweir                         OUString sRelId = WriteImage( aGraphicURL );
1006*cdf0e10cSrcweir 
1007*cdf0e10cSrcweir                         mpFS->startElementNS( XML_a, XML_buBlip, FSEND );
1008*cdf0e10cSrcweir                         mpFS->singleElementNS( XML_a, XML_blip, FSNS( XML_r, XML_embed ), USS( sRelId ), FSEND );
1009*cdf0e10cSrcweir                         mpFS->endElementNS( XML_a, XML_buBlip );
1010*cdf0e10cSrcweir                     } else {
1011*cdf0e10cSrcweir                         if( nBulletRelSize && nBulletRelSize != 100 )
1012*cdf0e10cSrcweir                             mpFS->singleElementNS( XML_a, XML_buSzPct,
1013*cdf0e10cSrcweir                                                    XML_val, IS( 1000*( (sal_Int32)nBulletRelSize ) ), FSEND );
1014*cdf0e10cSrcweir                         if( bHasFontDesc )
1015*cdf0e10cSrcweir                             mpFS->singleElementNS( XML_a, XML_buFont,
1016*cdf0e10cSrcweir                                                    XML_typeface, OUStringToOString( aFontDesc.Name, RTL_TEXTENCODING_UTF8 ).getStr(),
1017*cdf0e10cSrcweir                                                    XML_charset, (aFontDesc.CharSet == awt::CharSet::SYMBOL) ? "2" : NULL,
1018*cdf0e10cSrcweir                                                    FSEND );
1019*cdf0e10cSrcweir 
1020*cdf0e10cSrcweir                         if( pAutoNumType )
1021*cdf0e10cSrcweir                             mpFS->singleElementNS( XML_a, XML_buAutoNum, XML_type, pAutoNumType, FSEND );
1022*cdf0e10cSrcweir                         else {
1023*cdf0e10cSrcweir                             aBulletChar = SubstituteBullet( aBulletChar, aFontDesc );
1024*cdf0e10cSrcweir                             mpFS->singleElementNS( XML_a, XML_buChar, XML_char, USS( OUString( aBulletChar ) ), FSEND );
1025*cdf0e10cSrcweir                         }
1026*cdf0e10cSrcweir                     }
1027*cdf0e10cSrcweir                 }
1028*cdf0e10cSrcweir             }
1029*cdf0e10cSrcweir         }
1030*cdf0e10cSrcweir     }
1031*cdf0e10cSrcweir }
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir const char* DrawingML::GetAlignment( sal_Int32 nAlignment )
1034*cdf0e10cSrcweir {
1035*cdf0e10cSrcweir     const char* sAlignment = NULL;
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir     switch( nAlignment ) {
1038*cdf0e10cSrcweir         case style::ParagraphAdjust_CENTER:
1039*cdf0e10cSrcweir             sAlignment = "ctr";
1040*cdf0e10cSrcweir             break;
1041*cdf0e10cSrcweir         case style::ParagraphAdjust_RIGHT:
1042*cdf0e10cSrcweir             sAlignment = "r";
1043*cdf0e10cSrcweir             break;
1044*cdf0e10cSrcweir         case style::ParagraphAdjust_BLOCK:
1045*cdf0e10cSrcweir             sAlignment = "just";
1046*cdf0e10cSrcweir             break;
1047*cdf0e10cSrcweir         default:
1048*cdf0e10cSrcweir             ;
1049*cdf0e10cSrcweir     }
1050*cdf0e10cSrcweir 
1051*cdf0e10cSrcweir     return sAlignment;
1052*cdf0e10cSrcweir }
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir void DrawingML::WriteParagraphProperties( Reference< XTextContent > rParagraph )
1055*cdf0e10cSrcweir {
1056*cdf0e10cSrcweir     Reference< XPropertySet > rXPropSet( rParagraph, UNO_QUERY );
1057*cdf0e10cSrcweir     Reference< XPropertyState > rXPropState( rParagraph, UNO_QUERY );
1058*cdf0e10cSrcweir 
1059*cdf0e10cSrcweir     if( !rXPropSet.is() || !rXPropState.is() )
1060*cdf0e10cSrcweir         return;
1061*cdf0e10cSrcweir 
1062*cdf0e10cSrcweir     sal_Int16 nLevel = -1;
1063*cdf0e10cSrcweir     GET( nLevel, NumberingLevel );
1064*cdf0e10cSrcweir 
1065*cdf0e10cSrcweir     sal_Int32 nLeftMargin = 0;
1066*cdf0e10cSrcweir     // fix coordinates
1067*cdf0e10cSrcweir     //GET( nLeftMargin, ParaLeftMargin );
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir     sal_Int16 nAlignment( style::ParagraphAdjust_LEFT );
1070*cdf0e10cSrcweir     GET( nAlignment, ParaAdjust );
1071*cdf0e10cSrcweir 
1072*cdf0e10cSrcweir     if( nLevel != -1
1073*cdf0e10cSrcweir             || nLeftMargin > 0
1074*cdf0e10cSrcweir             || nAlignment != style::ParagraphAdjust_LEFT ) {
1075*cdf0e10cSrcweir         mpFS->startElementNS( XML_a, XML_pPr,
1076*cdf0e10cSrcweir                               XML_lvl, nLevel > 0 ? I32S( nLevel ) : NULL,
1077*cdf0e10cSrcweir                               XML_marL, nLeftMargin > 0 ? IS( nLeftMargin ) : NULL,
1078*cdf0e10cSrcweir                               XML_algn, GetAlignment( nAlignment ),
1079*cdf0e10cSrcweir                               FSEND );
1080*cdf0e10cSrcweir 
1081*cdf0e10cSrcweir         WriteParagraphNumbering( rXPropSet, nLevel );
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir         mpFS->endElementNS( XML_a, XML_pPr );
1084*cdf0e10cSrcweir     }
1085*cdf0e10cSrcweir }
1086*cdf0e10cSrcweir 
1087*cdf0e10cSrcweir void DrawingML::WriteParagraph( Reference< XTextContent > rParagraph )
1088*cdf0e10cSrcweir {
1089*cdf0e10cSrcweir     Reference< XEnumerationAccess > access( rParagraph, UNO_QUERY );
1090*cdf0e10cSrcweir     if( !access.is() )
1091*cdf0e10cSrcweir         return;
1092*cdf0e10cSrcweir 
1093*cdf0e10cSrcweir     Reference< XEnumeration > enumeration( access->createEnumeration() );
1094*cdf0e10cSrcweir     if( !enumeration.is() )
1095*cdf0e10cSrcweir         return;
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_p, FSEND );
1098*cdf0e10cSrcweir 
1099*cdf0e10cSrcweir     sal_Bool bPropertiesWritten = FALSE;
1100*cdf0e10cSrcweir     while( enumeration->hasMoreElements() ) {
1101*cdf0e10cSrcweir         Reference< XTextRange > run;
1102*cdf0e10cSrcweir         Any any ( enumeration->nextElement() );
1103*cdf0e10cSrcweir 
1104*cdf0e10cSrcweir         if (any >>= run) {
1105*cdf0e10cSrcweir             if( !bPropertiesWritten && run->getString().getLength() ) {
1106*cdf0e10cSrcweir                 WriteParagraphProperties( rParagraph );
1107*cdf0e10cSrcweir                 bPropertiesWritten = TRUE;
1108*cdf0e10cSrcweir             }
1109*cdf0e10cSrcweir             WriteRun( run );
1110*cdf0e10cSrcweir         }
1111*cdf0e10cSrcweir     }
1112*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_endParaRPr, FSEND );
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_p );
1115*cdf0e10cSrcweir }
1116*cdf0e10cSrcweir 
1117*cdf0e10cSrcweir void DrawingML::WriteText( Reference< XShape > rXShape  )
1118*cdf0e10cSrcweir {
1119*cdf0e10cSrcweir     Reference< XText > xXText( rXShape, UNO_QUERY );
1120*cdf0e10cSrcweir     Reference< XPropertySet > rXPropSet( rXShape, UNO_QUERY );
1121*cdf0e10cSrcweir 
1122*cdf0e10cSrcweir     if( !xXText.is() )
1123*cdf0e10cSrcweir         return;
1124*cdf0e10cSrcweir 
1125*cdf0e10cSrcweir #define DEFLRINS 254
1126*cdf0e10cSrcweir #define DEFTBINS 127
1127*cdf0e10cSrcweir     sal_Int32 nLeft, nRight, nTop, nBottom;
1128*cdf0e10cSrcweir     nLeft = nRight = DEFLRINS;
1129*cdf0e10cSrcweir     nTop = nBottom = DEFTBINS;
1130*cdf0e10cSrcweir 
1131*cdf0e10cSrcweir     // top inset looks a bit different compared to ppt export
1132*cdf0e10cSrcweir     // check if something related doesn't work as expected
1133*cdf0e10cSrcweir     GET( nLeft, TextLeftDistance );
1134*cdf0e10cSrcweir     GET( nRight, TextRightDistance );
1135*cdf0e10cSrcweir     GET( nTop, TextUpperDistance );
1136*cdf0e10cSrcweir     GET( nBottom, TextLowerDistance );
1137*cdf0e10cSrcweir 
1138*cdf0e10cSrcweir     TextVerticalAdjust eVerticalAlignment( TextVerticalAdjust_TOP );
1139*cdf0e10cSrcweir     const char* sVerticalAlignment = NULL;
1140*cdf0e10cSrcweir     GET( eVerticalAlignment, TextVerticalAdjust );
1141*cdf0e10cSrcweir     switch( eVerticalAlignment ) {
1142*cdf0e10cSrcweir         case TextVerticalAdjust_BOTTOM:
1143*cdf0e10cSrcweir             sVerticalAlignment = "b";
1144*cdf0e10cSrcweir             break;
1145*cdf0e10cSrcweir         case TextVerticalAdjust_CENTER:
1146*cdf0e10cSrcweir             sVerticalAlignment = "ctr";
1147*cdf0e10cSrcweir             break;
1148*cdf0e10cSrcweir         case TextVerticalAdjust_TOP:
1149*cdf0e10cSrcweir         default:
1150*cdf0e10cSrcweir             ;
1151*cdf0e10cSrcweir     }
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir     TextHorizontalAdjust eHorizontalAlignment( TextHorizontalAdjust_CENTER );
1154*cdf0e10cSrcweir     bool bHorizontalCenter = false;
1155*cdf0e10cSrcweir     GET( eHorizontalAlignment, TextHorizontalAdjust );
1156*cdf0e10cSrcweir     if( eHorizontalAlignment == TextHorizontalAdjust_CENTER )
1157*cdf0e10cSrcweir         bHorizontalCenter = true;
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir     sal_Bool bHasWrap = FALSE;
1160*cdf0e10cSrcweir     sal_Bool bWrap = FALSE;
1161*cdf0e10cSrcweir     if( GETA( TextWordWrap ) ) {
1162*cdf0e10cSrcweir         mAny >>= bWrap;
1163*cdf0e10cSrcweir         bHasWrap = TRUE;
1164*cdf0e10cSrcweir         //DBG(printf("wrap: %d\n", bWrap));
1165*cdf0e10cSrcweir     }
1166*cdf0e10cSrcweir 
1167*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_bodyPr,
1168*cdf0e10cSrcweir                            XML_wrap, bHasWrap && !bWrap ? "none" : NULL,
1169*cdf0e10cSrcweir                            XML_lIns, (nLeft != DEFLRINS) ? IS( MM100toEMU( nLeft ) ) : NULL,
1170*cdf0e10cSrcweir                            XML_rIns, (nRight != DEFLRINS) ? IS( MM100toEMU( nRight ) ) : NULL,
1171*cdf0e10cSrcweir                            XML_tIns, (nTop != DEFTBINS) ? IS( MM100toEMU( nTop ) ) : NULL,
1172*cdf0e10cSrcweir                            XML_bIns, (nBottom != DEFTBINS) ? IS( MM100toEMU( nBottom ) ) : NULL,
1173*cdf0e10cSrcweir                            XML_anchor, sVerticalAlignment,
1174*cdf0e10cSrcweir                            XML_anchorCtr, bHorizontalCenter ? "1" : NULL,
1175*cdf0e10cSrcweir                            FSEND );
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir     Reference< XEnumerationAccess > access( xXText, UNO_QUERY );
1178*cdf0e10cSrcweir     if( !access.is() )
1179*cdf0e10cSrcweir         return;
1180*cdf0e10cSrcweir 
1181*cdf0e10cSrcweir     Reference< XEnumeration > enumeration( access->createEnumeration() );
1182*cdf0e10cSrcweir     if( !enumeration.is() )
1183*cdf0e10cSrcweir         return;
1184*cdf0e10cSrcweir 
1185*cdf0e10cSrcweir     while( enumeration->hasMoreElements() ) {
1186*cdf0e10cSrcweir         Reference< XTextContent > paragraph;
1187*cdf0e10cSrcweir         Any any ( enumeration->nextElement() );
1188*cdf0e10cSrcweir 
1189*cdf0e10cSrcweir         if( any >>= paragraph)
1190*cdf0e10cSrcweir             WriteParagraph( paragraph );
1191*cdf0e10cSrcweir     }
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir }
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir void DrawingML::WritePresetShape( const char* pShape )
1196*cdf0e10cSrcweir {
1197*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_prstGeom,
1198*cdf0e10cSrcweir                           XML_prst, pShape,
1199*cdf0e10cSrcweir                           FSEND );
1200*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_avLst, FSEND );
1201*cdf0e10cSrcweir     mpFS->endElementNS(  XML_a, XML_prstGeom );
1202*cdf0e10cSrcweir }
1203*cdf0e10cSrcweir 
1204*cdf0e10cSrcweir void DrawingML::WritePresetShape( const char* pShape, MSO_SPT eShapeType, sal_Bool bPredefinedHandlesUsed, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, const PropertyValue& rProp )
1205*cdf0e10cSrcweir {
1206*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_prstGeom,
1207*cdf0e10cSrcweir                           XML_prst, pShape,
1208*cdf0e10cSrcweir                           FSEND );
1209*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_avLst, FSEND );
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir     Sequence< drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
1212*cdf0e10cSrcweir     if ( rProp.Value >>= aAdjustmentSeq ) {
1213*cdf0e10cSrcweir         DBG(printf("adj seq len: %d\n", int( aAdjustmentSeq.getLength() )));
1214*cdf0e10cSrcweir         if ( bPredefinedHandlesUsed )
1215*cdf0e10cSrcweir             EscherPropertyContainer::LookForPolarHandles( eShapeType, nAdjustmentsWhichNeedsToBeConverted );
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir         sal_Int32 nValue, nLength = aAdjustmentSeq.getLength();
1218*cdf0e10cSrcweir         for( sal_Int32 i=0; i < nLength; i++ )
1219*cdf0e10cSrcweir             if( EscherPropertyContainer::GetAdjustmentValue( aAdjustmentSeq[ i ], i, nAdjustmentsWhichNeedsToBeConverted, nValue ) )
1220*cdf0e10cSrcweir                 mpFS->singleElementNS( XML_a, XML_gd,
1221*cdf0e10cSrcweir                                        XML_name, nLength > 1 ? ( OString( "adj" ) + OString::valueOf( i + 1 ) ).getStr() : "adj",
1222*cdf0e10cSrcweir                                        XML_fmla, (OString("val ") + OString::valueOf( nValue )).getStr(),
1223*cdf0e10cSrcweir                                        FSEND );
1224*cdf0e10cSrcweir     }
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_avLst );
1227*cdf0e10cSrcweir     mpFS->endElementNS(  XML_a, XML_prstGeom );
1228*cdf0e10cSrcweir }
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir void DrawingML::WritePolyPolygon( const PolyPolygon& rPolyPolygon )
1231*cdf0e10cSrcweir {
1232*cdf0e10cSrcweir     if( rPolyPolygon.Count() < 1 )
1233*cdf0e10cSrcweir         return;
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_custGeom, FSEND );
1236*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_avLst, FSEND );
1237*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_gdLst, FSEND );
1238*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_ahLst, FSEND );
1239*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_rect,
1240*cdf0e10cSrcweir                            XML_l, "0",
1241*cdf0e10cSrcweir                            XML_t, "0",
1242*cdf0e10cSrcweir                            XML_r, "r",
1243*cdf0e10cSrcweir                            XML_b, "b",
1244*cdf0e10cSrcweir                            FSEND );
1245*cdf0e10cSrcweir 
1246*cdf0e10cSrcweir     mpFS->startElementNS( XML_a, XML_pathLst, FSEND );
1247*cdf0e10cSrcweir 
1248*cdf0e10cSrcweir     for( USHORT i = 0; i < rPolyPolygon.Count(); i ++ ) {
1249*cdf0e10cSrcweir 
1250*cdf0e10cSrcweir         const Polygon& rPoly = rPolyPolygon[ i ];
1251*cdf0e10cSrcweir         Rectangle aRect( rPoly.GetBoundRect() );
1252*cdf0e10cSrcweir         sal_Bool bBezier = FALSE;
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir         mpFS->startElementNS( XML_a, XML_path,
1255*cdf0e10cSrcweir                               XML_w, I64S( aRect.GetWidth() ),
1256*cdf0e10cSrcweir                               XML_h, I64S( aRect.GetHeight() ),
1257*cdf0e10cSrcweir                               FSEND );
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir         if( rPoly.GetSize() > 0 )
1260*cdf0e10cSrcweir         {
1261*cdf0e10cSrcweir             mpFS->startElementNS( XML_a, XML_moveTo, FSEND );
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir             mpFS->singleElementNS( XML_a, XML_pt,
1264*cdf0e10cSrcweir                                    XML_x, I64S( rPoly[ 0 ].X() - aRect.Left() ),
1265*cdf0e10cSrcweir                                    XML_y, I64S( rPoly[ 0 ].Y() - aRect.Top() ),
1266*cdf0e10cSrcweir                                    FSEND );
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir             mpFS->endElementNS( XML_a, XML_moveTo );
1269*cdf0e10cSrcweir         }
1270*cdf0e10cSrcweir 
1271*cdf0e10cSrcweir         for( USHORT j = 1; j < rPoly.GetSize(); j ++ )
1272*cdf0e10cSrcweir         {
1273*cdf0e10cSrcweir             enum PolyFlags flags = rPoly.GetFlags(j);
1274*cdf0e10cSrcweir             if( flags == POLY_CONTROL && !bBezier )
1275*cdf0e10cSrcweir             {
1276*cdf0e10cSrcweir                 mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND );
1277*cdf0e10cSrcweir                 bBezier = TRUE;
1278*cdf0e10cSrcweir             }
1279*cdf0e10cSrcweir             else if( flags == POLY_NORMAL && !bBezier )
1280*cdf0e10cSrcweir                 mpFS->startElementNS( XML_a, XML_lnTo, FSEND );
1281*cdf0e10cSrcweir 
1282*cdf0e10cSrcweir             mpFS->singleElementNS( XML_a, XML_pt,
1283*cdf0e10cSrcweir                                    XML_x, I64S( rPoly[j].X() - aRect.Left() ),
1284*cdf0e10cSrcweir                                    XML_y, I64S( rPoly[j].Y() - aRect.Top() ),
1285*cdf0e10cSrcweir                                    FSEND );
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir             if( ( flags == POLY_NORMAL || flags == POLY_SYMMTR ) && bBezier )
1288*cdf0e10cSrcweir             {
1289*cdf0e10cSrcweir                 mpFS->endElementNS( XML_a, XML_cubicBezTo );
1290*cdf0e10cSrcweir                 bBezier = FALSE;
1291*cdf0e10cSrcweir             }
1292*cdf0e10cSrcweir             else if( flags == POLY_NORMAL && !bBezier )
1293*cdf0e10cSrcweir                 mpFS->endElementNS( XML_a, XML_lnTo );
1294*cdf0e10cSrcweir             else if( bBezier && ( j % 3 ) == 0 )
1295*cdf0e10cSrcweir             {
1296*cdf0e10cSrcweir                 // //a:cubicBezTo can only contain 3 //a:pt elements, so we
1297*cdf0e10cSrcweir                 // need to break things up...
1298*cdf0e10cSrcweir                 mpFS->endElementNS( XML_a, XML_cubicBezTo );
1299*cdf0e10cSrcweir                 mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND );
1300*cdf0e10cSrcweir             }
1301*cdf0e10cSrcweir //             switch( rPoly.GetFlags(j) ) {
1302*cdf0e10cSrcweir //                 case POLY_NORMAL:
1303*cdf0e10cSrcweir //                     DBG(printf("normal\n"));
1304*cdf0e10cSrcweir //                     break;
1305*cdf0e10cSrcweir //                 case POLY_SMOOTH:
1306*cdf0e10cSrcweir //                     DBG(printf("smooth\n"));
1307*cdf0e10cSrcweir //                     break;
1308*cdf0e10cSrcweir //                 case POLY_CONTROL:
1309*cdf0e10cSrcweir //                     DBG(printf("control\n"));
1310*cdf0e10cSrcweir //                     break;
1311*cdf0e10cSrcweir //                 case POLY_SYMMTR:
1312*cdf0e10cSrcweir //                     DBG(printf("symmtr\n"));
1313*cdf0e10cSrcweir //                         break;
1314*cdf0e10cSrcweir //             }
1315*cdf0e10cSrcweir //             DBG(printf("point %ld %ld\n", rPoly[j].X() - aRect.Left(), rPoly[j].Y() - aRect.Top()));
1316*cdf0e10cSrcweir         }
1317*cdf0e10cSrcweir 
1318*cdf0e10cSrcweir         mpFS->endElementNS( XML_a, XML_path );
1319*cdf0e10cSrcweir     }
1320*cdf0e10cSrcweir 
1321*cdf0e10cSrcweir     mpFS->endElementNS( XML_a, XML_pathLst );
1322*cdf0e10cSrcweir 
1323*cdf0e10cSrcweir     mpFS->endElementNS(  XML_a, XML_custGeom );
1324*cdf0e10cSrcweir }
1325*cdf0e10cSrcweir 
1326*cdf0e10cSrcweir void DrawingML::WriteConnectorConnections( EscherConnectorListEntry& rConnectorEntry, sal_Int32 nStartID, sal_Int32 nEndID )
1327*cdf0e10cSrcweir {
1328*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_stCxn,
1329*cdf0e10cSrcweir                            XML_id, I32S( nStartID ),
1330*cdf0e10cSrcweir                            XML_idx, I64S( rConnectorEntry.GetConnectorRule( TRUE ) ),
1331*cdf0e10cSrcweir                            FSEND );
1332*cdf0e10cSrcweir     mpFS->singleElementNS( XML_a, XML_endCxn,
1333*cdf0e10cSrcweir                            XML_id, I32S( nEndID ),
1334*cdf0e10cSrcweir                            XML_idx, I64S( rConnectorEntry.GetConnectorRule( FALSE ) ),
1335*cdf0e10cSrcweir                            FSEND );
1336*cdf0e10cSrcweir }
1337*cdf0e10cSrcweir 
1338*cdf0e10cSrcweir // from sw/source/filter/ww8/wrtw8num.cxx for default bullets to export to MS intact
1339*cdf0e10cSrcweir static void lcl_SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, String& rFontName)
1340*cdf0e10cSrcweir {
1341*cdf0e10cSrcweir     sal_Unicode cChar = rNumStr.GetChar(0);
1342*cdf0e10cSrcweir     StarSymbolToMSMultiFont *pConvert = CreateStarSymbolToMSMultiFont();
1343*cdf0e10cSrcweir     String sFont = pConvert->ConvertChar(cChar);
1344*cdf0e10cSrcweir     delete pConvert;
1345*cdf0e10cSrcweir     if (sFont.Len())
1346*cdf0e10cSrcweir     {
1347*cdf0e10cSrcweir         rNumStr = static_cast< sal_Unicode >(cChar | 0xF000);
1348*cdf0e10cSrcweir         rFontName = sFont;
1349*cdf0e10cSrcweir         rChrSet = RTL_TEXTENCODING_SYMBOL;
1350*cdf0e10cSrcweir     }
1351*cdf0e10cSrcweir     else if ( (rNumStr.GetChar(0) < 0xE000 || rNumStr.GetChar(0) > 0xF8FF) )
1352*cdf0e10cSrcweir     {
1353*cdf0e10cSrcweir         /*
1354*cdf0e10cSrcweir            Ok we can't fit into a known windows unicode font, but
1355*cdf0e10cSrcweir            we are not in the private area, so we are a
1356*cdf0e10cSrcweir            standardized symbol, so turn off the symbol bit and
1357*cdf0e10cSrcweir            let words own font substitution kick in
1358*cdf0e10cSrcweir            */
1359*cdf0e10cSrcweir         rChrSet = RTL_TEXTENCODING_UNICODE;
1360*cdf0e10cSrcweir         rFontName = ::GetFontToken(rFontName, 0);
1361*cdf0e10cSrcweir     }
1362*cdf0e10cSrcweir     else
1363*cdf0e10cSrcweir     {
1364*cdf0e10cSrcweir         /*
1365*cdf0e10cSrcweir            Well we don't have an available substition, and we're
1366*cdf0e10cSrcweir            in our private area, so give up and show a standard
1367*cdf0e10cSrcweir            bullet symbol
1368*cdf0e10cSrcweir            */
1369*cdf0e10cSrcweir         rFontName.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Wingdings"));
1370*cdf0e10cSrcweir         rNumStr = static_cast< sal_Unicode >(0x6C);
1371*cdf0e10cSrcweir     }
1372*cdf0e10cSrcweir }
1373*cdf0e10cSrcweir 
1374*cdf0e10cSrcweir sal_Unicode DrawingML::SubstituteBullet( sal_Unicode cBulletId, ::com::sun::star::awt::FontDescriptor& rFontDesc )
1375*cdf0e10cSrcweir {
1376*cdf0e10cSrcweir     String sNumStr = cBulletId;
1377*cdf0e10cSrcweir 
1378*cdf0e10cSrcweir     if ( rFontDesc.Name.equalsIgnoreAsciiCaseAscii("starsymbol") ||
1379*cdf0e10cSrcweir          rFontDesc.Name.equalsIgnoreAsciiCaseAscii("opensymbol") )  {
1380*cdf0e10cSrcweir         String sFontName = rFontDesc.Name;
1381*cdf0e10cSrcweir         rtl_TextEncoding aCharSet = rFontDesc.CharSet;
1382*cdf0e10cSrcweir 
1383*cdf0e10cSrcweir         lcl_SubstituteBullet( sNumStr, aCharSet, sFontName );
1384*cdf0e10cSrcweir 
1385*cdf0e10cSrcweir         rFontDesc.Name = sFontName;
1386*cdf0e10cSrcweir         rFontDesc.CharSet = aCharSet;
1387*cdf0e10cSrcweir     }
1388*cdf0e10cSrcweir 
1389*cdf0e10cSrcweir     return sNumStr.GetChar( 0 );
1390*cdf0e10cSrcweir }
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir }
1393*cdf0e10cSrcweir }
1394