LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/oox/source/export - drawingml.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 151 816 18.5 %
Date: 2013-07-09 Functions: 15 43 34.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10