LCOV - code coverage report
Current view: top level - sdext/source/pdfimport/tree - drawtreevisiting.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 407 571 71.3 %
Date: 2012-08-25 Functions: 22 30 73.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 520 1310 39.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include "pdfiprocessor.hxx"
      31                 :            : #include "xmlemitter.hxx"
      32                 :            : #include "pdfihelper.hxx"
      33                 :            : #include "imagecontainer.hxx"
      34                 :            : #include "style.hxx"
      35                 :            : #include "drawtreevisiting.hxx"
      36                 :            : #include "genericelements.hxx"
      37                 :            : 
      38                 :            : #include "basegfx/polygon/b2dpolypolygontools.hxx"
      39                 :            : #include "basegfx/range/b2drange.hxx"
      40                 :            : 
      41                 :            : #include "com/sun/star/i18n/XBreakIterator.hpp"
      42                 :            : #include "com/sun/star/lang/XMultiServiceFactory.hpp"
      43                 :            : #include "comphelper/processfactory.hxx"
      44                 :            : #include "com/sun/star/i18n/ScriptType.hpp"
      45                 :            : #include "com/sun/star/i18n/DirectionProperty.hpp"
      46                 :            : 
      47                 :            : #include <string.h>
      48                 :            : 
      49                 :            : using namespace ::com::sun::star;
      50                 :            : using namespace ::com::sun::star;
      51                 :            : using namespace ::com::sun::star::lang;
      52                 :            : using namespace ::com::sun::star::i18n;
      53                 :            : using namespace ::com::sun::star::uno;
      54                 :            : 
      55                 :            : namespace pdfi
      56                 :            : {
      57                 :            : 
      58                 :       4509 : const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator >& DrawXmlOptimizer::GetBreakIterator()
      59                 :            : {
      60         [ +  + ]:       4509 :     if ( !mxBreakIter.is() )
      61                 :            :     {
      62         [ +  - ]:          3 :         Reference< XComponentContext > xContext( this->m_rProcessor.m_xContext, uno::UNO_SET_THROW );
      63 [ +  - ][ +  - ]:          3 :         Reference< XMultiComponentFactory > xMSF(  xContext->getServiceManager(), uno::UNO_SET_THROW );
                 [ +  - ]
      64 [ +  - ][ +  - ]:          3 :     Reference < XInterface > xInterface = xMSF->createInstanceWithContext(::rtl::OUString("com.sun.star.i18n.BreakIterator"), xContext);
      65                 :            : 
      66 [ +  - ][ +  - ]:          3 :         mxBreakIter = uno::Reference< i18n::XBreakIterator >( xInterface, uno::UNO_QUERY );
      67                 :            :     }
      68                 :       4509 :     return mxBreakIter;
      69                 :            : }
      70                 :            : 
      71                 :         33 : const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCharacterClassification >& DrawXmlEmitter::GetCharacterClassification()
      72                 :            : {
      73         [ +  + ]:         33 :     if ( !mxCharClass.is() )
      74                 :            :     {
      75         [ +  - ]:          3 :         Reference< XComponentContext > xContext( m_rEmitContext.m_xContext, uno::UNO_SET_THROW );
      76 [ +  - ][ +  - ]:          3 :         Reference< XMultiComponentFactory > xMSF(  xContext->getServiceManager(), uno::UNO_SET_THROW );
                 [ +  - ]
      77 [ +  - ][ +  - ]:          3 :     Reference < XInterface > xInterface = xMSF->createInstanceWithContext(::rtl::OUString("com.sun.star.i18n.CharacterClassification"), xContext);
      78 [ +  - ][ +  - ]:          3 :         mxCharClass = uno::Reference< i18n::XCharacterClassification >( xInterface, uno::UNO_QUERY );
      79                 :            :     }
      80                 :         33 :     return mxCharClass;
      81                 :            : }
      82                 :            : 
      83                 :          0 : void DrawXmlEmitter::visit( HyperlinkElement& elem, const std::list< Element* >::const_iterator&   )
      84                 :            : {
      85         [ #  # ]:          0 :     if( elem.Children.empty() )
      86                 :          0 :         return;
      87                 :            : 
      88 [ #  # ][ #  # ]:          0 :     const char* pType = dynamic_cast<DrawElement*>(elem.Children.front()) ? "draw:a" : "text:a";
                 [ #  # ]
      89                 :            : 
      90         [ #  # ]:          0 :     PropertyMap aProps;
      91 [ #  # ][ #  # ]:          0 :     aProps[ USTR( "xlink:type" ) ] = USTR( "simple" );
                 [ #  # ]
      92 [ #  # ][ #  # ]:          0 :     aProps[ USTR( "xlink:href" ) ] = elem.URI;
      93 [ #  # ][ #  # ]:          0 :     aProps[ USTR( "office:target-frame-name" ) ] = USTR( "_blank" );
                 [ #  # ]
      94 [ #  # ][ #  # ]:          0 :     aProps[ USTR( "xlink:show" ) ] = USTR( "new" );
                 [ #  # ]
      95                 :            : 
      96         [ #  # ]:          0 :     m_rEmitContext.rEmitter.beginTag( pType, aProps );
      97                 :          0 :     std::list< Element* >::iterator this_it =  elem.Children.begin();
      98 [ #  # ][ #  # ]:          0 :     while( this_it !=elem.Children.end() && *this_it != &elem )
         [ #  # ][ #  # ]
      99                 :            :     {
     100         [ #  # ]:          0 :         (*this_it)->visitedBy( *this, this_it );
     101                 :          0 :         ++this_it;
     102                 :            :     }
     103 [ #  # ][ #  # ]:          0 :     m_rEmitContext.rEmitter.endTag( pType );
     104                 :            : }
     105                 :            : 
     106                 :         33 : void DrawXmlEmitter::visit( TextElement& elem, const std::list< Element* >::const_iterator&   )
     107                 :            : {
     108         [ +  - ]:         33 :     if( ! elem.Text.getLength() )
     109                 :         33 :         return;
     110                 :            : 
     111                 :         33 :     rtl::OUString strSpace(32);
     112                 :         33 :     rtl::OUString strNbSpace(160);
     113                 :         33 :     rtl::OUString tabSpace(0x09);
     114         [ +  - ]:         33 :     PropertyMap aProps;
     115         [ +  - ]:         33 :     if( elem.StyleId != -1 )
     116                 :            :     {
     117         [ +  - ]:         66 :         aProps[ rtl::OUString( "text:style-name"  ) ] =
     118         [ +  - ]:         99 :             m_rEmitContext.rStyles.getStyleName( elem.StyleId );
     119                 :            :     }
     120                 :            : 
     121                 :         33 :     rtl::OUString str(elem.Text.getStr());
     122                 :            : 
     123                 :            :     // Check for RTL
     124                 :         33 :     bool isRTL = false;
     125         [ +  - ]:         33 :     Reference< i18n::XCharacterClassification > xCC( GetCharacterClassification() );
     126         [ +  - ]:         33 :     if( xCC.is() )
     127                 :            :     {
     128         [ +  + ]:        312 :         for(int i=1; i< elem.Text.getLength(); i++)
     129                 :            :         {
     130 [ +  - ][ +  - ]:        279 :             sal_Int16 nType = xCC->getCharacterDirection( str, i );
     131 [ +  - ][ +  - ]:        279 :             if ( nType == ::com::sun::star::i18n::DirectionProperty_RIGHT_TO_LEFT           ||
         [ +  - ][ -  + ]
     132                 :            :                  nType == ::com::sun::star::i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC    ||
     133                 :            :                  nType == ::com::sun::star::i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING ||
     134                 :            :                  nType == ::com::sun::star::i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE
     135                 :            :                 )
     136                 :          0 :                 isRTL = true;
     137                 :            :         }
     138                 :            :     }
     139                 :            : 
     140         [ -  + ]:         33 :     if (isRTL)  // If so, reverse string
     141         [ #  # ]:          0 :         str = m_rProcessor.mirrorString( str );
     142                 :            : 
     143         [ +  - ]:         33 :     m_rEmitContext.rEmitter.beginTag( "text:span", aProps );
     144                 :            : 
     145         [ +  + ]:        345 :     for(int i=0; i< elem.Text.getLength(); i++)
     146                 :            :     {
     147                 :        312 :         rtl::OUString strToken=  str.copy(i,1) ;
     148 [ -  + ][ +  + ]:        312 :         if( strSpace.equals(strToken) || strNbSpace.equals(strToken))
                 [ +  + ]
     149                 :            :         {
     150 [ +  - ][ +  - ]:         42 :             aProps[ USTR( "text:c" ) ] = USTR( "1" );
                 [ +  - ]
     151         [ +  - ]:         42 :             m_rEmitContext.rEmitter.beginTag( "text:s", aProps );
     152         [ +  - ]:         42 :             m_rEmitContext.rEmitter.endTag( "text:s");
     153                 :            :         }
     154                 :            :         else
     155                 :            :         {
     156         [ -  + ]:        270 :             if( tabSpace.equals(strToken) )
     157                 :            :             {
     158         [ #  # ]:          0 :                 m_rEmitContext.rEmitter.beginTag( "text:tab", aProps );
     159         [ #  # ]:          0 :                 m_rEmitContext.rEmitter.endTag( "text:tab");
     160                 :            :             }
     161                 :            :             else
     162                 :            :             {
     163         [ +  - ]:        270 :                 m_rEmitContext.rEmitter.write( strToken );
     164                 :            :             }
     165                 :            :         }
     166                 :        312 :     }
     167                 :            : 
     168                 :         33 :     std::list< Element* >::iterator this_it =  elem.Children.begin();
     169 [ -  + ][ #  # ]:         33 :     while( this_it !=elem.Children.end() && *this_it != &elem )
         [ +  - ][ -  + ]
     170                 :            :     {
     171         [ #  # ]:          0 :         (*this_it)->visitedBy( *this, this_it );
     172                 :          0 :         ++this_it;
     173                 :            :     }
     174                 :            : 
     175 [ +  - ][ +  - ]:         33 :     m_rEmitContext.rEmitter.endTag( "text:span" );
     176                 :            : }
     177                 :            : 
     178                 :         33 : void DrawXmlEmitter::visit( ParagraphElement& elem, const std::list< Element* >::const_iterator&   )
     179                 :            : {
     180         [ +  - ]:         33 :     PropertyMap aProps;
     181         [ +  - ]:         33 :     if( elem.StyleId != -1 )
     182                 :            :     {
     183 [ +  - ][ +  - ]:         33 :         aProps[ USTR( "text:style-name" ) ] = m_rEmitContext.rStyles.getStyleName( elem.StyleId );
                 [ +  - ]
     184                 :            :     }
     185                 :         33 :     const char* pTagType = "text:p";
     186         [ -  + ]:         33 :     if( elem.Type == elem.Headline )
     187                 :          0 :         pTagType = "text:h";
     188         [ +  - ]:         33 :     m_rEmitContext.rEmitter.beginTag( pTagType, aProps );
     189                 :            : 
     190                 :         33 :     std::list< Element* >::iterator this_it =  elem.Children.begin();
     191 [ +  + ][ +  - ]:         66 :     while( this_it !=elem.Children.end() && *this_it != &elem )
         [ +  - ][ +  + ]
     192                 :            :     {
     193         [ +  - ]:         33 :         (*this_it)->visitedBy( *this, this_it );
     194                 :         33 :         ++this_it;
     195                 :            :     }
     196                 :            : 
     197 [ +  - ][ +  - ]:         33 :     m_rEmitContext.rEmitter.endTag( pTagType );
     198                 :         33 : }
     199                 :            : 
     200                 :         42 : void DrawXmlEmitter::fillFrameProps( DrawElement&       rElem,
     201                 :            :                                      PropertyMap&       rProps,
     202                 :            :                                      const EmitContext& rEmitContext,
     203                 :            :                                      bool               bWasTransformed
     204                 :            :                                      )
     205                 :            : {
     206                 :         42 :     double rel_x = rElem.x, rel_y = rElem.y;
     207                 :            : 
     208 [ +  - ][ +  - ]:         42 :     rProps[ USTR( "draw:z-index" ) ] = rtl::OUString::valueOf( rElem.ZOrder );
     209 [ +  - ][ +  - ]:         42 :     rProps[ USTR( "draw:style-name" )] = rEmitContext.rStyles.getStyleName( rElem.StyleId );
     210 [ +  - ][ +  - ]:         42 :     rProps[ USTR( "svg:width" ) ]   = convertPixelToUnitString( rElem.w );
     211 [ +  - ][ +  - ]:         42 :     rProps[ USTR( "svg:height" ) ]  = convertPixelToUnitString( rElem.h );
     212                 :            : 
     213                 :            :     const GraphicsContext& rGC =
     214                 :         42 :         rEmitContext.rProcessor.getGraphicsContext( rElem.GCId );
     215 [ +  + ][ +  + ]:         42 :     if( rGC.Transformation.isIdentity() || bWasTransformed )
                 [ +  - ]
     216                 :            :     {
     217 [ +  - ][ +  - ]:          9 :         rProps[ USTR( "svg:x" ) ]       = convertPixelToUnitString( rel_x );
     218 [ +  - ][ +  - ]:          9 :         rProps[ USTR( "svg:y" ) ]       = convertPixelToUnitString( rel_y );
     219                 :            :     }
     220                 :            :     else
     221                 :            :     {
     222                 :         33 :         basegfx::B2DTuple aScale, aTranslation;
     223                 :            :         double fRotate, fShearX;
     224                 :            : 
     225         [ +  - ]:         33 :         rGC.Transformation.decompose( aScale, aTranslation, fRotate, fShearX );
     226                 :            : 
     227                 :         33 :         rtl::OUStringBuffer aBuf( 256 );
     228                 :            : 
     229                 :            :         // TODO(F2): general transformation case missing; if implemented, note
     230                 :            :         // that ODF rotation is oriented the other way
     231                 :            : 
     232                 :            :         // vertical mirroring is done by horizontally mirroring and rotaing 180 degree
     233                 :            :         // quaint !
     234         [ -  + ]:         33 :         if( rElem.MirrorVertical )
     235                 :          0 :             fRotate += M_PI;
     236                 :            : 
     237                 :            :         // build transformation string
     238         [ -  + ]:         33 :         if( fShearX != 0.0 )
     239                 :            :         {
     240         [ #  # ]:          0 :             aBuf.appendAscii( "skewX( " );
     241         [ #  # ]:          0 :             aBuf.append( fShearX );
     242         [ #  # ]:          0 :             aBuf.appendAscii( " )" );
     243                 :            :         }
     244         [ -  + ]:         33 :         if( fRotate != 0.0 )
     245                 :            :         {
     246         [ #  # ]:          0 :             if( aBuf.getLength() > 0 )
     247         [ #  # ]:          0 :                 aBuf.append( sal_Unicode(' ') );
     248         [ #  # ]:          0 :             aBuf.appendAscii( "rotate( " );
     249         [ #  # ]:          0 :             aBuf.append( -fRotate );
     250         [ #  # ]:          0 :             aBuf.appendAscii( " )" );
     251                 :            : 
     252                 :            :         }
     253         [ -  + ]:         33 :         if( aBuf.getLength() > 0 )
     254         [ #  # ]:          0 :             aBuf.append( sal_Unicode(' ') );
     255         [ +  - ]:         33 :         aBuf.appendAscii( "translate( " );
     256 [ +  - ][ +  - ]:         33 :         aBuf.append( convertPixelToUnitString( rel_x ) );
     257         [ +  - ]:         33 :         aBuf.append( sal_Unicode(' ') );
     258 [ +  - ][ +  - ]:         33 :         aBuf.append( convertPixelToUnitString( rel_y ) );
     259         [ +  - ]:         33 :         aBuf.appendAscii( " )" );
     260                 :            : 
     261 [ +  - ][ +  - ]:         33 :         rProps[ USTR( "draw:transform" ) ] = aBuf.makeStringAndClear();
                 [ +  - ]
     262                 :            :     }
     263                 :         42 : }
     264                 :            : 
     265                 :         33 : void DrawXmlEmitter::visit( FrameElement& elem, const std::list< Element* >::const_iterator&   )
     266                 :            : {
     267         [ +  - ]:         33 :     if( elem.Children.empty() )
     268                 :         33 :         return;
     269                 :            : 
     270 [ +  - ][ +  - ]:         33 :     bool bTextBox = (dynamic_cast<ParagraphElement*>(elem.Children.front()) != NULL);
                 [ +  - ]
     271         [ +  - ]:         33 :     PropertyMap aFrameProps;
     272         [ +  - ]:         33 :     fillFrameProps( elem, aFrameProps, m_rEmitContext );
     273         [ +  - ]:         33 :     m_rEmitContext.rEmitter.beginTag( "draw:frame", aFrameProps );
     274         [ +  - ]:         33 :     if( bTextBox )
     275 [ +  - ][ +  - ]:         33 :         m_rEmitContext.rEmitter.beginTag( "draw:text-box", PropertyMap() );
                 [ +  - ]
     276                 :            : 
     277                 :         33 :     std::list< Element* >::iterator this_it =  elem.Children.begin();
     278 [ +  + ][ +  - ]:         66 :     while( this_it !=elem.Children.end() && *this_it != &elem )
         [ +  - ][ +  + ]
     279                 :            :     {
     280         [ +  - ]:         33 :         (*this_it)->visitedBy( *this, this_it );
     281                 :         33 :         ++this_it;
     282                 :            :     }
     283                 :            : 
     284         [ +  - ]:         33 :     if( bTextBox )
     285         [ +  - ]:         33 :         m_rEmitContext.rEmitter.endTag( "draw:text-box" );
     286 [ +  - ][ +  - ]:         33 :     m_rEmitContext.rEmitter.endTag( "draw:frame" );
     287                 :            : }
     288                 :            : 
     289                 :          9 : void DrawXmlEmitter::visit( PolyPolyElement& elem, const std::list< Element* >::const_iterator& )
     290                 :            : {
     291         [ +  - ]:          9 :     elem.updateGeometry();
     292                 :            :     /* note:
     293                 :            :      *   aw recommends using 100dth of mm in all respects since the xml import
     294                 :            :      *   (a) is buggy (see issue 37213)
     295                 :            :      *   (b) is optimized for 100dth of mm and does not scale itself then,
     296                 :            :      *       this does not gain us speed but makes for smaller rounding errors since
     297                 :            :      *       the xml importer coordinates are integer based
     298                 :            :      */
     299 [ +  - ][ +  + ]:         18 :     for (sal_uInt32 i = 0; i< elem.PolyPoly.count(); i++)
     300                 :            :     {
     301         [ +  - ]:          9 :         basegfx::B2DPolygon b2dPolygon;
     302 [ +  - ][ +  - ]:          9 :         b2dPolygon =  elem.PolyPoly.getB2DPolygon( i );
                 [ +  - ]
     303                 :            : 
     304 [ +  - ][ +  + ]:         36 :         for ( sal_uInt32 j = 0; j< b2dPolygon.count(); j++ )
     305                 :            :         {
     306                 :         27 :             basegfx::B2DPoint point;
     307                 :         27 :             basegfx::B2DPoint nextPoint;
     308         [ +  - ]:         27 :             point = b2dPolygon.getB2DPoint( j );
     309                 :            : 
     310                 :         27 :             basegfx::B2DPoint prevPoint;
     311         [ +  - ]:         27 :             prevPoint = b2dPolygon.getPrevControlPoint( j ) ;
     312                 :            : 
     313                 :         27 :             point.setX( convPx2mmPrec2( point.getX() )*100.0 );
     314                 :         27 :             point.setY( convPx2mmPrec2( point.getY() )*100.0 );
     315                 :            : 
     316 [ +  + ][ +  - ]:         27 :             if ( b2dPolygon.isPrevControlPointUsed( j ) )
     317                 :            :             {
     318                 :         12 :                 prevPoint.setX( convPx2mmPrec2( prevPoint.getX() )*100.0 );
     319                 :         12 :                 prevPoint.setY( convPx2mmPrec2( prevPoint.getY() )*100.0 );
     320                 :            :             }
     321                 :            : 
     322 [ +  - ][ +  + ]:         27 :             if ( b2dPolygon.isNextControlPointUsed( j ) )
     323                 :            :             {
     324         [ +  - ]:         12 :                 nextPoint = b2dPolygon.getNextControlPoint( j ) ;
     325                 :         12 :                 nextPoint.setX( convPx2mmPrec2( nextPoint.getX() )*100.0 );
     326                 :         12 :                 nextPoint.setY( convPx2mmPrec2( nextPoint.getY() )*100.0 );
     327                 :            :             }
     328                 :            : 
     329         [ +  - ]:         27 :             b2dPolygon.setB2DPoint( j, point );
     330                 :            : 
     331 [ +  - ][ +  + ]:         27 :             if ( b2dPolygon.isPrevControlPointUsed( j ) )
     332         [ +  - ]:         12 :                 b2dPolygon.setPrevControlPoint( j , prevPoint ) ;
     333                 :            : 
     334 [ +  - ][ +  + ]:         27 :             if ( b2dPolygon.isNextControlPointUsed( j ) )
     335         [ +  - ]:         12 :                 b2dPolygon.setNextControlPoint( j , nextPoint ) ;
     336                 :         27 :         }
     337                 :            : 
     338         [ +  - ]:          9 :         elem.PolyPoly.setB2DPolygon( i, b2dPolygon );
     339         [ +  - ]:          9 :     }
     340                 :            : 
     341         [ +  - ]:          9 :     PropertyMap aProps;
     342                 :            :     // PDFIProcessor transforms geometrical objects, not images and text
     343                 :            :     // so we need to tell fillFrameProps here that the transformation for
     344                 :            :     // a PolyPolyElement was already applied (aside form translation)
     345         [ +  - ]:          9 :     fillFrameProps( elem, aProps, m_rEmitContext, true );
     346                 :          9 :     rtl::OUStringBuffer aBuf( 64 );
     347         [ +  - ]:          9 :     aBuf.appendAscii( "0 0 " );
     348         [ +  - ]:          9 :     aBuf.append( convPx2mmPrec2(elem.w)*100.0 );
     349         [ +  - ]:          9 :     aBuf.append( sal_Unicode(' ') );
     350         [ +  - ]:          9 :     aBuf.append( convPx2mmPrec2(elem.h)*100.0 );
     351 [ +  - ][ +  - ]:          9 :     aProps[ USTR( "svg:viewBox" ) ] = aBuf.makeStringAndClear();
                 [ +  - ]
     352 [ +  - ][ +  - ]:          9 :     aProps[ USTR( "svg:d" ) ]       = basegfx::tools::exportToSvgD( elem.PolyPoly );
                 [ +  - ]
     353                 :            : 
     354         [ +  - ]:          9 :     m_rEmitContext.rEmitter.beginTag( "draw:path", aProps );
     355 [ +  - ][ +  - ]:          9 :     m_rEmitContext.rEmitter.endTag( "draw:path" );
     356                 :          9 : }
     357                 :            : 
     358                 :          0 : void DrawXmlEmitter::visit( ImageElement& elem, const std::list< Element* >::const_iterator& )
     359                 :            : {
     360         [ #  # ]:          0 :     PropertyMap aImageProps;
     361         [ #  # ]:          0 :     m_rEmitContext.rEmitter.beginTag( "draw:image", aImageProps );
     362 [ #  # ][ #  # ]:          0 :     m_rEmitContext.rEmitter.beginTag( "office:binary-data", PropertyMap() );
                 [ #  # ]
     363         [ #  # ]:          0 :     m_rEmitContext.rImages.writeBase64EncodedStream( elem.Image, m_rEmitContext);
     364         [ #  # ]:          0 :     m_rEmitContext.rEmitter.endTag( "office:binary-data" );
     365 [ #  # ][ #  # ]:          0 :     m_rEmitContext.rEmitter.endTag( "draw:image" );
     366                 :          0 : }
     367                 :            : 
     368                 :          3 : void DrawXmlEmitter::visit( PageElement& elem, const std::list< Element* >::const_iterator&   )
     369                 :            : {
     370         [ +  - ]:          3 :     PropertyMap aPageProps;
     371 [ +  - ][ +  - ]:          3 :     aPageProps[ USTR( "draw:master-page-name" ) ] = m_rEmitContext.rStyles.getStyleName( elem.StyleId );
                 [ +  - ]
     372                 :            : 
     373         [ +  - ]:          3 :     m_rEmitContext.rEmitter.beginTag("draw:page", aPageProps);
     374                 :            : 
     375         [ -  + ]:          3 :     if( m_rEmitContext.xStatusIndicator.is() )
     376 [ #  # ][ #  # ]:          0 :         m_rEmitContext.xStatusIndicator->setValue( elem.PageNumber );
     377                 :            : 
     378                 :          3 :     std::list< Element* >::iterator this_it =  elem.Children.begin();
     379 [ +  + ][ +  - ]:         45 :     while( this_it !=elem.Children.end() && *this_it != &elem )
         [ +  - ][ +  + ]
     380                 :            :     {
     381         [ +  - ]:         42 :         (*this_it)->visitedBy( *this, this_it );
     382                 :         42 :         ++this_it;
     383                 :            :     }
     384                 :            : 
     385 [ +  - ][ +  - ]:          3 :     m_rEmitContext.rEmitter.endTag("draw:page");
     386                 :          3 : }
     387                 :            : 
     388                 :          3 : void DrawXmlEmitter::visit( DocumentElement& elem, const std::list< Element* >::const_iterator&)
     389                 :            : {
     390 [ +  - ][ +  - ]:          3 :     m_rEmitContext.rEmitter.beginTag( "office:body", PropertyMap() );
                 [ +  - ]
     391                 :            :     m_rEmitContext.rEmitter.beginTag( m_bWriteDrawDocument ? "office:drawing" : "office:presentation",
     392 [ +  - ][ +  - ]:          3 :                                       PropertyMap() );
         [ +  - ][ +  - ]
     393                 :            : 
     394                 :          3 :     std::list< Element* >::iterator this_it =  elem.Children.begin();
     395 [ +  + ][ +  - ]:          6 :     while( this_it !=elem.Children.end() && *this_it != &elem )
         [ +  - ][ +  + ]
     396                 :            :     {
     397         [ +  - ]:          3 :         (*this_it)->visitedBy( *this, this_it );
     398                 :          3 :         ++this_it;
     399                 :            :     }
     400                 :            : 
     401 [ +  - ][ +  - ]:          3 :     m_rEmitContext.rEmitter.endTag( m_bWriteDrawDocument ? "office:drawing" : "office:presentation" );
     402         [ +  - ]:          3 :     m_rEmitContext.rEmitter.endTag( "office:body" );
     403                 :          3 : }
     404                 :            : 
     405                 :            : /////////////////////////////////////////////////////////////////
     406                 :            : 
     407                 :          0 : void DrawXmlOptimizer::visit( HyperlinkElement&, const std::list< Element* >::const_iterator& )
     408                 :            : {
     409                 :          0 : }
     410                 :            : 
     411                 :         33 : void DrawXmlOptimizer::visit( TextElement&, const std::list< Element* >::const_iterator&)
     412                 :            : {
     413                 :         33 : }
     414                 :            : 
     415                 :         33 : void DrawXmlOptimizer::visit( FrameElement& elem, const std::list< Element* >::const_iterator& )
     416                 :            : {
     417                 :         33 :     elem.applyToChildren(*this);
     418                 :         33 : }
     419                 :            : 
     420                 :          0 : void DrawXmlOptimizer::visit( ImageElement&, const std::list< Element* >::const_iterator& )
     421                 :            : {
     422                 :          0 : }
     423                 :            : 
     424                 :          9 : void DrawXmlOptimizer::visit( PolyPolyElement& elem, const std::list< Element* >::const_iterator& )
     425                 :            : {
     426                 :            :     /* note: optimize two consecutive PolyPolyElements that
     427                 :            :      *  have the same path but one of which is a stroke while
     428                 :            :      *     the other is a fill
     429                 :            :      */
     430         [ +  - ]:          9 :     if( elem.Parent )
     431                 :            :     {
     432                 :            :         // find following PolyPolyElement in parent's children list
     433                 :          9 :         std::list< Element* >::iterator this_it = elem.Parent->Children.begin();
     434 [ +  - ][ +  + ]:         54 :         while( this_it != elem.Parent->Children.end() && *this_it != &elem )
         [ +  - ][ +  + ]
     435                 :         45 :             ++this_it;
     436                 :            : 
     437         [ +  - ]:          9 :         if( this_it != elem.Parent->Children.end() )
     438                 :            :         {
     439                 :          9 :             std::list< Element* >::iterator next_it = this_it;
     440         [ +  - ]:          9 :             if( ++next_it != elem.Parent->Children.end() )
     441                 :            :             {
     442         [ -  + ]:          9 :                 PolyPolyElement* pNext = dynamic_cast<PolyPolyElement*>(*next_it);
     443                 :            : 
     444                 :            :                 // TODO(F2): this comparison fails for OOo-generated polygons with beziers.
     445 [ +  + ][ +  - ]:          9 :                 if( pNext && pNext->PolyPoly == elem.PolyPoly )
         [ -  + ][ -  + ]
     446                 :            :                 {
     447                 :            :                     const GraphicsContext& rNextGC =
     448         [ #  # ]:          0 :                         m_rProcessor.getGraphicsContext( pNext->GCId );
     449                 :            :                     const GraphicsContext& rThisGC =
     450         [ #  # ]:          0 :                         m_rProcessor.getGraphicsContext( elem.GCId );
     451                 :            : 
     452 [ #  # ][ #  # ]:          0 :                     if( rThisGC.BlendMode      == rNextGC.BlendMode &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     453                 :            :                         rThisGC.Flatness       == rNextGC.Flatness &&
     454         [ #  # ]:          0 :                         rThisGC.Transformation == rNextGC.Transformation &&
     455         [ #  # ]:          0 :                         rThisGC.Clip           == rNextGC.Clip &&
     456                 :            :                         rThisGC.FillColor.Red  == rNextGC.FillColor.Red &&
     457                 :            :                         rThisGC.FillColor.Green== rNextGC.FillColor.Green &&
     458                 :            :                         rThisGC.FillColor.Blue == rNextGC.FillColor.Blue &&
     459                 :            :                         rThisGC.FillColor.Alpha== rNextGC.FillColor.Alpha &&
     460                 :            :                         pNext->Action          == PATH_STROKE &&
     461                 :            :                         (elem.Action == PATH_FILL || elem.Action == PATH_EOFILL) )
     462                 :            :                     {
     463         [ #  # ]:          0 :                         GraphicsContext aGC = rThisGC;
     464                 :          0 :                         aGC.LineJoin  = rNextGC.LineJoin;
     465                 :          0 :                         aGC.LineCap   = rNextGC.LineCap;
     466                 :          0 :                         aGC.LineWidth = rNextGC.LineWidth;
     467                 :          0 :                         aGC.MiterLimit= rNextGC.MiterLimit;
     468         [ #  # ]:          0 :                         aGC.DashArray = rNextGC.DashArray;
     469                 :          0 :                         aGC.LineColor = rNextGC.LineColor;
     470         [ #  # ]:          0 :                         elem.GCId = m_rProcessor.getGCId( aGC );
     471                 :            : 
     472                 :          0 :                         elem.Action |= pNext->Action;
     473                 :            : 
     474         [ #  # ]:          0 :                         elem.Children.splice( elem.Children.end(), pNext->Children );
     475         [ #  # ]:          0 :                         elem.Parent->Children.erase( next_it );
     476 [ #  # ][ #  # ]:          9 :                         delete pNext;
                 [ #  # ]
     477                 :            :                     }
     478                 :            :                 }
     479                 :            :             }
     480                 :            :         }
     481                 :            :     }
     482                 :          9 : }
     483                 :            : 
     484                 :         33 : void DrawXmlOptimizer::visit( ParagraphElement& elem, const std::list< Element* >::const_iterator& )
     485                 :            : {
     486                 :         33 :     optimizeTextElements( elem );
     487                 :            : 
     488                 :         33 :     elem.applyToChildren(*this);
     489                 :         33 : }
     490                 :            : 
     491                 :          3 : void DrawXmlOptimizer::visit( PageElement& elem, const std::list< Element* >::const_iterator& )
     492                 :            : {
     493         [ -  + ]:          3 :     if( m_rProcessor.getStatusIndicator().is() )
     494 [ #  # ][ #  # ]:          0 :         m_rProcessor.getStatusIndicator()->setValue( elem.PageNumber );
     495                 :            : 
     496                 :            :     // resolve hyperlinks
     497         [ +  - ]:          3 :     elem.resolveHyperlinks();
     498                 :            : 
     499         [ +  - ]:          3 :     elem.resolveFontStyles( m_rProcessor ); // underlines and such
     500                 :            : 
     501                 :            :     // FIXME: until hyperlinks and font effects are adjusted for
     502                 :            :     // geometrical search handle them before sorting
     503         [ +  - ]:          3 :     m_rProcessor.sortElements( &elem );
     504                 :            : 
     505                 :            :     // find paragraphs in text
     506                 :          3 :     ParagraphElement* pCurPara = NULL;
     507                 :          3 :     std::list< Element* >::iterator page_element, next_page_element;
     508                 :          3 :     next_page_element = elem.Children.begin();
     509                 :          3 :     double fCurLineHeight = 0.0; // average height of text items in current para
     510                 :          3 :     int nCurLineElements = 0; // number of line contributing elements in current para
     511                 :          3 :     double line_left = elem.w, line_right = 0.0;
     512                 :          3 :     double column_width = elem.w*0.75; // estimate text width
     513                 :            :     // TODO: guess columns
     514         [ +  + ]:         45 :     while( next_page_element != elem.Children.end() )
     515                 :            :     {
     516                 :         42 :         page_element = next_page_element++;
     517         [ -  + ]:         42 :         ParagraphElement* pPagePara = dynamic_cast<ParagraphElement*>(*page_element);
     518         [ -  + ]:         42 :         if( pPagePara )
     519                 :            :         {
     520                 :          0 :             pCurPara = pPagePara;
     521                 :            :             // adjust line height and text items
     522                 :          0 :             fCurLineHeight = 0.0;
     523                 :          0 :             nCurLineElements = 0;
     524         [ #  # ]:          0 :             for( std::list< Element* >::iterator it = pCurPara->Children.begin();
     525                 :          0 :                  it != pCurPara->Children.end(); ++it )
     526                 :            :             {
     527         [ #  # ]:          0 :                 TextElement* pTestText = dynamic_cast<TextElement*>(*it);
     528         [ #  # ]:          0 :                 if( pTestText )
     529                 :            :                 {
     530                 :          0 :                     fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pTestText->h)/double(nCurLineElements+1);
     531                 :          0 :                     nCurLineElements++;
     532                 :            :                 }
     533                 :            :             }
     534                 :          0 :             continue;
     535                 :            :         }
     536                 :            : 
     537         [ -  + ]:         42 :         HyperlinkElement* pLink = dynamic_cast<HyperlinkElement*>(*page_element);
     538         [ -  + ]:         42 :         DrawElement* pDraw = dynamic_cast<DrawElement*>(*page_element);
     539 [ -  + ][ #  # ]:         42 :         if( ! pDraw && pLink && ! pLink->Children.empty() )
         [ #  # ][ -  + ]
     540 [ #  # ][ #  # ]:          0 :             pDraw = dynamic_cast<DrawElement*>(pLink->Children.front() );
     541         [ +  - ]:         42 :         if( pDraw )
     542                 :            :         {
     543                 :            :             // insert small drawing objects as character, else leave them page bound
     544                 :            : 
     545                 :         42 :             bool bInsertToParagraph = false;
     546                 :            :             // first check if this is either inside the paragraph
     547 [ -  + ][ #  # ]:         42 :             if( pCurPara && pDraw->y < pCurPara->y + pCurPara->h )
     548                 :            :             {
     549         [ #  # ]:          0 :                 if( pDraw->h < fCurLineHeight * 1.5 )
     550                 :            :                 {
     551                 :          0 :                     bInsertToParagraph = true;
     552                 :          0 :                     fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pDraw->h)/double(nCurLineElements+1);
     553                 :          0 :                     nCurLineElements++;
     554                 :            :                     // mark draw element as character
     555                 :          0 :                     pDraw->isCharacter = true;
     556                 :            :                 }
     557                 :            :             }
     558                 :            :             // or perhaps the draw element begins a new paragraph
     559         [ +  + ]:         42 :             else if( next_page_element != elem.Children.end() )
     560                 :            :             {
     561         [ -  + ]:         39 :                 TextElement* pText = dynamic_cast<TextElement*>(*next_page_element);
     562         [ +  - ]:         39 :                 if( ! pText )
     563                 :            :                 {
     564         [ -  + ]:         39 :                     ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(*next_page_element);
     565 [ -  + ][ #  # ]:         39 :                     if( pPara && ! pPara->Children.empty() )
                 [ -  + ]
     566 [ #  # ][ #  # ]:          0 :                         pText = dynamic_cast<TextElement*>(pPara->Children.front());
     567                 :            :                 }
     568 [ -  + ][ #  # ]:         39 :                 if( pText && // check there is a text
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     569                 :            :                     pDraw->h < pText->h*1.5 && // and it is approx the same height
     570                 :            :                     // and either upper or lower edge of pDraw is inside text's vertical range
     571                 :            :                     ( ( pDraw->y >= pText->y && pDraw->y <= pText->y+pText->h ) ||
     572                 :            :                       ( pDraw->y+pDraw->h >= pText->y && pDraw->y+pDraw->h <= pText->y+pText->h )
     573                 :            :                       )
     574                 :            :                     )
     575                 :            :                 {
     576                 :          0 :                     bInsertToParagraph = true;
     577                 :          0 :                     fCurLineHeight = pDraw->h;
     578                 :          0 :                     nCurLineElements = 1;
     579                 :          0 :                     line_left = pDraw->x;
     580                 :          0 :                     line_right = pDraw->x + pDraw->w;
     581                 :            :                     // begin a new paragraph
     582                 :          0 :                     pCurPara = NULL;
     583                 :            :                     // mark draw element as character
     584                 :          0 :                     pDraw->isCharacter = true;
     585                 :            :                 }
     586                 :            :             }
     587                 :            : 
     588         [ +  - ]:         42 :             if( ! bInsertToParagraph )
     589                 :            :             {
     590                 :         42 :                 pCurPara = NULL;
     591                 :         42 :                 continue;
     592                 :            :             }
     593                 :            :         }
     594                 :            : 
     595         [ #  # ]:          0 :         TextElement* pText = dynamic_cast<TextElement*>(*page_element);
     596 [ #  # ][ #  # ]:          0 :         if( ! pText && pLink && ! pLink->Children.empty() )
         [ #  # ][ #  # ]
     597 [ #  # ][ #  # ]:          0 :             pText = dynamic_cast<TextElement*>(pLink->Children.front());
     598         [ #  # ]:          0 :         if( pText )
     599                 :            :         {
     600                 :            :             Element* pGeo = pLink ? static_cast<Element*>(pLink) :
     601         [ #  # ]:          0 :                                     static_cast<Element*>(pText);
     602         [ #  # ]:          0 :             if( pCurPara )
     603                 :            :             {
     604                 :            :                 // there was already a text element, check for a new paragraph
     605         [ #  # ]:          0 :                 if( nCurLineElements > 0 )
     606                 :            :                 {
     607                 :            :                     // if the new text is significantly distant from the paragraph
     608                 :            :                     // begin a new paragraph
     609         [ #  # ]:          0 :                     if( pGeo->y > pCurPara->y + pCurPara->h + fCurLineHeight*0.5  )
     610                 :          0 :                         pCurPara = NULL; // insert new paragraph
     611         [ #  # ]:          0 :                     else if( pGeo->y > (pCurPara->y+pCurPara->h - fCurLineHeight*0.05) )
     612                 :            :                     {
     613                 :            :                         // new paragraph if either the last line of the paragraph
     614                 :            :                         // was significantly shorter than the paragraph as a whole
     615         [ #  # ]:          0 :                         if( (line_right - line_left) < pCurPara->w*0.75 )
     616                 :          0 :                             pCurPara = NULL;
     617                 :            :                         // or the last line was significantly smaller than the column width
     618         [ #  # ]:          0 :                         else if( (line_right - line_left) < column_width*0.75 )
     619                 :          0 :                             pCurPara = NULL;
     620                 :            :                     }
     621                 :            :                 }
     622                 :            : 
     623                 :            : 
     624                 :            :             }
     625                 :            : 
     626                 :            : 
     627                 :            :             // update line height/width
     628         [ #  # ]:          0 :             if( pCurPara )
     629                 :            :             {
     630                 :          0 :                 fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pGeo->h)/double(nCurLineElements+1);
     631                 :          0 :                 nCurLineElements++;
     632         [ #  # ]:          0 :                 if( pGeo->x < line_left )
     633                 :          0 :                     line_left = pGeo->x;
     634         [ #  # ]:          0 :                 if( pGeo->x+pGeo->w > line_right )
     635                 :          0 :                     line_right = pGeo->x+pGeo->w;
     636                 :            :             }
     637                 :            :             else
     638                 :            :             {
     639                 :          0 :                 fCurLineHeight = pGeo->h;
     640                 :          0 :                 nCurLineElements = 1;
     641                 :          0 :                 line_left = pGeo->x;
     642                 :          0 :                 line_right = pGeo->x + pGeo->w;
     643                 :            :             }
     644                 :            :         }
     645                 :            : 
     646                 :            : 
     647                 :            :         // move element to current paragraph
     648         [ #  # ]:          0 :        if (! pCurPara )  // new paragraph, insert one
     649                 :            :        {
     650 [ #  # ][ #  # ]:          0 :             pCurPara = m_rProcessor.getElementFactory()->createParagraphElement( NULL );
                 [ #  # ]
     651                 :            :             // set parent
     652                 :          0 :             pCurPara->Parent = &elem;
     653                 :            :             //insert new paragraph before current element
     654         [ #  # ]:          0 :             page_element = elem.Children.insert( page_element, pCurPara );
     655                 :            :             // forward iterator to current element again
     656                 :          0 :             ++ page_element;
     657                 :            :             // update next_element which is now invalid
     658                 :          0 :             next_page_element = page_element;
     659                 :          0 :             ++ next_page_element;
     660                 :            :        }
     661                 :          0 :         Element* pCurEle = *page_element;
     662         [ #  # ]:          0 :         pCurEle->setParent( page_element, pCurPara );
     663                 :            :         OSL_ENSURE( !pText || pCurEle == pText || pCurEle == pLink, "paragraph child list in disorder" );
     664 [ #  # ][ #  # ]:          0 :         if( pText || pDraw )
     665         [ #  # ]:          0 :             pCurPara->updateGeometryWith( pCurEle );
     666                 :            :     }
     667                 :            : 
     668                 :            :     // process children
     669         [ +  - ]:          3 :     elem.applyToChildren(*this);
     670                 :          3 : }
     671                 :            : 
     672                 :          0 : bool isSpaces(TextElement* pTextElem)
     673                 :            : {
     674         [ #  # ]:          0 :     for (sal_Int32 i = 0; i != pTextElem->Text.getLength(); ++i) {
     675         [ #  # ]:          0 :         if (pTextElem->Text[i] != ' ') {
     676                 :          0 :             return false;
     677                 :            :         }
     678                 :            :     }
     679                 :          0 :     return true;
     680                 :            : }
     681                 :            : 
     682                 :          0 : bool notTransformed(GraphicsContext GC)
     683                 :            : {
     684                 :            :     return (
     685                 :          0 :         GC.Transformation.get(0,0) ==  100.00 &&
     686                 :          0 :         GC.Transformation.get(1,0) ==    0.00 &&
     687                 :          0 :         GC.Transformation.get(0,1) ==    0.00 &&
     688                 :          0 :         GC.Transformation.get(1,1) == -100.00
     689   [ #  #  #  #  :          0 :        );
             #  #  #  # ]
     690                 :            : }
     691                 :            : 
     692                 :         33 : void DrawXmlOptimizer::optimizeTextElements(Element& rParent)
     693                 :            : {
     694         [ +  - ]:         33 :     if( rParent.Children.empty() ) // this should not happen
     695                 :            :     {
     696                 :            :         OSL_FAIL( "empty paragraph optimized" );
     697                 :         33 :         return;
     698                 :            :     }
     699                 :            : 
     700                 :            :     // concatenate child elements with same font id
     701                 :         33 :     std::list< Element* >::iterator next = rParent.Children.begin();
     702                 :         33 :     std::list< Element* >::iterator it = next++;
     703                 :            : 
     704         [ +  + ]:        312 :     while( next != rParent.Children.end() )
     705                 :            :     {
     706                 :        279 :         bool bConcat = false;
     707         [ -  + ]:        279 :         TextElement* pCur = dynamic_cast<TextElement*>(*it);
     708                 :            : 
     709         [ +  - ]:        279 :         if( pCur )
     710                 :            :         {
     711         [ -  + ]:        279 :             TextElement* pNext = dynamic_cast<TextElement*>(*next);
     712                 :        279 :             bool isComplex = false;
     713                 :        279 :             rtl::OUString str(pCur->Text.getStr());
     714         [ +  + ]:       2394 :             for(int i=0; i< str.getLength(); i++)
     715                 :            :             {
     716 [ +  - ][ +  - ]:       2115 :                 sal_Int16 nType = GetBreakIterator()->getScriptType( str, i );
                 [ +  - ]
     717         [ -  + ]:       2115 :                 if (nType == ::com::sun::star::i18n::ScriptType::COMPLEX)
     718                 :          0 :                     isComplex = true;
     719                 :            :             }
     720                 :        279 :             bool bPara = strspn("ParagraphElement", typeid(rParent).name());
     721         [ -  + ]:        279 :             ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(&rParent);
     722 [ +  - ][ -  + ]:        279 :             if (bPara && isComplex)
     723                 :          0 :                 pPara->bRtl = true;
     724         [ +  - ]:        279 :             if( pNext )
     725                 :            :             {
     726         [ +  - ]:        279 :                 const GraphicsContext& rCurGC = m_rProcessor.getGraphicsContext( pCur->GCId );
     727         [ +  - ]:        279 :                 const GraphicsContext& rNextGC = m_rProcessor.getGraphicsContext( pNext->GCId );
     728                 :            : 
     729                 :            :                 // line and space optimization; works only in strictly horizontal mode
     730                 :            : 
     731                 :            :                 // concatenate consecutive text elements unless there is a
     732                 :            :                 // font or text color or matrix change, leave a new span in that case
     733 [ -  + ][ #  # ]:        837 :                 if( (pCur->FontId == pNext->FontId || isSpaces(pNext)) &&
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
                 [ +  - ]
     734                 :            :                     rCurGC.FillColor.Red == rNextGC.FillColor.Red &&
     735                 :            :                     rCurGC.FillColor.Green == rNextGC.FillColor.Green &&
     736                 :            :                     rCurGC.FillColor.Blue == rNextGC.FillColor.Blue &&
     737                 :            :                     rCurGC.FillColor.Alpha == rNextGC.FillColor.Alpha &&
     738 [ +  - ][ #  # ]:        558 :                     (rCurGC.Transformation == rNextGC.Transformation || notTransformed(rNextGC))
         [ #  # ][ -  + ]
         [ #  # ][ #  # ]
     739                 :            :                     )
     740                 :            :                 {
     741         [ +  - ]:        279 :                     pCur->updateGeometryWith( pNext );
     742                 :            :                     // append text to current element
     743         [ +  - ]:        279 :                         pCur->Text.append( pNext->Text.getStr(), pNext->Text.getLength() );
     744                 :            : 
     745                 :        279 :                         str = pCur->Text.getStr();
     746         [ +  + ]:       2673 :                     for(int i=0; i< str.getLength(); i++)
     747                 :            :                     {
     748 [ +  - ][ +  - ]:       2394 :                         sal_Int16 nType = GetBreakIterator()->getScriptType( str, i );
                 [ +  - ]
     749         [ -  + ]:       2394 :                         if (nType == ::com::sun::star::i18n::ScriptType::COMPLEX)
     750                 :          0 :                             isComplex = true;
     751                 :            :                     }
     752 [ +  - ][ -  + ]:        279 :                     if (bPara && isComplex)
     753                 :          0 :                         pPara->bRtl = true;
     754                 :            :                     // append eventual children to current element
     755                 :            :                     // and clear children (else the children just
     756                 :            :                     // appended to pCur would be destroyed)
     757         [ +  - ]:        279 :                     pCur->Children.splice( pCur->Children.end(), pNext->Children );
     758                 :            :                     // get rid of the now useless element
     759         [ +  - ]:        279 :                     rParent.Children.erase( next );
     760 [ +  - ][ +  - ]:        279 :                     delete pNext;
     761                 :        279 :                     bConcat = true;
     762                 :            :                 }
     763                 :        279 :             }
     764                 :            :         }
     765 [ #  # ][ #  # ]:          0 :         else if( dynamic_cast<HyperlinkElement*>(*it) )
                 [ #  # ]
     766         [ #  # ]:          0 :             optimizeTextElements( **it );
     767         [ +  - ]:        279 :         if ( bConcat )
     768                 :        279 :             next = it;
     769                 :            :         else
     770                 :          0 :             ++it;
     771                 :        279 :         ++next;
     772                 :            :     }
     773                 :            : }
     774                 :            : 
     775                 :          3 : void DrawXmlOptimizer::visit( DocumentElement& elem, const std::list< Element* >::const_iterator&)
     776                 :            : {
     777                 :          3 :     elem.applyToChildren(*this);
     778                 :          3 : }
     779                 :            : 
     780                 :            : //////////////////////////////////////////////////////////////////////////////////
     781                 :            : 
     782                 :            : 
     783                 :          9 : void DrawXmlFinalizer::visit( PolyPolyElement& elem, const std::list< Element* >::const_iterator& )
     784                 :            : {
     785                 :            :     // xxx TODO copied from DrawElement
     786         [ +  - ]:          9 :     const GraphicsContext& rGC = m_rProcessor.getGraphicsContext(elem.GCId );
     787         [ +  - ]:          9 :     PropertyMap aProps;
     788 [ +  - ][ +  - ]:          9 :     aProps[ USTR( "style:family" ) ] = USTR( "graphic" );
                 [ +  - ]
     789 [ +  - ][ +  - ]:          9 :     aProps[ USTR( "style:parent-style-name") ] = USTR( "standard" );
                 [ +  - ]
     790                 :            :     // generate standard graphic style if necessary
     791         [ +  - ]:          9 :     m_rStyleContainer.getStandardStyleId( "graphic" );
     792                 :            : 
     793         [ +  - ]:          9 :     PropertyMap aGCProps;
     794                 :            : 
     795                 :            :     // TODO(F3): proper dash emulation
     796         [ +  + ]:          9 :     if( elem.Action & PATH_STROKE )
     797                 :            :     {
     798 [ +  + ][ +  - ]:          6 :         aGCProps[ USTR("draw:stroke") ] = rGC.DashArray.empty() ? USTR("solid") : USTR("dash");
         [ +  - ][ +  - ]
                 [ +  - ]
     799 [ +  - ][ +  - ]:          6 :         aGCProps[ USTR("svg:stroke-color") ] = getColorString( rGC.LineColor );
                 [ +  - ]
     800         [ +  + ]:          6 :         if( rGC.LineWidth != 0.0 )
     801                 :            :         {
     802                 :          3 :             ::basegfx::B2DVector aVec(rGC.LineWidth,0);
     803         [ +  - ]:          3 :             aVec *= rGC.Transformation;
     804                 :            : 
     805                 :          3 :             aVec.setX ( convPx2mmPrec2( aVec.getX() )*100.0 );
     806                 :          3 :             aVec.setY ( convPx2mmPrec2( aVec.getY() )*100.0 );
     807                 :            : 
     808 [ +  - ][ +  - ]:          3 :             aGCProps[ USTR("svg:stroke-width") ] = rtl::OUString::valueOf( aVec.getLength() );
                 [ +  - ]
     809                 :            :         }
     810                 :            :     }
     811                 :            :     else
     812                 :            :     {
     813 [ +  - ][ +  - ]:          3 :         aGCProps[ USTR("draw:stroke") ] = USTR("none");
                 [ +  - ]
     814                 :            :     }
     815                 :            : 
     816                 :            :     // TODO(F1): check whether stuff could be emulated by gradient/bitmap/hatch
     817         [ +  + ]:          9 :     if( elem.Action & (PATH_FILL | PATH_EOFILL) )
     818                 :            :     {
     819 [ +  - ][ +  - ]:          3 :         aGCProps[ USTR("draw:fill") ]   = USTR("solid");
                 [ +  - ]
     820 [ +  - ][ +  - ]:          3 :         aGCProps[ USTR("draw:fill-color") ] = getColorString( rGC.FillColor );
                 [ +  - ]
     821                 :            :     }
     822                 :            :     else
     823                 :            :     {
     824 [ +  - ][ +  - ]:          6 :         aGCProps[ USTR("draw:fill") ] = USTR("none");
                 [ +  - ]
     825                 :            :     }
     826                 :            : 
     827         [ +  - ]:          9 :     StyleContainer::Style aStyle( "style:style", aProps );
     828         [ +  - ]:          9 :     StyleContainer::Style aSubStyle( "style:graphic-properties", aGCProps );
     829         [ +  - ]:          9 :     aStyle.SubStyles.push_back( &aSubStyle );
     830                 :            : 
     831 [ +  - ][ +  - ]:          9 :     elem.StyleId = m_rStyleContainer.getStyleId( aStyle );
         [ +  - ][ +  - ]
                 [ +  - ]
     832                 :          9 : }
     833                 :            : 
     834                 :          0 : void DrawXmlFinalizer::visit( HyperlinkElement&, const std::list< Element* >::const_iterator& )
     835                 :            : {
     836                 :          0 : }
     837                 :            : 
     838                 :         33 : void DrawXmlFinalizer::visit( TextElement& elem, const std::list< Element* >::const_iterator& )
     839                 :            : {
     840         [ +  - ]:         33 :     const FontAttributes& rFont = m_rProcessor.getFont( elem.FontId );
     841         [ +  - ]:         33 :     PropertyMap aProps;
     842 [ +  - ][ +  - ]:         33 :     aProps[ USTR( "style:family" ) ] = USTR( "text" );
                 [ +  - ]
     843                 :            : 
     844         [ +  - ]:         33 :     PropertyMap aFontProps;
     845                 :            : 
     846                 :            :     // family name
     847 [ +  - ][ +  - ]:         33 :     aFontProps[ USTR( "fo:font-family" ) ] = rFont.familyName;
     848 [ +  - ][ +  - ]:         33 :     aFontProps[ USTR( "style:font-family-complex" ) ] = rFont.familyName;
     849                 :            : 
     850                 :            :     // bold
     851         [ -  + ]:         33 :     if( rFont.isBold )
     852                 :            :     {
     853 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "fo:font-weight" ) ]         = USTR( "bold" );
                 [ #  # ]
     854 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "fo:font-weight-asian" ) ]   = USTR( "bold" );
                 [ #  # ]
     855 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "style:font-weight-complex" ) ] = USTR( "bold" );
                 [ #  # ]
     856                 :            :     }
     857                 :            :     // italic
     858         [ -  + ]:         33 :     if( rFont.isItalic )
     859                 :            :     {
     860 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "fo:font-style" ) ]         = USTR( "italic" );
                 [ #  # ]
     861 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "fo:font-style-asian" ) ]   = USTR( "italic" );
                 [ #  # ]
     862 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "style:font-style-complex" ) ] = USTR( "italic" );
                 [ #  # ]
     863                 :            :     }
     864                 :            :     // underline
     865         [ -  + ]:         33 :     if( rFont.isUnderline )
     866                 :            :     {
     867 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "style:text-underline-style" ) ]  = USTR( "solid" );
                 [ #  # ]
     868 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "style:text-underline-width" ) ]  = USTR( "auto" );
                 [ #  # ]
     869 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "style:text-underline-color" ) ]  = USTR( "font-color" );
                 [ #  # ]
     870                 :            :     }
     871                 :            :     // outline
     872         [ -  + ]:         33 :     if( rFont.isOutline )
     873                 :            :     {
     874 [ #  # ][ #  # ]:          0 :         aFontProps[ USTR( "style:text-outline" ) ]  = USTR( "true" );
                 [ #  # ]
     875                 :            :     }
     876                 :            :     // size
     877                 :         33 :     rtl::OUStringBuffer aBuf( 32 );
     878         [ +  - ]:         33 :     aBuf.append( rFont.size*72/PDFI_OUTDEV_RESOLUTION );
     879         [ +  - ]:         33 :     aBuf.appendAscii( "pt" );
     880         [ +  - ]:         33 :     rtl::OUString aFSize = aBuf.makeStringAndClear();
     881 [ +  - ][ +  - ]:         33 :     aFontProps[ USTR( "fo:font-size" ) ]            = aFSize;
     882 [ +  - ][ +  - ]:         33 :     aFontProps[ USTR( "style:font-size-asian" ) ]   = aFSize;
     883 [ +  - ][ +  - ]:         33 :     aFontProps[ USTR( "style:font-size-complex" ) ] = aFSize;
     884                 :            :     // color
     885         [ +  - ]:         33 :     const GraphicsContext& rGC = m_rProcessor.getGraphicsContext( elem.GCId );
     886 [ -  + ][ +  - ]:         33 :     aFontProps[ USTR( "fo:color" ) ]                 =  getColorString( rFont.isOutline ? rGC.LineColor : rGC.FillColor );
         [ +  - ][ +  - ]
     887                 :            : 
     888         [ +  - ]:         33 :     StyleContainer::Style aStyle( "style:style", aProps );
     889         [ +  - ]:         33 :     StyleContainer::Style aSubStyle( "style:text-properties", aFontProps );
     890         [ +  - ]:         33 :     aStyle.SubStyles.push_back( &aSubStyle );
     891 [ +  - ][ +  - ]:         33 :     elem.StyleId = m_rStyleContainer.getStyleId( aStyle );
         [ +  - ][ +  - ]
                 [ +  - ]
     892                 :         33 : }
     893                 :            : 
     894                 :         33 : void DrawXmlFinalizer::visit( ParagraphElement& elem, const std::list< Element* >::const_iterator& )
     895                 :            : {
     896                 :            : 
     897         [ +  - ]:         33 :     PropertyMap aProps;
     898 [ +  - ][ +  - ]:         33 :     aProps[ USTR( "style:family" ) ] = USTR( "paragraph" );
                 [ +  - ]
     899                 :            :     // generate standard paragraph style if necessary
     900         [ +  - ]:         33 :     m_rStyleContainer.getStandardStyleId( "paragraph" );
     901                 :            : 
     902         [ +  - ]:         33 :     PropertyMap aParProps;
     903                 :            : 
     904 [ +  - ][ +  - ]:         33 :     aParProps[ USTR("fo:text-align")]                   = USTR("start");
                 [ +  - ]
     905         [ -  + ]:         33 :     if (elem.bRtl)
     906 [ #  # ][ #  # ]:          0 :         aParProps[ USTR("style:writing-mode")]                    = USTR("rl-tb");
                 [ #  # ]
     907                 :            :     else
     908 [ +  - ][ +  - ]:         33 :         aParProps[ USTR("style:writing-mode")]                    = USTR("lr-tb");
                 [ +  - ]
     909                 :            : 
     910         [ +  - ]:         33 :     StyleContainer::Style aStyle( "style:style", aProps );
     911         [ +  - ]:         33 :     StyleContainer::Style aSubStyle( "style:paragraph-properties", aParProps );
     912         [ +  - ]:         33 :     aStyle.SubStyles.push_back( &aSubStyle );
     913                 :            : 
     914         [ +  - ]:         33 :     elem.StyleId = m_rStyleContainer.getStyleId( aStyle );
     915                 :            : 
     916 [ +  - ][ +  - ]:         33 :     elem.applyToChildren(*this);
         [ +  - ][ +  - ]
                 [ +  - ]
     917                 :         33 : }
     918                 :            : 
     919                 :         33 : void DrawXmlFinalizer::visit( FrameElement& elem, const std::list< Element* >::const_iterator&)
     920                 :            : {
     921         [ +  - ]:         33 :     PropertyMap aProps;
     922 [ +  - ][ +  - ]:         33 :     aProps[ USTR( "style:family" ) ] = USTR( "graphic" );
                 [ +  - ]
     923 [ +  - ][ +  - ]:         33 :     aProps[ USTR( "style:parent-style-name") ] = USTR( "standard" );
                 [ +  - ]
     924                 :            :     // generate standard graphic style if necessary
     925         [ +  - ]:         33 :     m_rStyleContainer.getStandardStyleId( "graphic" );
     926                 :            : 
     927         [ +  - ]:         33 :     PropertyMap aGCProps;
     928                 :            : 
     929 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("draw:stroke") ]                    = USTR("none");
                 [ +  - ]
     930 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("draw:fill") ]                      = USTR("none");
                 [ +  - ]
     931 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("draw:auto-grow-height") ]          = USTR("true");
                 [ +  - ]
     932 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("draw:auto-grow-width") ]           = USTR("true");
                 [ +  - ]
     933 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("draw:textarea-horizontal-align") ] = USTR("left");
                 [ +  - ]
     934 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("draw:textarea-vertical-align") ]   = USTR("top");
                 [ +  - ]
     935 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("fo:min-height")]                   = USTR("0cm");
                 [ +  - ]
     936 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("fo:min-width")]                    = USTR("0cm");
                 [ +  - ]
     937 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("fo:padding-top") ]                 = USTR("0cm");
                 [ +  - ]
     938 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("fo:padding-left") ]                = USTR("0cm");
                 [ +  - ]
     939 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("fo:padding-right") ]               = USTR("0cm");
                 [ +  - ]
     940 [ +  - ][ +  - ]:         33 :     aGCProps[ USTR("fo:padding-bottom") ]              = USTR("0cm");
                 [ +  - ]
     941                 :            : 
     942                 :            :     // remark: vertical mirroring is done in current OOO by
     943                 :            :     // mirroring horzontally and rotating 180 degrees
     944                 :            :     // this is quaint, but unfortunately it seems
     945                 :            :     // mirror=vertical is defined but not implemented in current code
     946         [ -  + ]:         33 :     if( elem.MirrorVertical )
     947 [ #  # ][ #  # ]:          0 :         aGCProps[ USTR("style:mirror") ] = USTR("horizontal");
                 [ #  # ]
     948                 :            : 
     949         [ +  - ]:         33 :     StyleContainer::Style aStyle( "style:style", aProps );
     950         [ +  - ]:         33 :     StyleContainer::Style aSubStyle( "style:graphic-properties", aGCProps );
     951         [ +  - ]:         33 :     aStyle.SubStyles.push_back( &aSubStyle );
     952                 :            : 
     953         [ +  - ]:         33 :     elem.StyleId = m_rStyleContainer.getStyleId( aStyle );
     954 [ +  - ][ +  - ]:         33 :     elem.applyToChildren(*this);
         [ +  - ][ +  - ]
                 [ +  - ]
     955                 :         33 : }
     956                 :            : 
     957                 :          0 : void DrawXmlFinalizer::visit( ImageElement&, const std::list< Element* >::const_iterator& )
     958                 :            : {
     959                 :          0 : }
     960                 :            : 
     961                 :          3 : void DrawXmlFinalizer::visit( PageElement& elem, const std::list< Element* >::const_iterator& )
     962                 :            : {
     963         [ -  + ]:          3 :     if( m_rProcessor.getStatusIndicator().is() )
     964 [ #  # ][ #  # ]:          0 :         m_rProcessor.getStatusIndicator()->setValue( elem.PageNumber );
     965                 :            : 
     966                 :            :     // transform from pixel to mm
     967                 :          3 :     double page_width = convPx2mm( elem.w ), page_height = convPx2mm( elem.h );
     968                 :            : 
     969                 :            :     // calculate page margins out of the relevant children (paragraphs)
     970                 :          3 :     elem.TopMargin = elem.h, elem.BottomMargin = 0, elem.LeftMargin = elem.w, elem.RightMargin = 0;
     971                 :            : 
     972         [ +  + ]:         45 :     for( std::list< Element* >::const_iterator it = elem.Children.begin(); it != elem.Children.end(); ++it )
     973                 :            :     {
     974         [ +  + ]:         42 :         if( (*it)->x < elem.LeftMargin )
     975                 :          3 :             elem.LeftMargin = (*it)->x;
     976         [ +  + ]:         42 :         if( (*it)->y < elem.TopMargin )
     977                 :          6 :             elem.TopMargin = (*it)->y;
     978         [ +  + ]:         42 :         if( (*it)->x + (*it)->w > elem.RightMargin )
     979                 :         12 :             elem.RightMargin = ((*it)->x + (*it)->w);
     980         [ +  + ]:         42 :         if( (*it)->y + (*it)->h > elem.BottomMargin )
     981                 :         24 :             elem.BottomMargin = ((*it)->y + (*it)->h);
     982                 :            :     }
     983                 :            : 
     984                 :            :     // transform margins to mm
     985                 :          3 :     double left_margin     = convPx2mm( elem.LeftMargin );
     986                 :          3 :     double right_margin    = convPx2mm( elem.RightMargin );
     987                 :          3 :     double top_margin      = convPx2mm( elem.TopMargin );
     988                 :          3 :     double bottom_margin   = convPx2mm( elem.BottomMargin );
     989                 :            : 
     990                 :            :     // round left/top margin to nearest mm
     991                 :          3 :     left_margin     = rtl_math_round( left_margin, 0, rtl_math_RoundingMode_Floor );
     992                 :          3 :     top_margin      = rtl_math_round( top_margin, 0, rtl_math_RoundingMode_Floor );
     993                 :            :     // round (fuzzy) right/bottom margin to nearest cm
     994         [ +  - ]:          3 :     right_margin    = rtl_math_round( right_margin, right_margin >= 10 ? -1 : 0, rtl_math_RoundingMode_Floor );
     995         [ +  - ]:          3 :     bottom_margin   = rtl_math_round( bottom_margin, bottom_margin >= 10 ? -1 : 0, rtl_math_RoundingMode_Floor );
     996                 :            : 
     997                 :            :     // set reasonable default in case of way too large margins
     998                 :            :     // e.g. no paragraph case
     999         [ -  + ]:          3 :     if( left_margin > page_width/2.0 - 10 )
    1000                 :          0 :         left_margin = 10;
    1001         [ +  - ]:          3 :     if( right_margin > page_width/2.0 - 10 )
    1002                 :          3 :         right_margin = 10;
    1003         [ -  + ]:          3 :     if( top_margin > page_height/2.0 - 10 )
    1004                 :          0 :         top_margin = 10;
    1005         [ +  - ]:          3 :     if( bottom_margin > page_height/2.0 - 10 )
    1006                 :          3 :         bottom_margin = 10;
    1007                 :            : 
    1008                 :            :     // catch the weird cases
    1009         [ -  + ]:          3 :     if( left_margin < 0 )
    1010                 :          0 :         left_margin = 0;
    1011         [ -  + ]:          3 :     if( right_margin < 0 )
    1012                 :          0 :         right_margin = 0;
    1013         [ -  + ]:          3 :     if( top_margin < 0 )
    1014                 :          0 :         top_margin = 0;
    1015         [ -  + ]:          3 :     if( bottom_margin < 0 )
    1016                 :          0 :         bottom_margin = 0;
    1017                 :            : 
    1018                 :            :     // widely differing margins are unlikely to be correct
    1019         [ -  + ]:          3 :     if( right_margin > left_margin*1.5 )
    1020                 :          0 :         right_margin = left_margin;
    1021                 :            : 
    1022                 :          3 :     elem.LeftMargin      = convmm2Px( left_margin );
    1023                 :          3 :     elem.RightMargin     = convmm2Px( right_margin );
    1024                 :          3 :     elem.TopMargin       = convmm2Px( top_margin );
    1025                 :          3 :     elem.BottomMargin    = convmm2Px( bottom_margin );
    1026                 :            : 
    1027                 :            :     // get styles for paragraphs
    1028         [ +  - ]:          3 :     PropertyMap aPageProps;
    1029         [ +  - ]:          3 :     PropertyMap aPageLayoutProps;
    1030                 :          3 :     rtl::OUStringBuffer aBuf( 64 );
    1031 [ +  - ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "fo:margin-top" ) ]     =  unitMMString( top_margin );
                 [ +  - ]
    1032 [ +  - ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "fo:margin-bottom" ) ]  =  unitMMString( bottom_margin );
                 [ +  - ]
    1033 [ +  - ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "fo:margin-left" ) ]    =  unitMMString( left_margin );
                 [ +  - ]
    1034 [ +  - ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "fo:margin-right" ) ]   =  unitMMString( right_margin );
                 [ +  - ]
    1035 [ +  - ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "fo:page-width" ) ]     =  unitMMString( page_width );
                 [ +  - ]
    1036 [ +  - ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "fo:page-height" ) ]    =  unitMMString( page_height );
                 [ +  - ]
    1037 [ #  # ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "style:print-orientation" ) ]= elem.w < elem.h ? USTR( "portrait" ) : USTR( "landscape" );
         [ +  - ][ +  - ]
                 [ -  + ]
    1038 [ +  - ][ +  - ]:          3 :     aPageLayoutProps[ USTR( "style:writing-mode" ) ]= USTR( "lr-tb" );
                 [ +  - ]
    1039                 :            : 
    1040         [ +  - ]:          3 :     StyleContainer::Style aStyle( "style:page-layout", aPageProps);
    1041         [ +  - ]:          3 :     StyleContainer::Style aSubStyle( "style:page-layout-properties", aPageLayoutProps);
    1042         [ +  - ]:          3 :     aStyle.SubStyles.push_back(&aSubStyle);
    1043         [ +  - ]:          3 :     sal_Int32 nPageStyle = m_rStyleContainer.impl_getStyleId( aStyle, false );
    1044                 :            : 
    1045                 :            :     // create master page
    1046         [ +  - ]:          3 :     rtl::OUString aMasterPageLayoutName = m_rStyleContainer.getStyleName( nPageStyle );
    1047 [ +  - ][ +  - ]:          3 :     aPageProps[ USTR( "style:page-layout-name" ) ] = aMasterPageLayoutName;
    1048                 :            : 
    1049         [ +  - ]:          3 :     StyleContainer::Style aMPStyle( "style:master-page", aPageProps);
    1050                 :            : 
    1051 [ +  - ][ +  - ]:          3 :     StyleContainer::Style aHeaderStyle( "style:header", PropertyMap() );
                 [ +  - ]
    1052 [ +  - ][ +  - ]:          3 :     StyleContainer::Style aFooterStyle( "style:footer", PropertyMap() );
                 [ +  - ]
    1053                 :            : 
    1054         [ +  - ]:          3 :     elem.StyleId = m_rStyleContainer.impl_getStyleId( aMPStyle,false );
    1055                 :            : 
    1056                 :            : 
    1057         [ +  - ]:          3 :     rtl::OUString aMasterPageName = m_rStyleContainer.getStyleName( elem.StyleId );
    1058                 :            : 
    1059                 :            :     // create styles for children
    1060 [ +  - ][ +  - ]:          3 :     elem.applyToChildren(*this);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1061                 :          3 : }
    1062                 :            : 
    1063                 :          3 : void DrawXmlFinalizer::visit( DocumentElement& elem, const std::list< Element* >::const_iterator& )
    1064                 :            : {
    1065                 :          3 :     elem.applyToChildren(*this);
    1066                 :          3 : }
    1067                 :            : 
    1068                 :            : }
    1069                 :            : 
    1070                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10