LCOV - code coverage report
Current view: top level - cppcanvas/source/mtfrenderer - implrenderer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 1176 0.0 %
Date: 2012-08-25 Functions: 0 47 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 2628 0.0 %

           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 <canvas/debug.hxx>
      31                 :            : #include <tools/diagnose_ex.h>
      32                 :            : #include <canvas/verbosetrace.hxx>
      33                 :            : #include <osl/mutex.hxx>
      34                 :            : #include <vcl/svapp.hxx>
      35                 :            : #include <rtl/logfile.hxx>
      36                 :            : #include <comphelper/sequence.hxx>
      37                 :            : #include <comphelper/anytostring.hxx>
      38                 :            : #include <cppuhelper/exc_hlp.hxx>
      39                 :            : #include <cppcanvas/canvas.hxx>
      40                 :            : #include <com/sun/star/rendering/XGraphicDevice.hpp>
      41                 :            : #include <com/sun/star/rendering/TexturingMode.hpp>
      42                 :            : #include <com/sun/star/uno/Sequence.hxx>
      43                 :            : #include <com/sun/star/geometry/RealPoint2D.hpp>
      44                 :            : #include <com/sun/star/rendering/PanoseProportion.hpp>
      45                 :            : #include <com/sun/star/rendering/ViewState.hpp>
      46                 :            : #include <com/sun/star/rendering/RenderState.hpp>
      47                 :            : #include <com/sun/star/rendering/XCanvasFont.hpp>
      48                 :            : #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
      49                 :            : #include <com/sun/star/rendering/XCanvas.hpp>
      50                 :            : #include <com/sun/star/rendering/PathCapType.hpp>
      51                 :            : #include <com/sun/star/rendering/PathJoinType.hpp>
      52                 :            : #include <basegfx/tools/canvastools.hxx>
      53                 :            : #include <basegfx/tools/gradienttools.hxx>
      54                 :            : #include <basegfx/numeric/ftools.hxx>
      55                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      56                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      57                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      58                 :            : #include <basegfx/polygon/b2dpolypolygon.hxx>
      59                 :            : #include <basegfx/matrix/b2dhommatrix.hxx>
      60                 :            : #include <basegfx/vector/b2dsize.hxx>
      61                 :            : #include <basegfx/range/b2drectangle.hxx>
      62                 :            : #include <basegfx/point/b2dpoint.hxx>
      63                 :            : #include <basegfx/tuple/b2dtuple.hxx>
      64                 :            : #include <basegfx/polygon/b2dpolygonclipper.hxx>
      65                 :            : #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
      66                 :            : #include <canvas/canvastools.hxx>
      67                 :            : #include <vcl/canvastools.hxx>
      68                 :            : #include <vcl/salbtype.hxx>
      69                 :            : #include <vcl/gdimtf.hxx>
      70                 :            : #include <vcl/metaact.hxx>
      71                 :            : #include <vcl/virdev.hxx>
      72                 :            : #include <vcl/metric.hxx>
      73                 :            : #include <vcl/graphictools.hxx>
      74                 :            : #include <tools/poly.hxx>
      75                 :            : #include <i18npool/mslangid.hxx>
      76                 :            : #include <implrenderer.hxx>
      77                 :            : #include <tools.hxx>
      78                 :            : #include <outdevstate.hxx>
      79                 :            : #include <action.hxx>
      80                 :            : #include <bitmapaction.hxx>
      81                 :            : #include <lineaction.hxx>
      82                 :            : #include <pointaction.hxx>
      83                 :            : #include <polypolyaction.hxx>
      84                 :            : #include <rendergraphicaction.hxx>
      85                 :            : #include <textaction.hxx>
      86                 :            : #include <transparencygroupaction.hxx>
      87                 :            : #include <vector>
      88                 :            : #include <algorithm>
      89                 :            : #include <iterator>
      90                 :            : #include <boost/scoped_array.hpp>
      91                 :            : #include "mtftools.hxx"
      92                 :            : #include "outdevstate.hxx"
      93                 :            : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      94                 :            : 
      95                 :            : #if OSL_DEBUG_LEVEL > 1
      96                 :            : #define EMFP_DEBUG(x) x
      97                 :            : #else
      98                 :            : #define EMFP_DEBUG(x)
      99                 :            : #endif
     100                 :            : 
     101                 :            : using namespace ::com::sun::star;
     102                 :            : 
     103                 :            : 
     104                 :            : // free support functions
     105                 :            : // ======================
     106                 :            : namespace
     107                 :            : {
     108                 :          0 :     template < class MetaActionType > void setStateColor( MetaActionType*                   pAct,
     109                 :            :                                                           bool&                             rIsColorSet,
     110                 :            :                                                           uno::Sequence< double >&          rColorSequence,
     111                 :            :                                                           const cppcanvas::CanvasSharedPtr& rCanvas )
     112                 :            :     {
     113                 :            :         // set rIsColorSet and check for true at the same time
     114 [ #  # ][ #  # ]:          0 :         if( (rIsColorSet=pAct->IsSetting()) != false )
         [ #  # ][ #  # ]
     115                 :            :         {
     116                 :          0 :             ::Color aColor( pAct->GetColor() );
     117                 :            : 
     118                 :            :             // force alpha part of color to
     119                 :            :             // opaque. transparent painting is done
     120                 :            :             // explicitly via META_TRANSPARENT_ACTION
     121   [ #  #  #  #  :          0 :             aColor.SetTransparency(0);
             #  #  #  # ]
     122                 :            :             //aColor.SetTransparency(128);
     123                 :            : 
     124 [ #  # ][ #  # ]:          0 :             rColorSequence = ::vcl::unotools::colorToDoubleSequence(
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     125                 :            :                 aColor,
     126                 :            :                 rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
     127                 :            :         }
     128                 :          0 :     }
     129                 :            : 
     130                 :          0 :     void setupStrokeAttributes( rendering::StrokeAttributes&                          o_rStrokeAttributes,
     131                 :            :                                 const ::cppcanvas::internal::ActionFactoryParameters& rParms,
     132                 :            :                                 const LineInfo&                                       rLineInfo                 )
     133                 :            :     {
     134                 :          0 :         const ::basegfx::B2DSize aWidth( rLineInfo.GetWidth(), 0 );
     135                 :            :         o_rStrokeAttributes.StrokeWidth =
     136 [ #  # ][ #  # ]:          0 :             (rParms.mrStates.getState().mapModeTransform * aWidth).getX();
     137                 :            : 
     138                 :            :         // setup reasonable defaults
     139                 :          0 :         o_rStrokeAttributes.MiterLimit   = 15.0; // 1.0 was no good default; GDI+'s limit is 10.0, our's is 15.0
     140                 :          0 :         o_rStrokeAttributes.StartCapType = rendering::PathCapType::BUTT;
     141                 :          0 :         o_rStrokeAttributes.EndCapType   = rendering::PathCapType::BUTT;
     142                 :            : 
     143   [ #  #  #  # ]:          0 :         switch(rLineInfo.GetLineJoin())
     144                 :            :         {
     145                 :            :             default: // B2DLINEJOIN_NONE, B2DLINEJOIN_MIDDLE
     146                 :          0 :                 o_rStrokeAttributes.JoinType = rendering::PathJoinType::NONE;
     147                 :          0 :                 break;
     148                 :            :             case basegfx::B2DLINEJOIN_BEVEL:
     149                 :          0 :                 o_rStrokeAttributes.JoinType = rendering::PathJoinType::BEVEL;
     150                 :          0 :                 break;
     151                 :            :             case basegfx::B2DLINEJOIN_MITER:
     152                 :          0 :                 o_rStrokeAttributes.JoinType = rendering::PathJoinType::MITER;
     153                 :          0 :                 break;
     154                 :            :             case basegfx::B2DLINEJOIN_ROUND:
     155                 :          0 :                 o_rStrokeAttributes.JoinType = rendering::PathJoinType::ROUND;
     156                 :          0 :                 break;
     157                 :            :         }
     158                 :            : 
     159         [ #  # ]:          0 :         if( LINE_DASH == rLineInfo.GetStyle() )
     160                 :            :         {
     161         [ #  # ]:          0 :             const ::cppcanvas::internal::OutDevState& rState( rParms.mrStates.getState() );
     162                 :            : 
     163                 :            :             // TODO(F1): Interpret OutDev::GetRefPoint() for the start of the dashing.
     164                 :            : 
     165                 :            :             // interpret dash info only if explicitly enabled as
     166                 :            :             // style
     167                 :          0 :             const ::basegfx::B2DSize aDistance( rLineInfo.GetDistance(), 0 );
     168         [ #  # ]:          0 :             const double nDistance( (rState.mapModeTransform * aDistance).getX() );
     169                 :            : 
     170                 :          0 :             const ::basegfx::B2DSize aDashLen( rLineInfo.GetDashLen(), 0 );
     171         [ #  # ]:          0 :             const double nDashLen( (rState.mapModeTransform * aDashLen).getX() );
     172                 :            : 
     173                 :          0 :             const ::basegfx::B2DSize aDotLen( rLineInfo.GetDotLen(), 0 );
     174         [ #  # ]:          0 :             const double nDotLen( (rState.mapModeTransform * aDotLen).getX() );
     175                 :            : 
     176                 :          0 :             const sal_Int32 nNumArryEntries( 2*rLineInfo.GetDashCount() +
     177                 :          0 :                                              2*rLineInfo.GetDotCount() );
     178                 :            : 
     179         [ #  # ]:          0 :             o_rStrokeAttributes.DashArray.realloc( nNumArryEntries );
     180         [ #  # ]:          0 :             double* pDashArray = o_rStrokeAttributes.DashArray.getArray();
     181                 :            : 
     182                 :            : 
     183                 :            :             // iteratively fill dash array, first with dashs, then
     184                 :            :             // with dots.
     185                 :            :             // ===================================================
     186                 :            : 
     187                 :          0 :             sal_Int32 nCurrEntry=0;
     188                 :            : 
     189         [ #  # ]:          0 :             for( sal_Int32 i=0; i<rLineInfo.GetDashCount(); ++i )
     190                 :            :             {
     191                 :          0 :                 pDashArray[nCurrEntry++] = nDashLen;
     192                 :          0 :                 pDashArray[nCurrEntry++] = nDistance;
     193                 :            :             }
     194         [ #  # ]:          0 :             for( sal_Int32 i=0; i<rLineInfo.GetDotCount(); ++i )
     195                 :            :             {
     196                 :          0 :                 pDashArray[nCurrEntry++] = nDotLen;
     197                 :          0 :                 pDashArray[nCurrEntry++] = nDistance;
     198                 :          0 :             }
     199                 :          0 :         }
     200                 :          0 :     }
     201                 :            : 
     202                 :            : 
     203                 :            :     /** Create masked BitmapEx, where the white areas of rBitmap are
     204                 :            :         transparent, and the other appear in rMaskColor.
     205                 :            :      */
     206                 :          0 :     BitmapEx createMaskBmpEx( const Bitmap&  rBitmap,
     207                 :            :                               const ::Color& rMaskColor )
     208                 :            :     {
     209                 :          0 :         const ::Color aWhite( COL_WHITE );
     210         [ #  # ]:          0 :         BitmapPalette aBiLevelPalette(2);
     211                 :          0 :         aBiLevelPalette[0] = aWhite;
     212                 :          0 :         aBiLevelPalette[1] = rMaskColor;
     213                 :            : 
     214         [ #  # ]:          0 :         Bitmap aMask( rBitmap.CreateMask( aWhite ));
     215                 :            :         Bitmap aSolid( rBitmap.GetSizePixel(),
     216                 :            :                        1,
     217 [ #  # ][ #  # ]:          0 :                        &aBiLevelPalette );
     218         [ #  # ]:          0 :         aSolid.Erase( rMaskColor );
     219                 :            : 
     220 [ #  # ][ #  # ]:          0 :         return BitmapEx( aSolid, aMask );
                 [ #  # ]
     221                 :            :     }
     222                 :            : 
     223                 :            :     /** Shameless rip from vcl/source/gdi/outdev3.cxx
     224                 :            : 
     225                 :            :         Should consolidate, into something like basetxt...
     226                 :            :      */
     227                 :          0 :     sal_Unicode getLocalizedChar( sal_Unicode nChar, LanguageType eLang )
     228                 :            :     {
     229                 :            :         // currently only conversion from ASCII digits is interesting
     230 [ #  # ][ #  # ]:          0 :         if( (nChar < '0') || ('9' < nChar) )
     231                 :          0 :             return nChar;
     232                 :            : 
     233                 :          0 :         sal_Unicode nOffset(0);
     234                 :            :         // eLang & LANGUAGE_MASK_PRIMARY catches language independent of region.
     235                 :            :         // CAVEAT! To some like Mongolian MS assigned the same primary language
     236                 :            :         // although the script type is different!
     237   [ #  #  #  #  :          0 :         switch( eLang & LANGUAGE_MASK_PRIMARY )
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     238                 :            :         {
     239                 :            :             default:
     240                 :          0 :                 break;
     241                 :            : 
     242                 :            :             case LANGUAGE_ARABIC_SAUDI_ARABIA  & LANGUAGE_MASK_PRIMARY:
     243                 :            :             case LANGUAGE_URDU          & LANGUAGE_MASK_PRIMARY:
     244                 :            :             case LANGUAGE_PUNJABI       & LANGUAGE_MASK_PRIMARY: //???
     245                 :          0 :                 nOffset = 0x0660 - '0';  // arabic/persian/urdu
     246                 :          0 :                 break;
     247                 :            :             case LANGUAGE_BENGALI       & LANGUAGE_MASK_PRIMARY:
     248                 :          0 :                 nOffset = 0x09E6 - '0';  // bengali
     249                 :          0 :                 break;
     250                 :            :             case LANGUAGE_BURMESE       & LANGUAGE_MASK_PRIMARY:
     251                 :          0 :                 nOffset = 0x1040 - '0';  // burmese
     252                 :          0 :                 break;
     253                 :            :             case LANGUAGE_HINDI         & LANGUAGE_MASK_PRIMARY:
     254                 :          0 :                 nOffset = 0x0966 - '0';  // devanagari
     255                 :          0 :                 break;
     256                 :            :             case LANGUAGE_GUJARATI      & LANGUAGE_MASK_PRIMARY:
     257                 :          0 :                 nOffset = 0x0AE6 - '0';  // gujarati
     258                 :          0 :                 break;
     259                 :            :             case LANGUAGE_KANNADA       & LANGUAGE_MASK_PRIMARY:
     260                 :          0 :                 nOffset = 0x0CE6 - '0';  // kannada
     261                 :          0 :                 break;
     262                 :            :             case LANGUAGE_KHMER         & LANGUAGE_MASK_PRIMARY:
     263                 :          0 :                 nOffset = 0x17E0 - '0';  // khmer
     264                 :          0 :                 break;
     265                 :            :             case LANGUAGE_LAO           & LANGUAGE_MASK_PRIMARY:
     266                 :          0 :                 nOffset = 0x0ED0 - '0';  // lao
     267                 :          0 :                 break;
     268                 :            :             case LANGUAGE_MALAYALAM     & LANGUAGE_MASK_PRIMARY:
     269                 :          0 :                 nOffset = 0x0D66 - '0';   // malayalam
     270                 :          0 :                 break;
     271                 :            :             case LANGUAGE_MONGOLIAN     & LANGUAGE_MASK_PRIMARY:
     272         [ #  # ]:          0 :                 if (eLang == LANGUAGE_MONGOLIAN_MONGOLIAN)
     273                 :          0 :                     nOffset = 0x1810 - '0';   // mongolian
     274                 :            :                 else
     275                 :          0 :                     nOffset = 0;              // mongolian cyrillic
     276                 :          0 :                 break;
     277                 :            :             case LANGUAGE_ORIYA         & LANGUAGE_MASK_PRIMARY:
     278                 :          0 :                 nOffset = 0x0B66 - '0';   // oriya
     279                 :          0 :                 break;
     280                 :            :             case LANGUAGE_TAMIL         & LANGUAGE_MASK_PRIMARY:
     281                 :          0 :                 nOffset = 0x0BE7 - '0';   // tamil
     282                 :          0 :                 break;
     283                 :            :             case LANGUAGE_TELUGU        & LANGUAGE_MASK_PRIMARY:
     284                 :          0 :                 nOffset = 0x0C66 - '0';   // telugu
     285                 :          0 :                 break;
     286                 :            :             case LANGUAGE_THAI          & LANGUAGE_MASK_PRIMARY:
     287                 :          0 :                 nOffset = 0x0E50 - '0';   // thai
     288                 :          0 :                 break;
     289                 :            :             case LANGUAGE_TIBETAN       & LANGUAGE_MASK_PRIMARY:
     290                 :          0 :                 nOffset = 0x0F20 - '0';   // tibetan
     291                 :          0 :                 break;
     292                 :            :         }
     293                 :            : 
     294                 :          0 :         nChar = sal::static_int_cast<sal_Unicode>(nChar + nOffset);
     295                 :          0 :         return nChar;
     296                 :            :     }
     297                 :            : 
     298                 :          0 :     void convertToLocalizedNumerals( XubString&   rStr,
     299                 :            :                                      LanguageType eTextLanguage )
     300                 :            :     {
     301                 :          0 :         const sal_Unicode* pBase = rStr.GetBuffer();
     302                 :          0 :         const sal_Unicode* pBegin = pBase + 0;
     303                 :          0 :         const xub_StrLen nEndIndex = rStr.Len();
     304                 :          0 :         const sal_Unicode* pEnd = pBase + nEndIndex;
     305                 :            : 
     306         [ #  # ]:          0 :         for( ; pBegin < pEnd; ++pBegin )
     307                 :            :         {
     308                 :            :             // TODO: are there non-digit localizations?
     309 [ #  # ][ #  # ]:          0 :             if( (*pBegin >= '0') && (*pBegin <= '9') )
     310                 :            :             {
     311                 :            :                 // translate characters to local preference
     312                 :          0 :                 sal_Unicode cChar = getLocalizedChar( *pBegin, eTextLanguage );
     313         [ #  # ]:          0 :                 if( cChar != *pBegin )
     314                 :          0 :                     rStr.SetChar( sal::static_int_cast<sal_uInt16>(pBegin - pBase), cChar );
     315                 :            :             }
     316                 :            :         }
     317                 :          0 :     }
     318                 :            : }
     319                 :            : 
     320                 :            : 
     321                 :            : namespace cppcanvas
     322                 :            : {
     323                 :            :     namespace internal
     324                 :            :     {
     325                 :            :         // state stack manipulators
     326                 :            :         // ------------------------
     327                 :          0 :         void VectorOfOutDevStates::clearStateStack()
     328                 :            :         {
     329                 :          0 :             m_aStates.clear();
     330         [ #  # ]:          0 :             const OutDevState aDefaultState;
     331 [ #  # ][ #  # ]:          0 :             m_aStates.push_back(aDefaultState);
     332                 :          0 :         }
     333                 :            : 
     334                 :          0 :         OutDevState& VectorOfOutDevStates::getState()
     335                 :            :         {
     336                 :          0 :             return m_aStates.back();
     337                 :            :         }
     338                 :            : 
     339                 :          0 :         const OutDevState& VectorOfOutDevStates::getState() const
     340                 :            :         {
     341                 :          0 :             return m_aStates.back();
     342                 :            :         }
     343                 :            : 
     344                 :          0 :         void VectorOfOutDevStates::pushState(sal_uInt16 nFlags)
     345                 :            :         {
     346                 :          0 :             m_aStates.push_back( getState() );
     347                 :          0 :             getState().pushFlags = nFlags;
     348                 :          0 :         }
     349                 :            : 
     350                 :          0 :         void VectorOfOutDevStates::popState()
     351                 :            :         {
     352         [ #  # ]:          0 :             if( getState().pushFlags != PUSH_ALL )
     353                 :            :             {
     354                 :            :                 // a state is pushed which is incomplete, i.e. does not
     355                 :            :                 // restore everything to the previous stack level when
     356                 :            :                 // popped.
     357                 :            :                 // That means, we take the old state, and restore every
     358                 :            :                 // OutDevState member whose flag is set, from the new to the
     359                 :            :                 // old state. Then the new state gets overwritten by the
     360                 :            :                 // calculated state
     361                 :            : 
     362                 :            :                 // preset to-be-calculated new state with old state
     363 [ #  # ][ #  # ]:          0 :                 OutDevState aCalculatedNewState( getState() );
     364                 :            : 
     365                 :            :                 // selectively copy to-be-restored content over saved old
     366                 :            :                 // state
     367         [ #  # ]:          0 :                 m_aStates.pop_back();
     368                 :            : 
     369         [ #  # ]:          0 :                 const OutDevState& rNewState( getState() );
     370                 :            : 
     371         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_LINECOLOR) )
     372                 :            :                 {
     373         [ #  # ]:          0 :                     aCalculatedNewState.lineColor      = rNewState.lineColor;
     374                 :          0 :                     aCalculatedNewState.isLineColorSet = rNewState.isLineColorSet;
     375                 :            :                 }
     376                 :            : 
     377         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_FILLCOLOR) )
     378                 :            :                 {
     379         [ #  # ]:          0 :                     aCalculatedNewState.fillColor      = rNewState.fillColor;
     380                 :          0 :                     aCalculatedNewState.isFillColorSet = rNewState.isFillColorSet;
     381                 :            :                 }
     382                 :            : 
     383         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_FONT) )
     384                 :            :                 {
     385         [ #  # ]:          0 :                     aCalculatedNewState.xFont                   = rNewState.xFont;
     386                 :          0 :                     aCalculatedNewState.fontRotation            = rNewState.fontRotation;
     387                 :          0 :                     aCalculatedNewState.textReliefStyle         = rNewState.textReliefStyle;
     388                 :          0 :                     aCalculatedNewState.textOverlineStyle       = rNewState.textOverlineStyle;
     389                 :          0 :                     aCalculatedNewState.textUnderlineStyle      = rNewState.textUnderlineStyle;
     390                 :          0 :                     aCalculatedNewState.textStrikeoutStyle      = rNewState.textStrikeoutStyle;
     391                 :          0 :                     aCalculatedNewState.textEmphasisMarkStyle   = rNewState.textEmphasisMarkStyle;
     392                 :          0 :                     aCalculatedNewState.isTextEffectShadowSet   = rNewState.isTextEffectShadowSet;
     393                 :          0 :                     aCalculatedNewState.isTextWordUnderlineSet  = rNewState.isTextWordUnderlineSet;
     394                 :          0 :                     aCalculatedNewState.isTextOutlineModeSet    = rNewState.isTextOutlineModeSet;
     395                 :            :                 }
     396                 :            : 
     397         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_TEXTCOLOR) )
     398                 :            :                 {
     399         [ #  # ]:          0 :                     aCalculatedNewState.textColor = rNewState.textColor;
     400                 :            :                 }
     401                 :            : 
     402         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_MAPMODE) )
     403                 :            :                 {
     404         [ #  # ]:          0 :                     aCalculatedNewState.mapModeTransform = rNewState.mapModeTransform;
     405                 :            :                 }
     406                 :            : 
     407         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_CLIPREGION) )
     408                 :            :                 {
     409         [ #  # ]:          0 :                     aCalculatedNewState.clip        = rNewState.clip;
     410                 :          0 :                     aCalculatedNewState.clipRect    = rNewState.clipRect;
     411         [ #  # ]:          0 :                     aCalculatedNewState.xClipPoly   = rNewState.xClipPoly;
     412                 :            :                 }
     413                 :            : 
     414                 :            :                 // TODO(F2): Raster ops NYI
     415                 :            :                 // if( (aCalculatedNewState.pushFlags & PUSH_RASTEROP) )
     416                 :            :                 // {
     417                 :            :                 // }
     418                 :            : 
     419         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_TEXTFILLCOLOR) )
     420                 :            :                 {
     421         [ #  # ]:          0 :                     aCalculatedNewState.textFillColor      = rNewState.textFillColor;
     422                 :          0 :                     aCalculatedNewState.isTextFillColorSet = rNewState.isTextFillColorSet;
     423                 :            :                 }
     424                 :            : 
     425         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_TEXTALIGN) )
     426                 :            :                 {
     427                 :          0 :                     aCalculatedNewState.textReferencePoint = rNewState.textReferencePoint;
     428                 :            :                 }
     429                 :            : 
     430                 :            :                 // TODO(F1): Refpoint handling NYI
     431                 :            :                 // if( (aCalculatedNewState.pushFlags & PUSH_REFPOINT) )
     432                 :            :                 // {
     433                 :            :                 // }
     434                 :            : 
     435         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_TEXTLINECOLOR) )
     436                 :            :                 {
     437         [ #  # ]:          0 :                     aCalculatedNewState.textLineColor      = rNewState.textLineColor;
     438                 :          0 :                     aCalculatedNewState.isTextLineColorSet = rNewState.isTextLineColorSet;
     439                 :            :                 }
     440                 :            : 
     441         [ #  # ]:          0 :                 if( (aCalculatedNewState.pushFlags & PUSH_TEXTLAYOUTMODE) )
     442                 :            :                 {
     443                 :          0 :                     aCalculatedNewState.textAlignment = rNewState.textAlignment;
     444                 :          0 :                     aCalculatedNewState.textDirection = rNewState.textDirection;
     445                 :            :                 }
     446                 :            : 
     447                 :            :                 // TODO(F2): Text language handling NYI
     448                 :            :                 // if( (aCalculatedNewState.pushFlags & PUSH_TEXTLANGUAGE) )
     449                 :            :                 // {
     450                 :            :                 // }
     451                 :            : 
     452                 :            :                 // always copy push mode
     453                 :          0 :                 aCalculatedNewState.pushFlags = rNewState.pushFlags;
     454                 :            : 
     455                 :            :                 // flush to stack
     456 [ #  # ][ #  # ]:          0 :                 getState() = aCalculatedNewState;
                 [ #  # ]
     457                 :            :             }
     458                 :            :             else
     459                 :            :             {
     460                 :          0 :                 m_aStates.pop_back();
     461                 :            :             }
     462                 :          0 :         }
     463                 :            : 
     464                 :          0 :         bool ImplRenderer::createFillAndStroke( const ::basegfx::B2DPolyPolygon& rPolyPoly,
     465                 :            :                                                 const ActionFactoryParameters&   rParms )
     466                 :            :         {
     467         [ #  # ]:          0 :             const OutDevState& rState( rParms.mrStates.getState() );
     468 [ #  # ][ #  #  :          0 :             if( (!rState.isLineColorSet &&
             #  #  #  # ]
                 [ #  # ]
     469                 :          0 :                  !rState.isFillColorSet) ||
     470                 :          0 :                 (rState.lineColor.getLength() == 0 &&
     471                 :          0 :                  rState.fillColor.getLength() == 0) )
     472                 :            :             {
     473                 :          0 :                 return false;
     474                 :            :             }
     475                 :            : 
     476                 :            :             ActionSharedPtr pPolyAction(
     477                 :            :                 internal::PolyPolyActionFactory::createPolyPolyAction(
     478         [ #  # ]:          0 :                     rPolyPoly, rParms.mrCanvas, rState ) );
     479                 :            : 
     480         [ #  # ]:          0 :             if( pPolyAction )
     481                 :            :             {
     482                 :            :                 maActions.push_back(
     483                 :            :                     MtfAction(
     484                 :            :                         pPolyAction,
     485 [ #  # ][ #  # ]:          0 :                         rParms.mrCurrActionIndex ) );
                 [ #  # ]
     486                 :            : 
     487         [ #  # ]:          0 :                 rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
     488                 :            :             }
     489                 :            : 
     490         [ #  # ]:          0 :             return true;
     491                 :            :         }
     492                 :            : 
     493                 :          0 :         bool ImplRenderer::createFillAndStroke( const ::basegfx::B2DPolygon&   rPoly,
     494                 :            :                                                 const ActionFactoryParameters& rParms )
     495                 :            :         {
     496                 :            :             return createFillAndStroke( ::basegfx::B2DPolyPolygon( rPoly ),
     497         [ #  # ]:          0 :                                         rParms );
     498                 :            :         }
     499                 :            : 
     500                 :          0 :         void ImplRenderer::skipContent( GDIMetaFile& rMtf,
     501                 :            :                                         const char*  pCommentString,
     502                 :            :                                         sal_Int32&   io_rCurrActionIndex ) const
     503                 :            :         {
     504 [ #  # ][ #  # ]:          0 :             ENSURE_OR_THROW( pCommentString,
         [ #  # ][ #  # ]
     505                 :            :                               "ImplRenderer::skipContent(): NULL string given" );
     506                 :            : 
     507                 :            :             MetaAction* pCurrAct;
     508         [ #  # ]:          0 :             while( (pCurrAct=rMtf.NextAction()) != NULL )
     509                 :            :             {
     510                 :            :                 // increment action index, we've skipped an action.
     511                 :          0 :                 ++io_rCurrActionIndex;
     512                 :            : 
     513   [ #  #  #  # ]:          0 :                 if( pCurrAct->GetType() == META_COMMENT_ACTION &&
                 [ #  # ]
     514                 :          0 :                     static_cast<MetaCommentAction*>(pCurrAct)->GetComment().equalsIgnoreAsciiCase(
     515                 :          0 :                         pCommentString) )
     516                 :            :                 {
     517                 :            :                     // requested comment found, done
     518                 :          0 :                     return;
     519                 :            :                 }
     520                 :            :             }
     521                 :            : 
     522                 :            :             // EOF
     523                 :          0 :             return;
     524                 :            :         }
     525                 :            : 
     526                 :          0 :         bool ImplRenderer::isActionContained( GDIMetaFile& rMtf,
     527                 :            :                                               const char*  pCommentString,
     528                 :            :                                               sal_uInt16       nType ) const
     529                 :            :         {
     530 [ #  # ][ #  # ]:          0 :             ENSURE_OR_THROW( pCommentString,
         [ #  # ][ #  # ]
     531                 :            :                               "ImplRenderer::isActionContained(): NULL string given" );
     532                 :            : 
     533                 :          0 :             bool bRet( false );
     534                 :            : 
     535                 :            :             // at least _one_ call to GDIMetaFile::NextAction() is
     536                 :            :             // executed
     537                 :          0 :             sal_uIntPtr nPos( 1 );
     538                 :            : 
     539                 :            :             MetaAction* pCurrAct;
     540         [ #  # ]:          0 :             while( (pCurrAct=rMtf.NextAction()) != NULL )
     541                 :            :             {
     542         [ #  # ]:          0 :                 if( pCurrAct->GetType() == nType )
     543                 :            :                 {
     544                 :          0 :                     bRet = true; // action type found
     545                 :          0 :                     break;
     546                 :            :                 }
     547                 :            : 
     548   [ #  #  #  # ]:          0 :                 if( pCurrAct->GetType() == META_COMMENT_ACTION &&
                 [ #  # ]
     549                 :          0 :                     static_cast<MetaCommentAction*>(pCurrAct)->GetComment().equalsIgnoreAsciiCase(
     550                 :          0 :                         pCommentString) )
     551                 :            :                 {
     552                 :            :                     // delimiting end comment found, done
     553                 :          0 :                     bRet = false; // not yet found
     554                 :          0 :                     break;
     555                 :            :                 }
     556                 :            : 
     557                 :          0 :                 ++nPos;
     558                 :            :             }
     559                 :            : 
     560                 :            :             // rewind metafile to previous position (this method must
     561                 :            :             // not change the current metaaction)
     562         [ #  # ]:          0 :             while( nPos-- )
     563                 :          0 :                 rMtf.WindPrev();
     564                 :            : 
     565         [ #  # ]:          0 :             if( !pCurrAct )
     566                 :            :             {
     567                 :            :                 // EOF, and not yet found
     568                 :          0 :                 bRet = false;
     569                 :            :             }
     570                 :            : 
     571                 :          0 :             return bRet;
     572                 :            :         }
     573                 :            : 
     574                 :          0 :         void ImplRenderer::createGradientAction( const ::PolyPolygon&           rPoly,
     575                 :            :                                                  const ::Gradient&              rGradient,
     576                 :            :                                                  const ActionFactoryParameters& rParms,
     577                 :            :                                                  bool                           bIsPolygonRectangle,
     578                 :            :                                                  bool                           bSubsettableActions )
     579                 :            :         {
     580                 :            :             DBG_TESTSOLARMUTEX();
     581                 :            : 
     582         [ #  # ]:          0 :             ::basegfx::B2DPolyPolygon aDevicePoly( rPoly.getB2DPolyPolygon() );
     583 [ #  # ][ #  # ]:          0 :             aDevicePoly.transform( rParms.mrStates.getState().mapModeTransform );
     584                 :            : 
     585                 :            :             // decide, whether this gradient can be rendered natively
     586                 :            :             // by the canvas, or must be emulated via VCL gradient
     587                 :            :             // action extraction.
     588                 :          0 :             const sal_uInt16 nSteps( rGradient.GetSteps() );
     589                 :            : 
     590 [ #  # ][ #  # ]:          0 :             if( // step count is infinite, can use native canvas
     591                 :            :                 // gradients here
     592                 :            :                 nSteps == 0 ||
     593                 :            :                 // step count is sufficiently high, such that no
     594                 :            :                 // discernible difference should be visible.
     595                 :            :                 nSteps > 64 )
     596                 :            :             {
     597                 :            :                 uno::Reference< lang::XMultiServiceFactory> xFactory(
     598 [ #  # ][ #  # ]:          0 :                     rParms.mrCanvas->getUNOCanvas()->getDevice()->getParametricPolyPolygonFactory() );
         [ #  # ][ #  # ]
                 [ #  # ]
     599                 :            : 
     600         [ #  # ]:          0 :                 if( xFactory.is() )
     601                 :            :                 {
     602         [ #  # ]:          0 :                     rendering::Texture aTexture;
     603                 :            : 
     604                 :          0 :                     aTexture.RepeatModeX = rendering::TexturingMode::CLAMP;
     605                 :          0 :                     aTexture.RepeatModeY = rendering::TexturingMode::CLAMP;
     606                 :          0 :                     aTexture.Alpha = 1.0;
     607                 :            : 
     608                 :            : 
     609                 :            :                     // setup start/end color values
     610                 :            :                     // ----------------------------
     611                 :            : 
     612                 :            :                     // scale color coefficients with gradient intensities
     613                 :          0 :                     const sal_uInt16 nStartIntensity( rGradient.GetStartIntensity() );
     614                 :          0 :                     ::Color aVCLStartColor( rGradient.GetStartColor() );
     615         [ #  # ]:          0 :                     aVCLStartColor.SetRed( (sal_uInt8)(aVCLStartColor.GetRed() * nStartIntensity / 100) );
     616         [ #  # ]:          0 :                     aVCLStartColor.SetGreen( (sal_uInt8)(aVCLStartColor.GetGreen() * nStartIntensity / 100) );
     617         [ #  # ]:          0 :                     aVCLStartColor.SetBlue( (sal_uInt8)(aVCLStartColor.GetBlue() * nStartIntensity / 100) );
     618                 :            : 
     619                 :          0 :                     const sal_uInt16 nEndIntensity( rGradient.GetEndIntensity() );
     620                 :          0 :                     ::Color aVCLEndColor( rGradient.GetEndColor() );
     621         [ #  # ]:          0 :                     aVCLEndColor.SetRed( (sal_uInt8)(aVCLEndColor.GetRed() * nEndIntensity / 100) );
     622         [ #  # ]:          0 :                     aVCLEndColor.SetGreen( (sal_uInt8)(aVCLEndColor.GetGreen() * nEndIntensity / 100) );
     623         [ #  # ]:          0 :                     aVCLEndColor.SetBlue( (sal_uInt8)(aVCLEndColor.GetBlue() * nEndIntensity / 100) );
     624                 :            : 
     625                 :            :                     uno::Reference<rendering::XColorSpace> xColorSpace(
     626 [ #  # ][ #  # ]:          0 :                         rParms.mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
         [ #  # ][ #  # ]
                 [ #  # ]
     627                 :            :                     const uno::Sequence< double > aStartColor(
     628                 :            :                         ::vcl::unotools::colorToDoubleSequence( aVCLStartColor,
     629         [ #  # ]:          0 :                                                                 xColorSpace ));
     630                 :            :                     const uno::Sequence< double > aEndColor(
     631                 :            :                         ::vcl::unotools::colorToDoubleSequence( aVCLEndColor,
     632         [ #  # ]:          0 :                                                                 xColorSpace ));
     633                 :            : 
     634         [ #  # ]:          0 :                     uno::Sequence< uno::Sequence < double > > aColors(2);
     635         [ #  # ]:          0 :                     uno::Sequence< double > aStops(2);
     636                 :            : 
     637         [ #  # ]:          0 :                     if( rGradient.GetStyle() == GradientStyle_AXIAL )
     638                 :            :                     {
     639         [ #  # ]:          0 :                         aStops.realloc(3);
     640         [ #  # ]:          0 :                         aColors.realloc(3);
     641                 :            : 
     642         [ #  # ]:          0 :                         aStops[0] = 0.0;
     643         [ #  # ]:          0 :                         aStops[1] = 0.5;
     644         [ #  # ]:          0 :                         aStops[2] = 1.0;
     645                 :            : 
     646 [ #  # ][ #  # ]:          0 :                         aColors[0] = aEndColor;
     647 [ #  # ][ #  # ]:          0 :                         aColors[1] = aStartColor;
     648 [ #  # ][ #  # ]:          0 :                         aColors[2] = aEndColor;
     649                 :            :                     }
     650                 :            :                     else
     651                 :            :                     {
     652         [ #  # ]:          0 :                         aStops[0] = 0.0;
     653         [ #  # ]:          0 :                         aStops[1] = 1.0;
     654                 :            : 
     655 [ #  # ][ #  # ]:          0 :                         aColors[0] = aStartColor;
     656 [ #  # ][ #  # ]:          0 :                         aColors[1] = aEndColor;
     657                 :            :                     }
     658                 :            : 
     659                 :            :                     const ::basegfx::B2DRectangle aBounds(
     660         [ #  # ]:          0 :                         ::basegfx::tools::getRange(aDevicePoly) );
     661                 :            :                     const ::basegfx::B2DVector aOffset(
     662                 :          0 :                         rGradient.GetOfsX() / 100.0,
     663                 :          0 :                         rGradient.GetOfsY() / 100.0);
     664                 :          0 :                     double fRotation( rGradient.GetAngle() * M_PI / 1800.0 );
     665                 :          0 :                     const double fBorder( rGradient.GetBorder() / 100.0 );
     666                 :            : 
     667         [ #  # ]:          0 :                     basegfx::B2DHomMatrix aRot90;
     668         [ #  # ]:          0 :                     aRot90.rotate(M_PI_2);
     669                 :            : 
     670         [ #  # ]:          0 :                     basegfx::ODFGradientInfo aGradInfo;
     671                 :          0 :                     rtl::OUString aGradientService;
     672   [ #  #  #  #  :          0 :                     switch( rGradient.GetStyle() )
                #  #  # ]
     673                 :            :                     {
     674                 :            :                         case GradientStyle_LINEAR:
     675                 :            :                             basegfx::tools::createLinearODFGradientInfo(aGradInfo,
     676                 :            :                                                                         aBounds,
     677                 :            :                                                                         nSteps,
     678                 :            :                                                                         fBorder,
     679         [ #  # ]:          0 :                                                                         fRotation);
     680                 :            :                             // map odf to svg gradient orientation - x
     681                 :            :                             // instead of y direction
     682 [ #  # ][ #  # ]:          0 :                             aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aRot90;
                 [ #  # ]
     683                 :          0 :                             aGradientService = "LinearGradient";
     684                 :          0 :                             break;
     685                 :            : 
     686                 :            :                         case GradientStyle_AXIAL:
     687                 :            :                         {
     688                 :            :                             // Adapt the border so that it is suitable
     689                 :            :                             // for the axial gradient.  An axial
     690                 :            :                             // gradient consists of two linear
     691                 :            :                             // gradients.  Each of those covers half
     692                 :            :                             // of the total size.  In order to
     693                 :            :                             // compensate for the condensed display of
     694                 :            :                             // the linear gradients, we have to
     695                 :            :                             // enlarge the area taken up by the actual
     696                 :            :                             // gradient (1-fBorder).  After that we
     697                 :            :                             // have to turn the result back into a
     698                 :            :                             // border value, hence the second (left
     699                 :            :                             // most 1-...
     700                 :          0 :                             const double fAxialBorder (1-2*(1-fBorder));
     701                 :            :                             basegfx::tools::createAxialODFGradientInfo(aGradInfo,
     702                 :            :                                                                         aBounds,
     703                 :            :                                                                         nSteps,
     704                 :            :                                                                         fAxialBorder,
     705         [ #  # ]:          0 :                                                                         fRotation);
     706                 :            :                             // map odf to svg gradient orientation - x
     707                 :            :                             // instead of y direction
     708 [ #  # ][ #  # ]:          0 :                             aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aRot90;
                 [ #  # ]
     709                 :            : 
     710                 :            :                             // map odf axial gradient to 3-stop linear
     711                 :            :                             // gradient - shift left by 0.5
     712         [ #  # ]:          0 :                             basegfx::B2DHomMatrix aShift;
     713         [ #  # ]:          0 :                             aShift.translate(-0.5,0);
     714 [ #  # ][ #  # ]:          0 :                             aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aShift;
                 [ #  # ]
     715                 :            : 
     716                 :          0 :                             aGradientService = "LinearGradient";
     717         [ #  # ]:          0 :                             break;
     718                 :            :                         }
     719                 :            : 
     720                 :            :                         case GradientStyle_RADIAL:
     721                 :            :                             basegfx::tools::createRadialODFGradientInfo(aGradInfo,
     722                 :            :                                                                         aBounds,
     723                 :            :                                                                         aOffset,
     724                 :            :                                                                         nSteps,
     725         [ #  # ]:          0 :                                                                         fBorder);
     726                 :          0 :                             aGradientService = "EllipticalGradient";
     727                 :          0 :                             break;
     728                 :            : 
     729                 :            :                         case GradientStyle_ELLIPTICAL:
     730                 :            :                             basegfx::tools::createEllipticalODFGradientInfo(aGradInfo,
     731                 :            :                                                                             aBounds,
     732                 :            :                                                                             aOffset,
     733                 :            :                                                                             nSteps,
     734                 :            :                                                                             fBorder,
     735         [ #  # ]:          0 :                                                                             fRotation);
     736                 :          0 :                             aGradientService = "EllipticalGradient";
     737                 :          0 :                             break;
     738                 :            : 
     739                 :            :                         case GradientStyle_SQUARE:
     740                 :            :                             basegfx::tools::createSquareODFGradientInfo(aGradInfo,
     741                 :            :                                                                         aBounds,
     742                 :            :                                                                         aOffset,
     743                 :            :                                                                         nSteps,
     744                 :            :                                                                         fBorder,
     745         [ #  # ]:          0 :                                                                         fRotation);
     746                 :          0 :                             aGradientService = "RectangularGradient";
     747                 :          0 :                             break;
     748                 :            : 
     749                 :            :                         case GradientStyle_RECT:
     750                 :            :                             basegfx::tools::createRectangularODFGradientInfo(aGradInfo,
     751                 :            :                                                                              aBounds,
     752                 :            :                                                                              aOffset,
     753                 :            :                                                                              nSteps,
     754                 :            :                                                                              fBorder,
     755         [ #  # ]:          0 :                                                                              fRotation);
     756                 :          0 :                             aGradientService = "RectangularGradient";
     757                 :          0 :                             break;
     758                 :            : 
     759                 :            :                         default:
     760 [ #  # ][ #  # ]:          0 :                             ENSURE_OR_THROW( false,
                 [ #  # ]
     761                 :            :                                              "ImplRenderer::createGradientAction(): Unexpected gradient type" );
     762                 :            :                             break;
     763                 :            :                     }
     764                 :            : 
     765                 :            :                     // As the texture coordinate space is relative to
     766                 :            :                     // the polygon coordinate space (NOT to the
     767                 :            :                     // polygon itself), move gradient to the start of
     768                 :            :                     // the actual polygon. If we skip this, the
     769                 :            :                     // gradient will always display at the origin, and
     770                 :            :                     // not within the polygon bound (which might be
     771                 :            :                     // miles away from the origin).
     772                 :            :                     aGradInfo.maTextureTransform.translate( aBounds.getMinX(),
     773 [ #  # ][ #  # ]:          0 :                                                             aBounds.getMinY() );
                 [ #  # ]
     774                 :            :                     ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform,
     775         [ #  # ]:          0 :                                                                     aGradInfo.maTextureTransform );
     776                 :            : 
     777         [ #  # ]:          0 :                     uno::Sequence<uno::Any> args(3);
     778                 :          0 :                     beans::PropertyValue aProp;
     779                 :          0 :                     aProp.Name = "Colors";
     780         [ #  # ]:          0 :                     aProp.Value <<= aColors;
     781 [ #  # ][ #  # ]:          0 :                     args[0] <<= aProp;
     782                 :          0 :                     aProp.Name = "Stops";
     783         [ #  # ]:          0 :                     aProp.Value <<= aStops;
     784 [ #  # ][ #  # ]:          0 :                     args[1] <<= aProp;
     785                 :          0 :                     aProp.Name = "AspectRatio";
     786         [ #  # ]:          0 :                     aProp.Value <<= aGradInfo.mfAspectRatio;
     787 [ #  # ][ #  # ]:          0 :                     args[2] <<= aProp;
     788                 :            : 
     789                 :            :                     aTexture.Gradient.set(
     790         [ #  # ]:          0 :                         xFactory->createInstanceWithArguments(aGradientService,
     791                 :          0 :                                                               args),
     792 [ #  # ][ #  # ]:          0 :                         uno::UNO_QUERY);
     793         [ #  # ]:          0 :                     if( aTexture.Gradient.is() )
     794                 :            :                     {
     795                 :            :                         ActionSharedPtr pPolyAction(
     796                 :            :                             internal::PolyPolyActionFactory::createPolyPolyAction(
     797                 :            :                                 aDevicePoly,
     798                 :            :                                 rParms.mrCanvas,
     799         [ #  # ]:          0 :                                 rParms.mrStates.getState(),
     800         [ #  # ]:          0 :                                 aTexture ) );
     801                 :            : 
     802         [ #  # ]:          0 :                         if( pPolyAction )
     803                 :            :                         {
     804                 :            :                             maActions.push_back(
     805                 :            :                                 MtfAction(
     806                 :            :                                     pPolyAction,
     807 [ #  # ][ #  # ]:          0 :                                     rParms.mrCurrActionIndex ) );
                 [ #  # ]
     808                 :            : 
     809         [ #  # ]:          0 :                             rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
     810                 :            :                         }
     811                 :            : 
     812                 :            :                         // done, using native gradients
     813         [ #  # ]:          0 :                         return;
     814 [ #  # ][ #  # ]:          0 :                     }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     815         [ #  # ]:          0 :                 }
     816                 :            :             }
     817                 :            : 
     818                 :            :             // cannot currently use native canvas gradients, as a
     819                 :            :             // finite step size is given (this funny feature is not
     820                 :            :             // supported by the XCanvas API)
     821         [ #  # ]:          0 :             rParms.mrStates.pushState(PUSH_ALL);
     822                 :            : 
     823         [ #  # ]:          0 :             if( !bIsPolygonRectangle )
     824                 :            :             {
     825                 :            :                 // only clip, if given polygon is not a rectangle in
     826                 :            :                 // the first place (the gradient is always limited to
     827                 :            :                 // the given bound rect)
     828                 :            :                 updateClipping(
     829                 :            :                     aDevicePoly,
     830                 :            :                     rParms,
     831         [ #  # ]:          0 :                     true );
     832                 :            :             }
     833                 :            : 
     834         [ #  # ]:          0 :             GDIMetaFile aTmpMtf;
     835                 :            :             rParms.mrVDev.AddGradientActions( rPoly.GetBoundRect(),
     836                 :            :                                               rGradient,
     837 [ #  # ][ #  # ]:          0 :                                                aTmpMtf );
     838                 :            : 
     839         [ #  # ]:          0 :             createActions( aTmpMtf, rParms, bSubsettableActions );
     840                 :            : 
     841 [ #  # ][ #  # ]:          0 :             rParms.mrStates.popState();
         [ #  # ][ #  # ]
     842                 :            :         }
     843                 :            : 
     844                 :          0 :         uno::Reference< rendering::XCanvasFont > ImplRenderer::createFont( double&                        o_rFontRotation,
     845                 :            :                                                                            const ::Font&                  rFont,
     846                 :            :                                                                            const ActionFactoryParameters& rParms ) const
     847                 :            :         {
     848                 :          0 :             rendering::FontRequest aFontRequest;
     849                 :            : 
     850         [ #  # ]:          0 :             if( rParms.mrParms.maFontName.is_initialized() )
     851         [ #  # ]:          0 :                 aFontRequest.FontDescription.FamilyName = *rParms.mrParms.maFontName;
     852                 :            :             else
     853 [ #  # ][ #  # ]:          0 :                 aFontRequest.FontDescription.FamilyName = rFont.GetName();
     854                 :            : 
     855 [ #  # ][ #  # ]:          0 :             aFontRequest.FontDescription.StyleName = rFont.GetStyleName();
     856                 :            : 
     857 [ #  # ][ #  # ]:          0 :             aFontRequest.FontDescription.IsSymbolFont = (rFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL) ? util::TriState_YES : util::TriState_NO;
     858 [ #  # ][ #  # ]:          0 :             aFontRequest.FontDescription.IsVertical = rFont.IsVertical() ? util::TriState_YES : util::TriState_NO;
     859                 :            : 
     860                 :            :             // TODO(F2): improve vclenum->panose conversion
     861                 :            :             aFontRequest.FontDescription.FontDescription.Weight =
     862                 :          0 :                 rParms.mrParms.maFontWeight.is_initialized() ?
     863         [ #  # ]:          0 :                 *rParms.mrParms.maFontWeight :
     864 [ #  # ][ #  # ]:          0 :                 ::canvas::tools::numeric_cast<sal_Int8>( ::basegfx::fround( rFont.GetWeight() ) );
                 [ #  # ]
     865                 :            :             aFontRequest.FontDescription.FontDescription.Letterform =
     866                 :          0 :                 rParms.mrParms.maFontLetterForm.is_initialized() ?
     867         [ #  # ]:          0 :                 *rParms.mrParms.maFontLetterForm :
     868 [ #  # ][ #  # ]:          0 :                 (rFont.GetItalic() == ITALIC_NONE) ? 0 : 9;
                 [ #  # ]
     869                 :            :             aFontRequest.FontDescription.FontDescription.Proportion =
     870                 :          0 :                 rParms.mrParms.maFontProportion.is_initialized() ?
     871         [ #  # ]:          0 :                 *rParms.mrParms.maFontProportion :
     872         [ #  # ]:          0 :                 (rFont.GetPitch() == PITCH_FIXED)
     873                 :            :                     ? rendering::PanoseProportion::MONO_SPACED
     874 [ #  # ][ #  # ]:          0 :                     : rendering::PanoseProportion::ANYTHING;
     875                 :            : 
     876         [ #  # ]:          0 :             LanguageType aLang = rFont.GetLanguage();
     877         [ #  # ]:          0 :             aFontRequest.Locale = MsLangId::convertLanguageToLocale(aLang, false);
     878                 :            : 
     879                 :            :             // setup state-local text transformation,
     880                 :            :             // if the font be rotated
     881         [ #  # ]:          0 :             const short nFontAngle( rFont.GetOrientation() );
     882         [ #  # ]:          0 :             if( nFontAngle != 0 )
     883                 :            :             {
     884                 :            :                 // set to unity transform rotated by font angle
     885                 :          0 :                 const double nAngle( nFontAngle * (F_PI / 1800.0) );
     886                 :          0 :                 o_rFontRotation = -nAngle;
     887                 :            :             }
     888                 :            :             else
     889                 :            :             {
     890                 :          0 :                 o_rFontRotation = 0.0;
     891                 :            :             }
     892                 :            : 
     893                 :          0 :             geometry::Matrix2D aFontMatrix;
     894         [ #  # ]:          0 :             ::canvas::tools::setIdentityMatrix2D( aFontMatrix );
     895                 :            : 
     896                 :            :             // TODO(F2): use correct scale direction, font
     897                 :            :             // height might be width or anything else
     898                 :            : 
     899                 :            :             // TODO(Q3): This code smells of programming by
     900                 :            :             // coincidence (the next two if statements)
     901         [ #  # ]:          0 :             const ::Size rFontSizeLog( rFont.GetSize() );
     902                 :          0 :             const sal_Int32 nFontWidthLog = rFontSizeLog.Width();
     903         [ #  # ]:          0 :             if( nFontWidthLog != 0 )
     904                 :            :             {
     905         [ #  # ]:          0 :                 ::Font aTestFont = rFont;
     906         [ #  # ]:          0 :                 aTestFont.SetWidth( 0 );
     907 [ #  # ][ #  # ]:          0 :                 sal_Int32 nNormalWidth = rParms.mrVDev.GetFontMetric( aTestFont ).GetWidth();
                 [ #  # ]
     908         [ #  # ]:          0 :                 if( nNormalWidth != nFontWidthLog )
     909         [ #  # ]:          0 :                     if( nNormalWidth )
     910         [ #  # ]:          0 :                         aFontMatrix.m00 = (double)nFontWidthLog / nNormalWidth;
     911                 :            :             }
     912                 :            : 
     913                 :            :             // #i52608# apply map mode scale also to font matrix - an
     914                 :            :             // anisotrophic mapmode must be reflected in an
     915                 :            :             // anisotrophic font matrix scale.
     916         [ #  # ]:          0 :             const OutDevState& rState( rParms.mrStates.getState() );
     917         [ #  # ]:          0 :             if( !::basegfx::fTools::equal(
     918         [ #  # ]:          0 :                     rState.mapModeTransform.get(0,0),
     919         [ #  # ]:          0 :                     rState.mapModeTransform.get(1,1)) )
     920                 :            :             {
     921         [ #  # ]:          0 :                 const double nScaleX( rState.mapModeTransform.get(0,0) );
     922         [ #  # ]:          0 :                 const double nScaleY( rState.mapModeTransform.get(1,1) );
     923                 :            : 
     924                 :            :                 // note: no reason to check for division by zero, we
     925                 :            :                 // always have the value closer (or equal) to zero as
     926                 :            :                 // the nominator.
     927         [ #  # ]:          0 :                 if( fabs(nScaleX) < fabs(nScaleY) )
     928                 :          0 :                     aFontMatrix.m00 *= nScaleX / nScaleY;
     929                 :            :                 else
     930                 :          0 :                     aFontMatrix.m11 *= nScaleY / nScaleX;
     931                 :            :             }
     932 [ #  # ][ #  # ]:          0 :             aFontRequest.CellSize = (rState.mapModeTransform * ::vcl::unotools::b2DSizeFromSize(rFontSizeLog)).getY();
     933                 :            : 
     934 [ #  # ][ #  # ]:          0 :             return rParms.mrCanvas->getUNOCanvas()->createFont( aFontRequest,
     935                 :            :                                                                 uno::Sequence< beans::PropertyValue >(),
     936 [ #  # ][ #  # ]:          0 :                                                                 aFontMatrix );
                 [ #  # ]
     937                 :            :         }
     938                 :            : 
     939                 :            :         // create text effects such as shadow/relief/embossed
     940                 :          0 :         void ImplRenderer::createTextAction( const ::Point&                 rStartPoint,
     941                 :            :                                              const String                   rString,
     942                 :            :                                              int                            nIndex,
     943                 :            :                                              int                            nLength,
     944                 :            :                                              const sal_Int32*               pCharWidths,
     945                 :            :                                              const ActionFactoryParameters& rParms,
     946                 :            :                                              bool                           bSubsettableActions )
     947                 :            :         {
     948 [ #  # ][ #  # ]:          0 :             ENSURE_OR_THROW( nIndex >= 0 && nLength <= rString.Len() + nIndex,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     949                 :            :                               "ImplRenderer::createTextWithEffectsAction(): Invalid text index" );
     950                 :            : 
     951         [ #  # ]:          0 :             if( !nLength )
     952                 :          0 :                 return; // zero-length text, no visible output
     953                 :            : 
     954         [ #  # ]:          0 :             const OutDevState& rState( rParms.mrStates.getState() );
     955                 :            : 
     956                 :            :             // TODO(F2): implement all text effects
     957                 :            :             // if( rState.textAlignment );             // TODO(F2): NYI
     958                 :            : 
     959                 :          0 :             ::Color aShadowColor( COL_AUTO );
     960                 :          0 :             ::Color aReliefColor( COL_AUTO );
     961                 :          0 :             ::Size  aShadowOffset;
     962                 :          0 :             ::Size  aReliefOffset;
     963                 :            : 
     964                 :            :             uno::Reference<rendering::XColorSpace> xColorSpace(
     965 [ #  # ][ #  # ]:          0 :                 rParms.mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
         [ #  # ][ #  # ]
                 [ #  # ]
     966                 :            : 
     967         [ #  # ]:          0 :             if( rState.isTextEffectShadowSet )
     968                 :            :             {
     969                 :            :                 // calculate shadow offset (similar to outdev3.cxx)
     970                 :            :                 // TODO(F3): better match with outdev3.cxx
     971         [ #  # ]:          0 :                 sal_Int32 nShadowOffset = static_cast<sal_Int32>(1.5 + ((rParms.mrVDev.GetFont().GetHeight()-24.0)/24.0));
     972         [ #  # ]:          0 :                 if( nShadowOffset < 1 )
     973                 :          0 :                     nShadowOffset = 1;
     974                 :            : 
     975                 :          0 :                 aShadowOffset.setWidth( nShadowOffset );
     976                 :          0 :                 aShadowOffset.setHeight( nShadowOffset );
     977                 :            : 
     978                 :            :                 // determine shadow color (from outdev3.cxx)
     979                 :            :                 ::Color aTextColor = ::vcl::unotools::doubleSequenceToColor(
     980 [ #  # ][ #  # ]:          0 :                     rState.textColor, xColorSpace );
                 [ #  # ]
     981                 :          0 :                 bool bIsDark = (aTextColor.GetColor() == COL_BLACK)
     982 [ #  # ][ #  # ]:          0 :                     || (aTextColor.GetLuminance() < 8);
                 [ #  # ]
     983                 :            : 
     984         [ #  # ]:          0 :                 aShadowColor = bIsDark ? COL_LIGHTGRAY : COL_BLACK;
     985         [ #  # ]:          0 :                 aShadowColor.SetTransparency( aTextColor.GetTransparency() );
     986                 :            :             }
     987                 :            : 
     988         [ #  # ]:          0 :             if( rState.textReliefStyle )
     989                 :            :             {
     990                 :            :                 // calculate relief offset (similar to outdev3.cxx)
     991         [ #  # ]:          0 :                 sal_Int32 nReliefOffset = rParms.mrVDev.PixelToLogic( Size( 1, 1 ) ).Height();
     992                 :          0 :                 nReliefOffset += nReliefOffset/2;
     993         [ #  # ]:          0 :                 if( nReliefOffset < 1 )
     994                 :          0 :                     nReliefOffset = 1;
     995                 :            : 
     996         [ #  # ]:          0 :                 if( rState.textReliefStyle == RELIEF_ENGRAVED )
     997                 :          0 :                     nReliefOffset = -nReliefOffset;
     998                 :            : 
     999                 :          0 :                 aReliefOffset.setWidth( nReliefOffset );
    1000                 :          0 :                 aReliefOffset.setHeight( nReliefOffset );
    1001                 :            : 
    1002                 :            :                 // determine relief color (from outdev3.cxx)
    1003                 :            :                 ::Color aTextColor = ::vcl::unotools::doubleSequenceToColor(
    1004 [ #  # ][ #  # ]:          0 :                     rState.textColor, xColorSpace );
                 [ #  # ]
    1005                 :            : 
    1006                 :          0 :                 aReliefColor = ::Color( COL_LIGHTGRAY );
    1007                 :            : 
    1008                 :            :                 // we don't have a automatic color, so black is always
    1009                 :            :                 // drawn on white (literally copied from
    1010                 :            :                 // vcl/source/gdi/outdev3.cxx)
    1011         [ #  # ]:          0 :                 if( aTextColor.GetColor() == COL_BLACK )
    1012                 :            :                 {
    1013                 :          0 :                     aTextColor = ::Color( COL_WHITE );
    1014         [ #  # ]:          0 :                     rParms.mrStates.getState().textColor =
    1015                 :            :                         ::vcl::unotools::colorToDoubleSequence(
    1016 [ #  # ][ #  # ]:          0 :                             aTextColor, xColorSpace );
                 [ #  # ]
    1017                 :            :                 }
    1018                 :            : 
    1019         [ #  # ]:          0 :                 if( aTextColor.GetColor() == COL_WHITE )
    1020                 :          0 :                     aReliefColor = ::Color( COL_BLACK );
    1021         [ #  # ]:          0 :                 aReliefColor.SetTransparency( aTextColor.GetTransparency() );
    1022                 :            :             }
    1023                 :            : 
    1024                 :            :             // create the actual text action
    1025                 :            :             ActionSharedPtr pTextAction(
    1026                 :            :                 TextActionFactory::createTextAction(
    1027                 :            :                     rStartPoint,
    1028                 :            :                     aReliefOffset,
    1029                 :            :                     aReliefColor,
    1030                 :            :                     aShadowOffset,
    1031                 :            :                     aShadowColor,
    1032                 :            :                     rString,
    1033                 :            :                     nIndex,
    1034                 :            :                     nLength,
    1035                 :            :                     pCharWidths,
    1036                 :            :                     rParms.mrVDev,
    1037                 :            :                     rParms.mrCanvas,
    1038                 :            :                     rState,
    1039                 :            :                     rParms.mrParms,
    1040         [ #  # ]:          0 :                     bSubsettableActions ) );
    1041                 :            : 
    1042         [ #  # ]:          0 :             ActionSharedPtr pStrikeoutTextAction;
    1043                 :            : 
    1044 [ #  # ][ #  # ]:          0 :             if ( rState.textStrikeoutStyle == STRIKEOUT_X || rState.textStrikeoutStyle == STRIKEOUT_SLASH )
    1045                 :            :             {
    1046         [ #  # ]:          0 :                 long nWidth = rParms.mrVDev.GetTextWidth( rString,nIndex,nLength );
    1047                 :            : 
    1048                 :            :                 xub_Unicode pChars[4];
    1049         [ #  # ]:          0 :                 if ( rState.textStrikeoutStyle == STRIKEOUT_X )
    1050                 :          0 :                     pChars[0] = 'X';
    1051                 :            :                 else
    1052                 :          0 :                     pChars[0] = '/';
    1053                 :          0 :                 pChars[3]=pChars[2]=pChars[1]=pChars[0];
    1054                 :            : 
    1055                 :            :                 long nStrikeoutWidth = (rParms.mrVDev.GetTextWidth(
    1056 [ #  # ][ #  # ]:          0 :                     rtl::OUString(pChars, SAL_N_ELEMENTS(pChars))) + 2) / 4;
                 [ #  # ]
    1057                 :            : 
    1058         [ #  # ]:          0 :                 if( nStrikeoutWidth <= 0 )
    1059                 :          0 :                     nStrikeoutWidth = 1;
    1060                 :            : 
    1061                 :          0 :                 long nMaxWidth = nStrikeoutWidth/2;
    1062         [ #  # ]:          0 :                 if ( nMaxWidth < 2 )
    1063                 :          0 :                     nMaxWidth = 2;
    1064                 :          0 :                 nMaxWidth += nWidth + 1;
    1065                 :            : 
    1066                 :          0 :                 long nFullStrikeoutWidth = 0;
    1067         [ #  # ]:          0 :                 String aStrikeoutText;
    1068         [ #  # ]:          0 :                 while( (nFullStrikeoutWidth+=nStrikeoutWidth ) < nMaxWidth+1 )
    1069         [ #  # ]:          0 :                     aStrikeoutText += pChars[0];
    1070                 :            : 
    1071                 :          0 :                 xub_StrLen nLen = aStrikeoutText.Len();
    1072                 :            : 
    1073         [ #  # ]:          0 :                 if( nLen )
    1074                 :            :                 {
    1075                 :          0 :                     long nInterval = ( nWidth - nStrikeoutWidth * nLen ) / nLen;
    1076                 :          0 :                     nStrikeoutWidth += nInterval;
    1077         [ #  # ]:          0 :                     sal_Int32* pStrikeoutCharWidths = new sal_Int32[nLen];
    1078                 :            : 
    1079         [ #  # ]:          0 :                     for ( int i = 0;i<nLen; i++)
    1080                 :            :                     {
    1081                 :          0 :                         pStrikeoutCharWidths[i] = nStrikeoutWidth;
    1082                 :            :                     }
    1083                 :            : 
    1084         [ #  # ]:          0 :                     for ( int i = 1;i< nLen; i++ )
    1085                 :            :                     {
    1086                 :          0 :                         pStrikeoutCharWidths[ i ] += pStrikeoutCharWidths[ i-1 ];
    1087                 :            :                     }
    1088                 :            : 
    1089                 :          0 :                     sal_Int32 nStartPos = 0;
    1090                 :            : 
    1091                 :            :                     pStrikeoutTextAction =
    1092                 :            :                         TextActionFactory::createTextAction(
    1093                 :            :                             rStartPoint,
    1094                 :            :                             aReliefOffset,
    1095                 :            :                             aReliefColor,
    1096                 :            :                             aShadowOffset,
    1097                 :            :                             aShadowColor,
    1098                 :            :                             aStrikeoutText,
    1099                 :            :                             nStartPos,
    1100                 :          0 :                             aStrikeoutText.Len(),
    1101                 :            :                             pStrikeoutCharWidths,
    1102                 :            :                             rParms.mrVDev,
    1103                 :            :                             rParms.mrCanvas,
    1104                 :            :                             rState,
    1105                 :            :                             rParms.mrParms,
    1106 [ #  # ][ #  # ]:          0 :                             bSubsettableActions ) ;
                 [ #  # ]
    1107         [ #  # ]:          0 :                 }
    1108                 :            :             }
    1109                 :            : 
    1110         [ #  # ]:          0 :             if( pTextAction )
    1111                 :            :             {
    1112                 :            :                 maActions.push_back(
    1113                 :            :                     MtfAction(
    1114                 :            :                         pTextAction,
    1115 [ #  # ][ #  # ]:          0 :                         rParms.mrCurrActionIndex ) );
                 [ #  # ]
    1116                 :            : 
    1117         [ #  # ]:          0 :                 if ( pStrikeoutTextAction )
    1118                 :            :                 {
    1119                 :            :                     maActions.push_back(
    1120                 :            :                         MtfAction(
    1121                 :            :                         pStrikeoutTextAction,
    1122 [ #  # ][ #  # ]:          0 :                         rParms.mrCurrActionIndex ) );
                 [ #  # ]
    1123                 :            :                 }
    1124                 :            : 
    1125         [ #  # ]:          0 :                 rParms.mrCurrActionIndex += pTextAction->getActionCount()-1;
    1126 [ #  # ][ #  # ]:          0 :             }
    1127                 :            :         }
    1128                 :            : 
    1129                 :          0 :         void ImplRenderer::updateClipping( const ::basegfx::B2DPolyPolygon& rClipPoly,
    1130                 :            :                                            const ActionFactoryParameters&   rParms,
    1131                 :            :                                            bool                             bIntersect )
    1132                 :            :         {
    1133         [ #  # ]:          0 :             ::cppcanvas::internal::OutDevState& rState( rParms.mrStates.getState() );
    1134         [ #  # ]:          0 :             ::basegfx::B2DPolyPolygon aClipPoly( rClipPoly );
    1135                 :            : 
    1136         [ #  # ]:          0 :             const bool bEmptyClipRect( rState.clipRect.IsEmpty() );
    1137         [ #  # ]:          0 :             const bool bEmptyClipPoly( rState.clip.count() == 0 );
    1138                 :            : 
    1139 [ #  # ][ #  # ]:          0 :             ENSURE_OR_THROW( bEmptyClipPoly || bEmptyClipRect,
         [ #  # ][ #  # ]
                 [ #  # ]
    1140                 :            :                               "ImplRenderer::updateClipping(): Clip rect and polygon are both set!" );
    1141                 :            : 
    1142 [ #  # ][ #  # ]:          0 :             if( !bIntersect ||
                 [ #  # ]
    1143                 :            :                 (bEmptyClipRect && bEmptyClipPoly) )
    1144                 :            :             {
    1145         [ #  # ]:          0 :                 rState.clip = rClipPoly;
    1146                 :            :             }
    1147                 :            :             else
    1148                 :            :             {
    1149         [ #  # ]:          0 :                 if( !bEmptyClipRect )
    1150                 :            :                 {
    1151                 :            :                     // TODO(P3): Use Liang-Barsky polygon clip here,
    1152                 :            :                     // after all, one object is just a rectangle!
    1153                 :            : 
    1154                 :            :                     // convert rect to polygon beforehand, must revert
    1155                 :            :                     // to general polygon clipping here.
    1156                 :            :                     rState.clip = ::basegfx::B2DPolyPolygon(
    1157                 :            :                         ::basegfx::tools::createPolygonFromRect(
    1158                 :            :                             // #121100# VCL rectangular clips always
    1159                 :            :                             // include one more pixel to the right
    1160                 :            :                             // and the bottom
    1161                 :          0 :                             ::basegfx::B2DRectangle( rState.clipRect.Left(),
    1162                 :          0 :                                                      rState.clipRect.Top(),
    1163                 :          0 :                                                      rState.clipRect.Right()+1,
    1164 [ #  # ][ #  # ]:          0 :                                                      rState.clipRect.Bottom()+1 ) ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1165                 :            :                 }
    1166                 :            : 
    1167                 :            :                 // AW: Simplified
    1168                 :            :                 rState.clip = basegfx::tools::clipPolyPolygonOnPolyPolygon(
    1169 [ #  # ][ #  # ]:          0 :                     aClipPoly, rState.clip, true, false);
                 [ #  # ]
    1170                 :            :             }
    1171                 :            : 
    1172                 :            :             // by now, our clip resides in the OutDevState::clip
    1173                 :            :             // poly-polygon.
    1174                 :          0 :             rState.clipRect.SetEmpty();
    1175                 :            : 
    1176 [ #  # ][ #  # ]:          0 :             if( rState.clip.count() == 0 )
    1177                 :            :             {
    1178 [ #  # ][ #  # ]:          0 :                 if( rState.clipRect.IsEmpty() )
    1179                 :            :                 {
    1180                 :          0 :                     rState.xClipPoly.clear();
    1181                 :            :                 }
    1182                 :            :                 else
    1183                 :            :                 {
    1184                 :            :                     rState.xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
    1185 [ #  # ][ #  # ]:          0 :                         rParms.mrCanvas->getUNOCanvas()->getDevice(),
    1186                 :            :                         ::basegfx::B2DPolyPolygon(
    1187                 :            :                             ::basegfx::tools::createPolygonFromRect(
    1188                 :            :                                 // #121100# VCL rectangular clips
    1189                 :            :                                 // always include one more pixel to
    1190                 :            :                                 // the right and the bottom
    1191                 :          0 :                                 ::basegfx::B2DRectangle( rState.clipRect.Left(),
    1192                 :          0 :                                                          rState.clipRect.Top(),
    1193                 :          0 :                                                          rState.clipRect.Right()+1,
    1194 [ #  # ][ #  # ]:          0 :                                                          rState.clipRect.Bottom()+1 ) ) ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1195                 :            :                 }
    1196                 :            :             }
    1197                 :            :             else
    1198                 :            :             {
    1199                 :            :                 rState.xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
    1200 [ #  # ][ #  # ]:          0 :                     rParms.mrCanvas->getUNOCanvas()->getDevice(),
    1201 [ #  # ][ #  # ]:          0 :                     rState.clip );
                 [ #  # ]
    1202         [ #  # ]:          0 :             }
    1203                 :          0 :         }
    1204                 :            : 
    1205                 :          0 :         void ImplRenderer::updateClipping( const ::Rectangle&             rClipRect,
    1206                 :            :                                            const ActionFactoryParameters& rParms,
    1207                 :            :                                            bool                           bIntersect )
    1208                 :            :         {
    1209                 :          0 :             ::cppcanvas::internal::OutDevState& rState( rParms.mrStates.getState() );
    1210                 :            : 
    1211                 :          0 :             const bool bEmptyClipRect( rState.clipRect.IsEmpty() );
    1212                 :          0 :             const bool bEmptyClipPoly( rState.clip.count() == 0 );
    1213                 :            : 
    1214 [ #  # ][ #  # ]:          0 :             ENSURE_OR_THROW( bEmptyClipPoly || bEmptyClipRect,
         [ #  # ][ #  # ]
                 [ #  # ]
    1215                 :            :                               "ImplRenderer::updateClipping(): Clip rect and polygon are both set!" );
    1216                 :            : 
    1217 [ #  # ][ #  # ]:          0 :             if( !bIntersect ||
                 [ #  # ]
    1218                 :            :                 (bEmptyClipRect && bEmptyClipPoly) )
    1219                 :            :             {
    1220                 :          0 :                 rState.clipRect = rClipRect;
    1221                 :          0 :                 rState.clip.clear();
    1222                 :            :             }
    1223         [ #  # ]:          0 :             else if( bEmptyClipPoly )
    1224                 :            :             {
    1225                 :          0 :                 rState.clipRect.Intersection( rClipRect );
    1226                 :          0 :                 rState.clip.clear();
    1227                 :            :             }
    1228                 :            :             else
    1229                 :            :             {
    1230                 :            :                 // TODO(P3): Handle a fourth case here, when all clip
    1231                 :            :                 // polygons are rectangular, once B2DMultiRange's
    1232                 :            :                 // sweep line implementation is done.
    1233                 :            : 
    1234                 :            :                 // general case: convert to polygon and clip
    1235                 :            :                 // -----------------------------------------
    1236                 :            : 
    1237                 :            :                 // convert rect to polygon beforehand, must revert
    1238                 :            :                 // to general polygon clipping here.
    1239                 :            :                 ::basegfx::B2DPolyPolygon aClipPoly(
    1240                 :            :                     ::basegfx::tools::createPolygonFromRect(
    1241                 :          0 :                         ::basegfx::B2DRectangle( rClipRect.Left(),
    1242                 :          0 :                                                  rClipRect.Top(),
    1243                 :          0 :                                                  rClipRect.Right(),
    1244 [ #  # ][ #  # ]:          0 :                                                  rClipRect.Bottom() ) ) );
         [ #  # ][ #  # ]
    1245                 :            : 
    1246                 :          0 :                 rState.clipRect.SetEmpty();
    1247                 :            : 
    1248                 :            :                 // AW: Simplified
    1249                 :            :                 rState.clip = basegfx::tools::clipPolyPolygonOnPolyPolygon(
    1250 [ #  # ][ #  # ]:          0 :                     aClipPoly, rState.clip, true, false);
         [ #  # ][ #  # ]
    1251                 :            :             }
    1252                 :            : 
    1253         [ #  # ]:          0 :             if( rState.clip.count() == 0 )
    1254                 :            :             {
    1255         [ #  # ]:          0 :                 if( rState.clipRect.IsEmpty() )
    1256                 :            :                 {
    1257                 :          0 :                     rState.xClipPoly.clear();
    1258                 :            :                 }
    1259                 :            :                 else
    1260                 :            :                 {
    1261                 :            :                     rState.xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
    1262 [ #  # ][ #  # ]:          0 :                         rParms.mrCanvas->getUNOCanvas()->getDevice(),
    1263                 :            :                         ::basegfx::B2DPolyPolygon(
    1264                 :            :                             ::basegfx::tools::createPolygonFromRect(
    1265                 :            :                                 // #121100# VCL rectangular clips
    1266                 :            :                                 // always include one more pixel to
    1267                 :            :                                 // the right and the bottom
    1268                 :          0 :                                 ::basegfx::B2DRectangle( rState.clipRect.Left(),
    1269                 :          0 :                                                          rState.clipRect.Top(),
    1270                 :          0 :                                                          rState.clipRect.Right()+1,
    1271 [ #  # ][ #  # ]:          0 :                                                          rState.clipRect.Bottom()+1 ) ) ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1272                 :            :                 }
    1273                 :            :             }
    1274                 :            :             else
    1275                 :            :             {
    1276                 :            :                 rState.xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
    1277         [ #  # ]:          0 :                     rParms.mrCanvas->getUNOCanvas()->getDevice(),
    1278 [ #  # ][ #  # ]:          0 :                     rState.clip );
                 [ #  # ]
    1279                 :            :             }
    1280                 :          0 :         }
    1281                 :            : 
    1282                 :          0 :         bool ImplRenderer::createActions( GDIMetaFile&                   rMtf,
    1283                 :            :                                           const ActionFactoryParameters& rFactoryParms,
    1284                 :            :                                           bool                           bSubsettableActions )
    1285                 :            :         {
    1286                 :            :             /* TODO(P2): interpret mtf-comments
    1287                 :            :                ================================
    1288                 :            : 
    1289                 :            :                - gradient fillings (do that via comments)
    1290                 :            : 
    1291                 :            :                - think about mapping. _If_ we do everything in logical
    1292                 :            :                     coordinates (which would solve the probs for stroke
    1293                 :            :                  widths and text offsets), then we would have to
    1294                 :            :                  recalc scaling for every drawing operation. This is
    1295                 :            :                  because the outdev map mode might change at any time.
    1296                 :            :                  Also keep in mind, that, although we've double precision
    1297                 :            :                  float arithmetic now, different offsets might still
    1298                 :            :                  generate different roundings (aka
    1299                 :            :                  'OutputDevice::SetPixelOffset())
    1300                 :            : 
    1301                 :            :              */
    1302                 :            : 
    1303                 :            :             // alias common parameters
    1304                 :          0 :             VectorOfOutDevStates&  rStates(rFactoryParms.mrStates);
    1305                 :          0 :             const CanvasSharedPtr& rCanvas(rFactoryParms.mrCanvas);
    1306                 :          0 :             ::VirtualDevice&       rVDev(rFactoryParms.mrVDev);
    1307                 :          0 :             const Parameters&      rParms(rFactoryParms.mrParms);
    1308                 :          0 :             sal_Int32&             io_rCurrActionIndex(rFactoryParms.mrCurrActionIndex);
    1309                 :            : 
    1310                 :            : 
    1311                 :            :             // Loop over every metaaction
    1312                 :            :             // ==========================
    1313                 :            :             MetaAction* pCurrAct;
    1314                 :            : 
    1315                 :            :             // TODO(P1): think about caching
    1316         [ #  # ]:          0 :             for( pCurrAct=rMtf.FirstAction();
    1317                 :            :                  pCurrAct;
    1318                 :            :                  pCurrAct = rMtf.NextAction() )
    1319                 :            :             {
    1320                 :            :                 // execute every action, to keep VDev state up-to-date
    1321                 :            :                 // currently used only for
    1322                 :            :                 // - the map mode
    1323                 :            :                 // - the line/fill color when processing a META_TRANSPARENT_ACTION
    1324                 :            :                 // - SetFont to process font metric specific actions
    1325                 :          0 :                 pCurrAct->Execute( &rVDev );
    1326                 :            : 
    1327                 :            :                 EMFP_DEBUG(printf("MTF\trecord type: 0x%x (%d)\n", pCurrAct->GetType(), pCurrAct->GetType()));
    1328                 :            : 
    1329   [ #  #  #  #  :          0 :                 switch( pCurrAct->GetType() )
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1330                 :            :                 {
    1331                 :            :                     // ------------------------------------------------------------
    1332                 :            : 
    1333                 :            :                     // In the first part of this monster-switch, we
    1334                 :            :                     // handle all state-changing meta actions. These
    1335                 :            :                     // are all handled locally.
    1336                 :            : 
    1337                 :            :                     // ------------------------------------------------------------
    1338                 :            : 
    1339                 :            :                     case META_PUSH_ACTION:
    1340                 :            :                     {
    1341                 :          0 :                         MetaPushAction* pPushAction = static_cast<MetaPushAction*>(pCurrAct);
    1342                 :          0 :                         rStates.pushState(pPushAction->GetFlags());
    1343                 :            :                     }
    1344                 :          0 :                     break;
    1345                 :            : 
    1346                 :            :                     case META_POP_ACTION:
    1347                 :          0 :                         rStates.popState();
    1348                 :          0 :                         break;
    1349                 :            : 
    1350                 :            :                     case META_TEXTLANGUAGE_ACTION:
    1351                 :            :                         // FALLTHROUGH intended
    1352                 :            :                     case META_REFPOINT_ACTION:
    1353                 :            :                         // handled via pCurrAct->Execute( &rVDev )
    1354                 :          0 :                         break;
    1355                 :            : 
    1356                 :            :                     case META_MAPMODE_ACTION:
    1357                 :            :                         // modify current mapModeTransformation
    1358                 :            :                         // transformation, such that subsequent
    1359                 :            :                         // coordinates map correctly
    1360                 :          0 :                         tools::calcLogic2PixelAffineTransform( rStates.getState().mapModeTransform,
    1361                 :          0 :                                                                rVDev );
    1362                 :          0 :                         break;
    1363                 :            : 
    1364                 :            :                     // monitor clip regions, to assemble clip polygon on our own
    1365                 :            :                     case META_CLIPREGION_ACTION:
    1366                 :            :                     {
    1367                 :          0 :                         MetaClipRegionAction* pClipAction = static_cast<MetaClipRegionAction*>(pCurrAct);
    1368                 :            : 
    1369         [ #  # ]:          0 :                         if( !pClipAction->IsClipping() )
    1370                 :            :                         {
    1371                 :            :                             // clear clipping
    1372                 :          0 :                             rStates.getState().clip.clear();
    1373                 :            :                         }
    1374                 :            :                         else
    1375                 :            :                         {
    1376         [ #  # ]:          0 :                             if( !pClipAction->GetRegion().HasPolyPolygon() )
    1377                 :            :                             {
    1378                 :            :                                 VERBOSE_TRACE( "ImplRenderer::createActions(): non-polygonal clip "
    1379                 :            :                                                "region encountered, falling back to bounding box!" );
    1380                 :            : 
    1381                 :            :                                 // #121806# explicitly kept integer
    1382                 :            :                                 Rectangle aClipRect(
    1383                 :            :                                     rVDev.LogicToPixel(
    1384 [ #  # ][ #  # ]:          0 :                                         pClipAction->GetRegion().GetBoundRect() ) );
    1385                 :            : 
    1386                 :            :                                 // intersect current clip with given rect
    1387                 :            :                                 updateClipping(
    1388                 :            :                                     aClipRect,
    1389                 :            :                                     rFactoryParms,
    1390         [ #  # ]:          0 :                                     false );
    1391                 :            :                             }
    1392                 :            :                             else
    1393                 :            :                             {
    1394                 :            :                                 // set new clip polygon (don't intersect
    1395                 :            :                                 // with old one, just set it)
    1396                 :            : 
    1397                 :            :                                 // #121806# explicitly kept integer
    1398                 :            :                                 updateClipping(
    1399                 :            :                                     rVDev.LogicToPixel(
    1400                 :          0 :                                         pClipAction->GetRegion().GetPolyPolygon() ).getB2DPolyPolygon(),
    1401                 :            :                                     rFactoryParms,
    1402 [ #  # ][ #  # ]:          0 :                                     false );
         [ #  # ][ #  # ]
                 [ #  # ]
    1403                 :            :                             }
    1404                 :            :                         }
    1405                 :            : 
    1406                 :          0 :                         break;
    1407                 :            :                     }
    1408                 :            : 
    1409                 :            :                     case META_ISECTRECTCLIPREGION_ACTION:
    1410                 :            :                     {
    1411                 :          0 :                         MetaISectRectClipRegionAction* pClipAction = static_cast<MetaISectRectClipRegionAction*>(pCurrAct);
    1412                 :            : 
    1413                 :            :                         // #121806# explicitly kept integer
    1414                 :            :                         Rectangle aClipRect(
    1415         [ #  # ]:          0 :                             rVDev.LogicToPixel( pClipAction->GetRect() ) );
    1416                 :            : 
    1417                 :            :                         // intersect current clip with given rect
    1418                 :            :                         updateClipping(
    1419                 :            :                             aClipRect,
    1420                 :            :                             rFactoryParms,
    1421         [ #  # ]:          0 :                             true );
    1422                 :            : 
    1423                 :            :                         break;
    1424                 :            :                     }
    1425                 :            : 
    1426                 :            :                     case META_ISECTREGIONCLIPREGION_ACTION:
    1427                 :            :                     {
    1428                 :          0 :                         MetaISectRegionClipRegionAction* pClipAction = static_cast<MetaISectRegionClipRegionAction*>(pCurrAct);
    1429                 :            : 
    1430         [ #  # ]:          0 :                         if( !pClipAction->GetRegion().HasPolyPolygon() )
    1431                 :            :                         {
    1432                 :            :                             VERBOSE_TRACE( "ImplRenderer::createActions(): non-polygonal clip "
    1433                 :            :                                            "region encountered, falling back to bounding box!" );
    1434                 :            : 
    1435                 :            :                             // #121806# explicitly kept integer
    1436                 :            :                             Rectangle aClipRect(
    1437 [ #  # ][ #  # ]:          0 :                                 rVDev.LogicToPixel( pClipAction->GetRegion().GetBoundRect() ) );
    1438                 :            : 
    1439                 :            :                             // intersect current clip with given rect
    1440                 :            :                             updateClipping(
    1441                 :            :                                 aClipRect,
    1442                 :            :                                 rFactoryParms,
    1443         [ #  # ]:          0 :                                 true );
    1444                 :            :                         }
    1445                 :            :                         else
    1446                 :            :                         {
    1447                 :            :                             // intersect current clip with given clip polygon
    1448                 :            : 
    1449                 :            :                             // #121806# explicitly kept integer
    1450                 :            :                             updateClipping(
    1451                 :            :                                 rVDev.LogicToPixel(
    1452                 :          0 :                                     pClipAction->GetRegion().GetPolyPolygon() ).getB2DPolyPolygon(),
    1453                 :            :                                 rFactoryParms,
    1454 [ #  # ][ #  # ]:          0 :                                 true );
         [ #  # ][ #  # ]
                 [ #  # ]
    1455                 :            :                         }
    1456                 :            : 
    1457                 :          0 :                         break;
    1458                 :            :                     }
    1459                 :            : 
    1460                 :            :                     case META_MOVECLIPREGION_ACTION:
    1461                 :            :                         // TODO(F2): NYI
    1462                 :          0 :                         break;
    1463                 :            : 
    1464                 :            :                     case META_LINECOLOR_ACTION:
    1465         [ #  # ]:          0 :                         if( !rParms.maLineColor.is_initialized() )
    1466                 :            :                         {
    1467                 :            :                             setStateColor( static_cast<MetaLineColorAction*>(pCurrAct),
    1468                 :          0 :                                            rStates.getState().isLineColorSet,
    1469                 :          0 :                                            rStates.getState().lineColor,
    1470                 :          0 :                                            rCanvas );
    1471                 :            :                         }
    1472                 :          0 :                         break;
    1473                 :            : 
    1474                 :            :                     case META_FILLCOLOR_ACTION:
    1475         [ #  # ]:          0 :                         if( !rParms.maFillColor.is_initialized() )
    1476                 :            :                         {
    1477                 :            :                             setStateColor( static_cast<MetaFillColorAction*>(pCurrAct),
    1478                 :          0 :                                            rStates.getState().isFillColorSet,
    1479                 :          0 :                                            rStates.getState().fillColor,
    1480                 :          0 :                                            rCanvas );
    1481                 :            :                         }
    1482                 :          0 :                         break;
    1483                 :            : 
    1484                 :            :                     case META_TEXTCOLOR_ACTION:
    1485                 :            :                     {
    1486         [ #  # ]:          0 :                         if( !rParms.maTextColor.is_initialized() )
    1487                 :            :                         {
    1488                 :            :                             // Text color is set unconditionally, thus, no
    1489                 :            :                             // use of setStateColor here
    1490                 :          0 :                             ::Color aColor( static_cast<MetaTextColorAction*>(pCurrAct)->GetColor() );
    1491                 :            : 
    1492                 :            :                             // force alpha part of color to
    1493                 :            :                             // opaque. transparent painting is done
    1494                 :            :                             // explicitly via META_TRANSPARENT_ACTION
    1495         [ #  # ]:          0 :                             aColor.SetTransparency(0);
    1496                 :            : 
    1497         [ #  # ]:          0 :                             rStates.getState().textColor =
    1498                 :            :                                 ::vcl::unotools::colorToDoubleSequence(
    1499                 :            :                                     aColor,
    1500 [ #  # ][ #  # ]:          0 :                                     rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1501                 :            :                         }
    1502                 :            :                     }
    1503                 :          0 :                     break;
    1504                 :            : 
    1505                 :            :                     case META_TEXTFILLCOLOR_ACTION:
    1506         [ #  # ]:          0 :                         if( !rParms.maTextColor.is_initialized() )
    1507                 :            :                         {
    1508                 :            :                             setStateColor( static_cast<MetaTextFillColorAction*>(pCurrAct),
    1509                 :          0 :                                            rStates.getState().isTextFillColorSet,
    1510                 :          0 :                                            rStates.getState().textFillColor,
    1511                 :          0 :                                            rCanvas );
    1512                 :            :                         }
    1513                 :          0 :                         break;
    1514                 :            : 
    1515                 :            :                     case META_TEXTLINECOLOR_ACTION:
    1516         [ #  # ]:          0 :                         if( !rParms.maTextColor.is_initialized() )
    1517                 :            :                         {
    1518                 :            :                             setStateColor( static_cast<MetaTextLineColorAction*>(pCurrAct),
    1519                 :          0 :                                            rStates.getState().isTextLineColorSet,
    1520                 :          0 :                                            rStates.getState().textLineColor,
    1521                 :          0 :                                            rCanvas );
    1522                 :            :                         }
    1523                 :          0 :                         break;
    1524                 :            : 
    1525                 :            :                     case META_TEXTALIGN_ACTION:
    1526                 :            :                     {
    1527                 :          0 :                         ::cppcanvas::internal::OutDevState& rState = rStates.getState();
    1528                 :          0 :                         const TextAlign eTextAlign( static_cast<MetaTextAlignAction*>(pCurrAct)->GetTextAlign() );
    1529                 :            : 
    1530                 :          0 :                         rState.textReferencePoint = eTextAlign;
    1531                 :            :                     }
    1532                 :          0 :                     break;
    1533                 :            : 
    1534                 :            :                     case META_FONT_ACTION:
    1535                 :            :                     {
    1536                 :          0 :                         ::cppcanvas::internal::OutDevState& rState = rStates.getState();
    1537                 :          0 :                         const ::Font& rFont( static_cast<MetaFontAction*>(pCurrAct)->GetFont() );
    1538                 :            : 
    1539                 :            :                         rState.xFont = createFont( rState.fontRotation,
    1540                 :            :                                                    rFont,
    1541         [ #  # ]:          0 :                                                    rFactoryParms );
    1542                 :            : 
    1543                 :            :                         // TODO(Q2): define and use appropriate enumeration types
    1544                 :          0 :                         rState.textReliefStyle          = (sal_Int8)rFont.GetRelief();
    1545                 :          0 :                         rState.textOverlineStyle        = (sal_Int8)rFont.GetOverline();
    1546                 :          0 :                         rState.textUnderlineStyle       = rParms.maFontUnderline.is_initialized() ?
    1547                 :          0 :                             (*rParms.maFontUnderline ? (sal_Int8)UNDERLINE_SINGLE : (sal_Int8)UNDERLINE_NONE) :
    1548   [ #  #  #  # ]:          0 :                             (sal_Int8)rFont.GetUnderline();
    1549                 :          0 :                         rState.textStrikeoutStyle       = (sal_Int8)rFont.GetStrikeout();
    1550                 :          0 :                         rState.textEmphasisMarkStyle    = (sal_Int8)rFont.GetEmphasisMark();
    1551                 :          0 :                         rState.isTextEffectShadowSet    = (rFont.IsShadow() != sal_False);
    1552                 :          0 :                         rState.isTextWordUnderlineSet   = (rFont.IsWordLineMode() != sal_False);
    1553                 :          0 :                         rState.isTextOutlineModeSet     = (rFont.IsOutline() != sal_False);
    1554                 :            :                     }
    1555                 :          0 :                     break;
    1556                 :            : 
    1557                 :            :                     case META_RASTEROP_ACTION:
    1558                 :            :                         // TODO(F2): NYI
    1559                 :          0 :                         break;
    1560                 :            : 
    1561                 :            :                     case META_LAYOUTMODE_ACTION:
    1562                 :            :                     {
    1563                 :            :                         // TODO(F2): A lot is missing here
    1564                 :          0 :                         int nLayoutMode = static_cast<MetaLayoutModeAction*>(pCurrAct)->GetLayoutMode();
    1565                 :          0 :                         ::cppcanvas::internal::OutDevState& rState = rStates.getState();
    1566   [ #  #  #  #  :          0 :                         switch( nLayoutMode & (TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_BIDI_STRONG) )
                      # ]
    1567                 :            :                         {
    1568                 :            :                             case TEXT_LAYOUT_BIDI_LTR:
    1569                 :          0 :                                 rState.textDirection = rendering::TextDirection::WEAK_LEFT_TO_RIGHT;
    1570                 :          0 :                                 break;
    1571                 :            : 
    1572                 :            :                             case (TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_BIDI_STRONG):
    1573                 :          0 :                                 rState.textDirection = rendering::TextDirection::STRONG_LEFT_TO_RIGHT;
    1574                 :          0 :                                 break;
    1575                 :            : 
    1576                 :            :                             case TEXT_LAYOUT_BIDI_RTL:
    1577                 :          0 :                                 rState.textDirection = rendering::TextDirection::WEAK_RIGHT_TO_LEFT;
    1578                 :          0 :                                 break;
    1579                 :            : 
    1580                 :            :                             case (TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_BIDI_STRONG):
    1581                 :          0 :                                 rState.textDirection = rendering::TextDirection::STRONG_RIGHT_TO_LEFT;
    1582                 :          0 :                                 break;
    1583                 :            :                         }
    1584                 :            : 
    1585                 :          0 :                         rState.textAlignment = 0; // TODO(F2): rendering::TextAlignment::LEFT_ALIGNED;
    1586 [ #  # ][ #  # ]:          0 :                         if( (nLayoutMode & (TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_RIGHT) )
    1587                 :          0 :                             && !(nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT ) )
    1588                 :            :                         {
    1589                 :          0 :                             rState.textAlignment = 1; // TODO(F2): rendering::TextAlignment::RIGHT_ALIGNED;
    1590                 :            :                         }
    1591                 :            :                     }
    1592                 :          0 :                     break;
    1593                 :            : 
    1594                 :            :                     // ------------------------------------------------------------
    1595                 :            : 
    1596                 :            :                     // In the second part of this monster-switch, we
    1597                 :            :                     // handle all recursing meta actions. These are the
    1598                 :            :                     // ones generating a metafile by themselves, which is
    1599                 :            :                     // then processed by recursively calling this method.
    1600                 :            : 
    1601                 :            :                     // ------------------------------------------------------------
    1602                 :            : 
    1603                 :            :                     case META_GRADIENT_ACTION:
    1604                 :            :                     {
    1605                 :          0 :                         MetaGradientAction* pGradAct = static_cast<MetaGradientAction*>(pCurrAct);
    1606                 :          0 :                         createGradientAction( ::Polygon( pGradAct->GetRect() ),
    1607                 :          0 :                                               pGradAct->GetGradient(),
    1608                 :            :                                               rFactoryParms,
    1609                 :            :                                               true,
    1610 [ #  # ][ #  # ]:          0 :                                               bSubsettableActions );
                 [ #  # ]
    1611                 :            :                     }
    1612                 :          0 :                     break;
    1613                 :            : 
    1614                 :            :                     case META_HATCH_ACTION:
    1615                 :            :                     {
    1616                 :            :                         // TODO(F2): use native Canvas hatches here
    1617         [ #  # ]:          0 :                         GDIMetaFile aTmpMtf;
    1618                 :            : 
    1619                 :          0 :                         rVDev.AddHatchActions( static_cast<MetaHatchAction*>(pCurrAct)->GetPolyPolygon(),
    1620                 :          0 :                                                static_cast<MetaHatchAction*>(pCurrAct)->GetHatch(),
    1621         [ #  # ]:          0 :                                                aTmpMtf );
    1622                 :            :                         createActions( aTmpMtf, rFactoryParms,
    1623 [ #  # ][ #  # ]:          0 :                                        bSubsettableActions );
    1624                 :            :                     }
    1625                 :          0 :                     break;
    1626                 :            : 
    1627                 :            :                     case META_EPS_ACTION:
    1628                 :            :                     {
    1629                 :          0 :                         MetaEPSAction*      pAct = static_cast<MetaEPSAction*>(pCurrAct);
    1630                 :          0 :                         const GDIMetaFile&  rSubstitute = pAct->GetSubstitute();
    1631                 :            : 
    1632                 :            :                         // #121806# explicitly kept integer
    1633                 :          0 :                         const Size aMtfSize( rSubstitute.GetPrefSize() );
    1634                 :            :                         const Size aMtfSizePixPre( rVDev.LogicToPixel( aMtfSize,
    1635         [ #  # ]:          0 :                                                                        rSubstitute.GetPrefMapMode() ) );
    1636                 :            : 
    1637                 :            :                         // #i44110# correct null-sized output - there
    1638                 :            :                         // are metafiles which have zero size in at
    1639                 :            :                         // least one dimension
    1640         [ #  # ]:          0 :                         const Size aMtfSizePix( ::std::max( aMtfSizePixPre.Width(), 1L ),
    1641         [ #  # ]:          0 :                                                 ::std::max( aMtfSizePixPre.Height(), 1L ) );
    1642                 :            : 
    1643                 :            :                         // Setup local transform, such that the
    1644                 :            :                         // metafile renders itself into the given
    1645                 :            :                         // output rectangle
    1646         [ #  # ]:          0 :                         rStates.pushState(PUSH_ALL);
    1647                 :            : 
    1648         [ #  # ]:          0 :                         rVDev.Push();
    1649         [ #  # ]:          0 :                         rVDev.SetMapMode( rSubstitute.GetPrefMapMode() );
    1650                 :            : 
    1651         [ #  # ]:          0 :                         const ::Point& rPos( rVDev.LogicToPixel( pAct->GetPoint() ) );
    1652         [ #  # ]:          0 :                         const ::Size&  rSize( rVDev.LogicToPixel( pAct->GetSize() ) );
    1653                 :            : 
    1654         [ #  # ]:          0 :                         rStates.getState().transform.translate( rPos.X(),
    1655         [ #  # ]:          0 :                                                                  rPos.Y() );
    1656         [ #  # ]:          0 :                         rStates.getState().transform.scale( (double)rSize.Width() / aMtfSizePix.Width(),
    1657         [ #  # ]:          0 :                                                              (double)rSize.Height() / aMtfSizePix.Height() );
    1658                 :            : 
    1659                 :          0 :                         createActions( const_cast<GDIMetaFile&>(pAct->GetSubstitute()),
    1660                 :            :                                        rFactoryParms,
    1661         [ #  # ]:          0 :                                        bSubsettableActions );
    1662                 :            : 
    1663         [ #  # ]:          0 :                         rVDev.Pop();
    1664         [ #  # ]:          0 :                         rStates.popState();
    1665                 :            :                     }
    1666                 :          0 :                     break;
    1667                 :            : 
    1668                 :            :                     // handle metafile comments, to retrieve
    1669                 :            :                     // meta-information for gradients, fills and
    1670                 :            :                     // strokes. May skip actions, and may recurse.
    1671                 :            :                     case META_COMMENT_ACTION:
    1672                 :            :                     {
    1673                 :          0 :                         MetaCommentAction* pAct = static_cast<MetaCommentAction*>(pCurrAct);
    1674                 :            : 
    1675                 :            :                         // Handle gradients
    1676         [ #  # ]:          0 :                         if (pAct->GetComment().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("XGRAD_SEQ_BEGIN")))
    1677                 :            :                         {
    1678                 :          0 :                             MetaGradientExAction* pGradAction = NULL;
    1679                 :          0 :                             bool bDone( false );
    1680 [ #  # ][ #  # ]:          0 :                             while( !bDone &&
                 [ #  # ]
    1681                 :            :                                    (pCurrAct=rMtf.NextAction()) != NULL )
    1682                 :            :                             {
    1683      [ #  #  # ]:          0 :                                 switch( pCurrAct->GetType() )
    1684                 :            :                                 {
    1685                 :            :                                     // extract gradient info
    1686                 :            :                                     case META_GRADIENTEX_ACTION:
    1687                 :          0 :                                         pGradAction = static_cast<MetaGradientExAction*>(pCurrAct);
    1688                 :          0 :                                         break;
    1689                 :            : 
    1690                 :            :                                     // skip broken-down rendering, output gradient when sequence is ended
    1691                 :            :                                     case META_COMMENT_ACTION:
    1692         [ #  # ]:          0 :                                         if( static_cast<MetaCommentAction*>(pCurrAct)->GetComment().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("XGRAD_SEQ_END")) )
    1693                 :            :                                         {
    1694                 :          0 :                                             bDone = true;
    1695                 :            : 
    1696         [ #  # ]:          0 :                                             if( pGradAction )
    1697                 :            :                                             {
    1698                 :          0 :                                                 createGradientAction( pGradAction->GetPolyPolygon(),
    1699                 :          0 :                                                                       pGradAction->GetGradient(),
    1700                 :            :                                                                       rFactoryParms,
    1701                 :            :                                                                       false,
    1702                 :          0 :                                                                       bSubsettableActions );
    1703                 :            :                                             }
    1704                 :            :                                         }
    1705                 :          0 :                                         break;
    1706                 :            :                                 }
    1707                 :            :                             }
    1708                 :            :                         }
    1709                 :            :                         // TODO(P2): Handle drawing layer strokes, via
    1710                 :            :                         // XPATHSTROKE_SEQ_BEGIN comment
    1711                 :            : 
    1712                 :            :                         // Handle drawing layer fills
    1713         [ #  # ]:          0 :                         else if( pAct->GetComment().equalsL(RTL_CONSTASCII_STRINGPARAM("XPATHFILL_SEQ_BEGIN")) )
    1714                 :            :                         {
    1715                 :          0 :                             const sal_uInt8* pData = pAct->GetData();
    1716         [ #  # ]:          0 :                             if ( pData )
    1717                 :            :                             {
    1718         [ #  # ]:          0 :                                 SvMemoryStream  aMemStm( (void*)pData, pAct->GetDataSize(), STREAM_READ );
    1719                 :            : 
    1720         [ #  # ]:          0 :                                 SvtGraphicFill aFill;
    1721         [ #  # ]:          0 :                                 aMemStm >> aFill;
    1722                 :            : 
    1723                 :            :                                 // TODO(P2): Also handle gradients and
    1724                 :            :                                 // hatches like this
    1725                 :            : 
    1726                 :            :                                 // only evaluate comment for pure
    1727                 :            :                                 // bitmap fills. If a transparency
    1728                 :            :                                 // gradient is involved (denoted by
    1729                 :            :                                 // the FloatTransparent action), take
    1730                 :            :                                 // the normal meta actions.
    1731 [ #  # ][ #  # ]:          0 :                                 if( aFill.getFillType() == SvtGraphicFill::fillTexture &&
         [ #  # ][ #  # ]
    1732                 :            :                                     !isActionContained( rMtf,
    1733                 :            :                                                        "XPATHFILL_SEQ_END",
    1734         [ #  # ]:          0 :                                                         META_FLOATTRANSPARENT_ACTION ) )
    1735                 :            :                                 {
    1736         [ #  # ]:          0 :                                     rendering::Texture aTexture;
    1737                 :            : 
    1738                 :            :                                     // TODO(F1): the SvtGraphicFill
    1739                 :            :                                     // can also transport metafiles
    1740                 :            :                                     // here, handle that case, too
    1741         [ #  # ]:          0 :                                     Graphic aGraphic;
    1742         [ #  # ]:          0 :                                     aFill.getGraphic( aGraphic );
    1743                 :            : 
    1744         [ #  # ]:          0 :                                     BitmapEx     aBmpEx( aGraphic.GetBitmapEx() );
    1745                 :          0 :                                     const ::Size aBmpSize( aBmpEx.GetSizePixel() );
    1746                 :            : 
    1747         [ #  # ]:          0 :                                     ::SvtGraphicFill::Transform aTransform;
    1748         [ #  # ]:          0 :                                     aFill.getTransform( aTransform );
    1749                 :            : 
    1750         [ #  # ]:          0 :                                     ::basegfx::B2DHomMatrix aMatrix;
    1751                 :            : 
    1752                 :            :                                     // convert to basegfx matrix
    1753         [ #  # ]:          0 :                                     aMatrix.set(0,0, aTransform.matrix[ 0 ] );
    1754         [ #  # ]:          0 :                                     aMatrix.set(0,1, aTransform.matrix[ 1 ] );
    1755         [ #  # ]:          0 :                                     aMatrix.set(0,2, aTransform.matrix[ 2 ] );
    1756         [ #  # ]:          0 :                                     aMatrix.set(1,0, aTransform.matrix[ 3 ] );
    1757         [ #  # ]:          0 :                                     aMatrix.set(1,1, aTransform.matrix[ 4 ] );
    1758         [ #  # ]:          0 :                                     aMatrix.set(1,2, aTransform.matrix[ 5 ] );
    1759                 :            : 
    1760         [ #  # ]:          0 :                                     ::basegfx::B2DHomMatrix aScale;
    1761                 :          0 :                                     aScale.scale( aBmpSize.Width(),
    1762         [ #  # ]:          0 :                                                   aBmpSize.Height() );
    1763                 :            : 
    1764                 :            :                                     // post-multiply with the bitmap
    1765                 :            :                                     // size (XCanvas' texture assumes
    1766                 :            :                                     // the given bitmap to be
    1767                 :            :                                     // normalized to [0,1]x[0,1]
    1768                 :            :                                     // rectangle)
    1769 [ #  # ][ #  # ]:          0 :                                     aMatrix = aMatrix * aScale;
                 [ #  # ]
    1770                 :            : 
    1771                 :            :                                     // pre-multiply with the
    1772                 :            :                                     // logic-to-pixel scale factor
    1773                 :            :                                     // (the metafile comment works in
    1774                 :            :                                     // logical coordinates).
    1775         [ #  # ]:          0 :                                     ::basegfx::B2DHomMatrix aLogic2PixelTransform;
    1776                 :            :                                     aMatrix *= tools::calcLogic2PixelLinearTransform( aLogic2PixelTransform,
    1777 [ #  # ][ #  # ]:          0 :                                                                                       rVDev );
    1778                 :            : 
    1779                 :            :                                     ::basegfx::unotools::affineMatrixFromHomMatrix(
    1780                 :            :                                         aTexture.AffineTransform,
    1781         [ #  # ]:          0 :                                         aMatrix );
    1782                 :            : 
    1783         [ #  # ]:          0 :                                     aTexture.Alpha = 1.0 - aFill.getTransparency();
    1784                 :            :                                     aTexture.Bitmap =
    1785                 :            :                                         ::vcl::unotools::xBitmapFromBitmapEx(
    1786 [ #  # ][ #  # ]:          0 :                                             rCanvas->getUNOCanvas()->getDevice(),
    1787 [ #  # ][ #  # ]:          0 :                                             aBmpEx );
                 [ #  # ]
    1788 [ #  # ][ #  # ]:          0 :                                     if( aFill.isTiling() )
    1789                 :            :                                     {
    1790                 :          0 :                                         aTexture.RepeatModeX = rendering::TexturingMode::REPEAT;
    1791                 :          0 :                                         aTexture.RepeatModeY = rendering::TexturingMode::REPEAT;
    1792                 :            :                                     }
    1793                 :            :                                     else
    1794                 :            :                                     {
    1795                 :          0 :                                         aTexture.RepeatModeX = rendering::TexturingMode::NONE;
    1796                 :          0 :                                         aTexture.RepeatModeY = rendering::TexturingMode::NONE;
    1797                 :            :                                     }
    1798                 :            : 
    1799         [ #  # ]:          0 :                                     ::PolyPolygon aPath;
    1800         [ #  # ]:          0 :                                     aFill.getPath( aPath );
    1801                 :            : 
    1802         [ #  # ]:          0 :                                     ::basegfx::B2DPolyPolygon aPoly( aPath.getB2DPolyPolygon() );
    1803 [ #  # ][ #  # ]:          0 :                                     aPoly.transform( rStates.getState().mapModeTransform );
    1804                 :            :                                     ActionSharedPtr pPolyAction(
    1805                 :            :                                         internal::PolyPolyActionFactory::createPolyPolyAction(
    1806                 :            :                                             aPoly,
    1807                 :            :                                             rCanvas,
    1808         [ #  # ]:          0 :                                             rStates.getState(),
    1809         [ #  # ]:          0 :                                             aTexture ) );
    1810                 :            : 
    1811         [ #  # ]:          0 :                                     if( pPolyAction )
    1812                 :            :                                     {
    1813                 :            :                                         maActions.push_back(
    1814                 :            :                                             MtfAction(
    1815                 :            :                                                 pPolyAction,
    1816 [ #  # ][ #  # ]:          0 :                                                 io_rCurrActionIndex ) );
                 [ #  # ]
    1817                 :            : 
    1818         [ #  # ]:          0 :                                         io_rCurrActionIndex += pPolyAction->getActionCount()-1;
    1819                 :            :                                     }
    1820                 :            : 
    1821                 :            :                                     // skip broken-down render output
    1822                 :            :                                     skipContent( rMtf,
    1823                 :            :                                                  "XPATHFILL_SEQ_END",
    1824 [ #  # ][ #  # ]:          0 :                                                  io_rCurrActionIndex );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1825 [ #  # ][ #  # ]:          0 :                                 }
    1826                 :            :                             }
    1827                 :            :                         }
    1828                 :            :                         // Handle drawing layer fills
    1829         [ #  # ]:          0 :                         else if( pAct->GetComment().equalsL(RTL_CONSTASCII_STRINGPARAM("EMF_PLUS")) ) {
    1830                 :            :                             static int count = -1, limit = 0x7fffffff;
    1831         [ #  # ]:          0 :                             if (count == -1) {
    1832                 :          0 :                                 count = 0;
    1833         [ #  # ]:          0 :                                 if (char *env = getenv ("EMF_PLUS_LIMIT")) {
    1834                 :          0 :                                     limit = atoi (env);
    1835                 :            :                                     EMFP_DEBUG (printf ("EMF+ records limit: %d\n", limit));
    1836                 :            :                                 }
    1837                 :            :                             }
    1838                 :            :                             EMFP_DEBUG (printf ("EMF+ passed to canvas mtf renderer, size: %u\n", (unsigned int)pAct->GetDataSize ()));
    1839         [ #  # ]:          0 :                             if (count < limit)
    1840                 :          0 :                             processEMFPlus( pAct, rFactoryParms, rStates.getState(), rCanvas );
    1841                 :          0 :                             count ++;
    1842         [ #  # ]:          0 :                         } else if( pAct->GetComment().equalsL(RTL_CONSTASCII_STRINGPARAM("EMF_PLUS_HEADER_INFO")) ) {
    1843                 :            :                             EMFP_DEBUG (printf ("EMF+ passed to canvas mtf renderer - header info, size: %u\n", (unsigned int)pAct->GetDataSize ()));
    1844                 :            : 
    1845         [ #  # ]:          0 :                             SvMemoryStream rMF ((void*) pAct->GetData (), pAct->GetDataSize (), STREAM_READ);
    1846                 :            : 
    1847 [ #  # ][ #  # ]:          0 :                             rMF >> nFrameLeft >> nFrameTop >> nFrameRight >> nFrameBottom;
         [ #  # ][ #  # ]
    1848                 :            :                             EMFP_DEBUG (printf ("EMF+ picture frame: %d,%d - %d,%d\n", (int)nFrameLeft, (int)nFrameTop, (int)nFrameRight, (int)nFrameBottom));
    1849 [ #  # ][ #  # ]:          0 :                             rMF >> nPixX >> nPixY >> nMmX >> nMmY;
         [ #  # ][ #  # ]
    1850                 :            :                             EMFP_DEBUG (printf ("EMF+ ref device pixel size: %dx%d mm size: %dx%d\n", (int)nPixX, (int)nPixY, (int)nMmX, (int)nMmY));
    1851                 :            : 
    1852 [ #  # ][ #  # ]:          0 :                             rMF >> aBaseTransform;
    1853                 :            :                             //aWorldTransform.Set (aBaseTransform);
    1854                 :            :                         }
    1855                 :            :                     }
    1856                 :          0 :                     break;
    1857                 :            : 
    1858                 :            :                     // ------------------------------------------------------------
    1859                 :            : 
    1860                 :            :                     // In the third part of this monster-switch, we
    1861                 :            :                     // handle all 'acting' meta actions. These are all
    1862                 :            :                     // processed by constructing function objects for
    1863                 :            :                     // them, which will later ease caching.
    1864                 :            : 
    1865                 :            :                     // ------------------------------------------------------------
    1866                 :            : 
    1867                 :            :                     case META_POINT_ACTION:
    1868                 :            :                     {
    1869                 :          0 :                         const OutDevState& rState( rStates.getState() );
    1870         [ #  # ]:          0 :                         if( rState.lineColor.getLength() )
    1871                 :            :                         {
    1872                 :            :                             ActionSharedPtr pPointAction(
    1873                 :            :                                 internal::PointActionFactory::createPointAction(
    1874                 :            :                                     rState.mapModeTransform * ::vcl::unotools::b2DPointFromPoint(
    1875                 :          0 :                                         static_cast<MetaPointAction*>(pCurrAct)->GetPoint() ),
    1876                 :            :                                     rCanvas,
    1877 [ #  # ][ #  # ]:          0 :                                     rState ) );
                 [ #  # ]
    1878                 :            : 
    1879         [ #  # ]:          0 :                             if( pPointAction )
    1880                 :            :                             {
    1881                 :            :                                 maActions.push_back(
    1882                 :            :                                     MtfAction(
    1883                 :            :                                         pPointAction,
    1884 [ #  # ][ #  # ]:          0 :                                         io_rCurrActionIndex ) );
                 [ #  # ]
    1885                 :            : 
    1886         [ #  # ]:          0 :                                 io_rCurrActionIndex += pPointAction->getActionCount()-1;
    1887         [ #  # ]:          0 :                             }
    1888                 :            :                         }
    1889                 :            :                     }
    1890                 :          0 :                     break;
    1891                 :            : 
    1892                 :            :                     case META_PIXEL_ACTION:
    1893                 :            :                     {
    1894                 :          0 :                         const OutDevState& rState( rStates.getState() );
    1895         [ #  # ]:          0 :                         if( rState.lineColor.getLength() )
    1896                 :            :                         {
    1897                 :            :                             ActionSharedPtr pPointAction(
    1898                 :            :                                 internal::PointActionFactory::createPointAction(
    1899                 :            :                                     rState.mapModeTransform * ::vcl::unotools::b2DPointFromPoint(
    1900                 :          0 :                                         static_cast<MetaPixelAction*>(pCurrAct)->GetPoint() ),
    1901                 :            :                                     rCanvas,
    1902                 :            :                                     rState,
    1903 [ #  # ][ #  # ]:          0 :                                     static_cast<MetaPixelAction*>(pCurrAct)->GetColor() ) );
                 [ #  # ]
    1904                 :            : 
    1905         [ #  # ]:          0 :                             if( pPointAction )
    1906                 :            :                             {
    1907                 :            :                                 maActions.push_back(
    1908                 :            :                                     MtfAction(
    1909                 :            :                                         pPointAction,
    1910 [ #  # ][ #  # ]:          0 :                                         io_rCurrActionIndex ) );
                 [ #  # ]
    1911                 :            : 
    1912         [ #  # ]:          0 :                                 io_rCurrActionIndex += pPointAction->getActionCount()-1;
    1913         [ #  # ]:          0 :                             }
    1914                 :            :                         }
    1915                 :            :                     }
    1916                 :          0 :                     break;
    1917                 :            : 
    1918                 :            :                     case META_LINE_ACTION:
    1919                 :            :                     {
    1920                 :          0 :                         const OutDevState& rState( rStates.getState() );
    1921         [ #  # ]:          0 :                         if( rState.lineColor.getLength() )
    1922                 :            :                         {
    1923                 :          0 :                             MetaLineAction* pLineAct = static_cast<MetaLineAction*>(pCurrAct);
    1924                 :            : 
    1925                 :          0 :                             const LineInfo& rLineInfo( pLineAct->GetLineInfo() );
    1926                 :            : 
    1927                 :            :                             const ::basegfx::B2DPoint aStartPoint(
    1928 [ #  # ][ #  # ]:          0 :                                 rState.mapModeTransform * ::vcl::unotools::b2DPointFromPoint( pLineAct->GetStartPoint() ));
    1929                 :            :                             const ::basegfx::B2DPoint aEndPoint(
    1930 [ #  # ][ #  # ]:          0 :                                 rState.mapModeTransform * ::vcl::unotools::b2DPointFromPoint( pLineAct->GetEndPoint() ));
    1931                 :            : 
    1932         [ #  # ]:          0 :                             ActionSharedPtr pLineAction;
    1933                 :            : 
    1934         [ #  # ]:          0 :                             if( rLineInfo.IsDefault() )
    1935                 :            :                             {
    1936                 :            :                                 // plain hair line
    1937                 :            :                                 pLineAction =
    1938                 :            :                                     internal::LineActionFactory::createLineAction(
    1939                 :            :                                         aStartPoint,
    1940                 :            :                                         aEndPoint,
    1941                 :            :                                         rCanvas,
    1942 [ #  # ][ #  # ]:          0 :                                         rState );
                 [ #  # ]
    1943                 :            : 
    1944         [ #  # ]:          0 :                                 if( pLineAction )
    1945                 :            :                                 {
    1946                 :            :                                     maActions.push_back(
    1947                 :            :                                         MtfAction(
    1948                 :            :                                             pLineAction,
    1949 [ #  # ][ #  # ]:          0 :                                             io_rCurrActionIndex ) );
                 [ #  # ]
    1950                 :            : 
    1951         [ #  # ]:          0 :                                     io_rCurrActionIndex += pLineAction->getActionCount()-1;
    1952                 :            :                                 }
    1953                 :            :                             }
    1954         [ #  # ]:          0 :                             else if( LINE_NONE != rLineInfo.GetStyle() )
    1955                 :            :                             {
    1956                 :            :                                 // 'thick' line
    1957         [ #  # ]:          0 :                                 rendering::StrokeAttributes aStrokeAttributes;
    1958                 :            : 
    1959                 :            :                                 setupStrokeAttributes( aStrokeAttributes,
    1960                 :            :                                                        rFactoryParms,
    1961         [ #  # ]:          0 :                                                        rLineInfo );
    1962                 :            : 
    1963                 :            :                                 // XCanvas can only stroke polygons,
    1964                 :            :                                 // not simple lines - thus, handle
    1965                 :            :                                 // this case via the polypolygon
    1966                 :            :                                 // action
    1967         [ #  # ]:          0 :                                 ::basegfx::B2DPolygon aPoly;
    1968         [ #  # ]:          0 :                                 aPoly.append( aStartPoint );
    1969         [ #  # ]:          0 :                                 aPoly.append( aEndPoint );
    1970                 :            :                                 pLineAction =
    1971                 :            :                                     internal::PolyPolyActionFactory::createPolyPolyAction(
    1972                 :            :                                         ::basegfx::B2DPolyPolygon( aPoly ),
    1973 [ #  # ][ #  # ]:          0 :                                         rCanvas, rState, aStrokeAttributes );
         [ #  # ][ #  # ]
                 [ #  # ]
    1974                 :            : 
    1975         [ #  # ]:          0 :                                 if( pLineAction )
    1976                 :            :                                 {
    1977                 :            :                                     maActions.push_back(
    1978                 :            :                                         MtfAction(
    1979                 :            :                                             pLineAction,
    1980 [ #  # ][ #  # ]:          0 :                                             io_rCurrActionIndex ) );
                 [ #  # ]
    1981                 :            : 
    1982         [ #  # ]:          0 :                                     io_rCurrActionIndex += pLineAction->getActionCount()-1;
    1983 [ #  # ][ #  # ]:          0 :                                 }
    1984         [ #  # ]:          0 :                             }
    1985                 :            :                             // else: line style is default
    1986                 :            :                             // (i.e. invisible), don't generate action
    1987                 :            :                         }
    1988                 :            :                     }
    1989                 :          0 :                     break;
    1990                 :            : 
    1991                 :            :                     case META_RECT_ACTION:
    1992                 :            :                     {
    1993                 :            :                         const Rectangle& rRect(
    1994                 :          0 :                             static_cast<MetaRectAction*>(pCurrAct)->GetRect() );
    1995                 :            : 
    1996 [ #  # ][ #  # ]:          0 :                         if( rRect.IsEmpty() )
    1997                 :            :                             break;
    1998                 :            : 
    1999         [ #  # ]:          0 :                         const OutDevState& rState( rStates.getState() );
    2000                 :            :                         const ::basegfx::B2DPoint aTopLeftPixel(
    2001 [ #  # ][ #  # ]:          0 :                             rState.mapModeTransform * ::vcl::unotools::b2DPointFromPoint( rRect.TopLeft() ) );
    2002                 :            :                         const ::basegfx::B2DPoint aBottomRightPixel(
    2003                 :            :                             rState.mapModeTransform * ::vcl::unotools::b2DPointFromPoint( rRect.BottomRight() ) +
    2004                 :            :                             // #121100# OutputDevice::DrawRect() fills
    2005                 :            :                             // rectangles Apple-like, i.e. with one
    2006                 :            :                             // additional pixel to the right and bottom.
    2007 [ #  # ][ #  # ]:          0 :                             ::basegfx::B2DPoint(1,1) );
                 [ #  # ]
    2008                 :            : 
    2009                 :            :                         createFillAndStroke( ::basegfx::tools::createPolygonFromRect(
    2010                 :            :                                                  ::basegfx::B2DRange( aTopLeftPixel,
    2011                 :            :                                                                       aBottomRightPixel )),
    2012 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
         [ #  # ][ #  # ]
    2013                 :          0 :                         break;
    2014                 :            :                     }
    2015                 :            : 
    2016                 :            :                     case META_ROUNDRECT_ACTION:
    2017                 :            :                     {
    2018                 :            :                         const Rectangle& rRect(
    2019                 :          0 :                             static_cast<MetaRoundRectAction*>(pCurrAct)->GetRect());
    2020                 :            : 
    2021 [ #  # ][ #  # ]:          0 :                         if( rRect.IsEmpty() )
    2022                 :            :                             break;
    2023                 :            : 
    2024                 :            :                         ::basegfx::B2DPolygon aPoly(
    2025                 :            :                             ::basegfx::tools::createPolygonFromRect(
    2026                 :            :                                 ::basegfx::B2DRange(
    2027                 :            :                                     ::vcl::unotools::b2DPointFromPoint( rRect.TopLeft() ),
    2028                 :            :                                     ::vcl::unotools::b2DPointFromPoint( rRect.BottomRight() ) +
    2029                 :            :                                     ::basegfx::B2DPoint(1,1) ),
    2030         [ #  # ]:          0 :                                 ( (double) static_cast<MetaRoundRectAction*>(pCurrAct)->GetHorzRound() ) / rRect.GetWidth(),
    2031 [ #  # ][ #  # ]:          0 :                                 ( (double) static_cast<MetaRoundRectAction*>(pCurrAct)->GetVertRound() ) / rRect.GetHeight() ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2032 [ #  # ][ #  # ]:          0 :                         aPoly.transform( rStates.getState().mapModeTransform );
    2033                 :            : 
    2034                 :            :                         createFillAndStroke( aPoly,
    2035 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
    2036                 :            :                     }
    2037                 :          0 :                     break;
    2038                 :            : 
    2039                 :            :                     case META_ELLIPSE_ACTION:
    2040                 :            :                     {
    2041                 :            :                         const Rectangle& rRect(
    2042                 :          0 :                             static_cast<MetaEllipseAction*>(pCurrAct)->GetRect() );
    2043                 :            : 
    2044 [ #  # ][ #  # ]:          0 :                         if( rRect.IsEmpty() )
    2045                 :            :                             break;
    2046                 :            : 
    2047                 :            :                         const ::basegfx::B2DRange aRange(
    2048                 :            :                             ::vcl::unotools::b2DPointFromPoint( rRect.TopLeft() ),
    2049                 :            :                             ::vcl::unotools::b2DPointFromPoint( rRect.BottomRight() ) +
    2050 [ #  # ][ #  # ]:          0 :                             ::basegfx::B2DPoint(1,1) );
         [ #  # ][ #  # ]
    2051                 :            : 
    2052                 :            :                         ::basegfx::B2DPolygon aPoly(
    2053                 :            :                             ::basegfx::tools::createPolygonFromEllipse(
    2054                 :            :                                 aRange.getCenter(),
    2055                 :            :                                 aRange.getWidth(),
    2056 [ #  # ][ #  # ]:          0 :                                 aRange.getHeight() ));
         [ #  # ][ #  # ]
    2057 [ #  # ][ #  # ]:          0 :                         aPoly.transform( rStates.getState().mapModeTransform );
    2058                 :            : 
    2059                 :            :                         createFillAndStroke( aPoly,
    2060 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
    2061                 :            :                     }
    2062                 :          0 :                     break;
    2063                 :            : 
    2064                 :            :                     case META_ARC_ACTION:
    2065                 :            :                     {
    2066                 :            :                         // TODO(F1): Missing basegfx functionality. Mind empty rects!
    2067                 :          0 :                         const Polygon aToolsPoly( static_cast<MetaArcAction*>(pCurrAct)->GetRect(),
    2068                 :          0 :                                                   static_cast<MetaArcAction*>(pCurrAct)->GetStartPoint(),
    2069         [ #  # ]:          0 :                                                   static_cast<MetaArcAction*>(pCurrAct)->GetEndPoint(), POLY_ARC );
    2070         [ #  # ]:          0 :                         ::basegfx::B2DPolygon aPoly( aToolsPoly.getB2DPolygon() );
    2071 [ #  # ][ #  # ]:          0 :                         aPoly.transform( rStates.getState().mapModeTransform );
    2072                 :            : 
    2073                 :            :                         createFillAndStroke( aPoly,
    2074 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
                 [ #  # ]
    2075                 :            :                     }
    2076                 :          0 :                     break;
    2077                 :            : 
    2078                 :            :                     case META_PIE_ACTION:
    2079                 :            :                     {
    2080                 :            :                         // TODO(F1): Missing basegfx functionality. Mind empty rects!
    2081                 :          0 :                         const Polygon aToolsPoly( static_cast<MetaPieAction*>(pCurrAct)->GetRect(),
    2082                 :          0 :                                                   static_cast<MetaPieAction*>(pCurrAct)->GetStartPoint(),
    2083         [ #  # ]:          0 :                                                   static_cast<MetaPieAction*>(pCurrAct)->GetEndPoint(), POLY_PIE );
    2084         [ #  # ]:          0 :                         ::basegfx::B2DPolygon aPoly( aToolsPoly.getB2DPolygon() );
    2085 [ #  # ][ #  # ]:          0 :                         aPoly.transform( rStates.getState().mapModeTransform );
    2086                 :            : 
    2087                 :            :                         createFillAndStroke( aPoly,
    2088 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
                 [ #  # ]
    2089                 :            :                     }
    2090                 :          0 :                     break;
    2091                 :            : 
    2092                 :            :                     case META_CHORD_ACTION:
    2093                 :            :                     {
    2094                 :            :                         // TODO(F1): Missing basegfx functionality. Mind empty rects!
    2095                 :          0 :                         const Polygon aToolsPoly( static_cast<MetaChordAction*>(pCurrAct)->GetRect(),
    2096                 :          0 :                                                   static_cast<MetaChordAction*>(pCurrAct)->GetStartPoint(),
    2097         [ #  # ]:          0 :                                                   static_cast<MetaChordAction*>(pCurrAct)->GetEndPoint(), POLY_CHORD );
    2098         [ #  # ]:          0 :                         ::basegfx::B2DPolygon aPoly( aToolsPoly.getB2DPolygon() );
    2099 [ #  # ][ #  # ]:          0 :                         aPoly.transform( rStates.getState().mapModeTransform );
    2100                 :            : 
    2101                 :            :                         createFillAndStroke( aPoly,
    2102 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
                 [ #  # ]
    2103                 :            :                     }
    2104                 :          0 :                     break;
    2105                 :            : 
    2106                 :            :                     case META_POLYLINE_ACTION:
    2107                 :            :                     {
    2108                 :          0 :                         const OutDevState& rState( rStates.getState() );
    2109         [ #  # ]:          0 :                         if( rState.lineColor.getLength() ||
           [ #  #  #  # ]
    2110                 :          0 :                             rState.fillColor.getLength() )
    2111                 :            :                         {
    2112                 :          0 :                             MetaPolyLineAction* pPolyLineAct = static_cast<MetaPolyLineAction*>(pCurrAct);
    2113                 :            : 
    2114                 :          0 :                             const LineInfo& rLineInfo( pPolyLineAct->GetLineInfo() );
    2115         [ #  # ]:          0 :                             ::basegfx::B2DPolygon aPoly( pPolyLineAct->GetPolygon().getB2DPolygon() );
    2116         [ #  # ]:          0 :                             aPoly.transform( rState.mapModeTransform );
    2117                 :            : 
    2118         [ #  # ]:          0 :                             ActionSharedPtr pLineAction;
    2119                 :            : 
    2120         [ #  # ]:          0 :                             if( rLineInfo.IsDefault() )
    2121                 :            :                             {
    2122                 :            :                                 // plain hair line polygon
    2123                 :            :                                 pLineAction =
    2124                 :            :                                     internal::PolyPolyActionFactory::createLinePolyPolyAction(
    2125                 :            :                                         ::basegfx::B2DPolyPolygon(aPoly),
    2126                 :            :                                         rCanvas,
    2127 [ #  # ][ #  # ]:          0 :                                         rState );
         [ #  # ][ #  # ]
                 [ #  # ]
    2128                 :            : 
    2129         [ #  # ]:          0 :                                 if( pLineAction )
    2130                 :            :                                 {
    2131                 :            :                                     maActions.push_back(
    2132                 :            :                                         MtfAction(
    2133                 :            :                                             pLineAction,
    2134 [ #  # ][ #  # ]:          0 :                                             io_rCurrActionIndex ) );
                 [ #  # ]
    2135                 :            : 
    2136         [ #  # ]:          0 :                                     io_rCurrActionIndex += pLineAction->getActionCount()-1;
    2137                 :            :                                 }
    2138                 :            :                             }
    2139         [ #  # ]:          0 :                             else if( LINE_NONE != rLineInfo.GetStyle() )
    2140                 :            :                             {
    2141                 :            :                                 // 'thick' line polygon
    2142         [ #  # ]:          0 :                                 rendering::StrokeAttributes aStrokeAttributes;
    2143                 :            : 
    2144                 :            :                                 setupStrokeAttributes( aStrokeAttributes,
    2145                 :            :                                                        rFactoryParms,
    2146         [ #  # ]:          0 :                                                        rLineInfo );
    2147                 :            : 
    2148                 :            :                                 pLineAction =
    2149                 :            :                                     internal::PolyPolyActionFactory::createPolyPolyAction(
    2150                 :            :                                         ::basegfx::B2DPolyPolygon(aPoly),
    2151                 :            :                                         rCanvas,
    2152                 :            :                                         rState,
    2153 [ #  # ][ #  # ]:          0 :                                         aStrokeAttributes ) ;
         [ #  # ][ #  # ]
                 [ #  # ]
    2154                 :            : 
    2155         [ #  # ]:          0 :                                 if( pLineAction )
    2156                 :            :                                 {
    2157                 :            :                                     maActions.push_back(
    2158                 :            :                                         MtfAction(
    2159                 :            :                                             pLineAction,
    2160 [ #  # ][ #  # ]:          0 :                                             io_rCurrActionIndex ) );
                 [ #  # ]
    2161                 :            : 
    2162         [ #  # ]:          0 :                                     io_rCurrActionIndex += pLineAction->getActionCount()-1;
    2163         [ #  # ]:          0 :                                 }
    2164 [ #  # ][ #  # ]:          0 :                             }
    2165                 :            :                             // else: line style is default
    2166                 :            :                             // (i.e. invisible), don't generate action
    2167                 :            :                         }
    2168                 :            :                     }
    2169                 :          0 :                     break;
    2170                 :            : 
    2171                 :            :                     case META_POLYGON_ACTION:
    2172                 :            :                     {
    2173         [ #  # ]:          0 :                         ::basegfx::B2DPolygon aPoly( static_cast<MetaPolygonAction*>(pCurrAct)->GetPolygon().getB2DPolygon() );
    2174 [ #  # ][ #  # ]:          0 :                         aPoly.transform( rStates.getState().mapModeTransform );
    2175                 :            :                         createFillAndStroke( aPoly,
    2176 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
    2177                 :            :                     }
    2178                 :          0 :                     break;
    2179                 :            : 
    2180                 :            :                     case META_POLYPOLYGON_ACTION:
    2181                 :            :                     {
    2182         [ #  # ]:          0 :                         ::basegfx::B2DPolyPolygon aPoly( static_cast<MetaPolyPolygonAction*>(pCurrAct)->GetPolyPolygon().getB2DPolyPolygon() );
    2183 [ #  # ][ #  # ]:          0 :                         aPoly.transform( rStates.getState().mapModeTransform );
    2184                 :            :                         createFillAndStroke( aPoly,
    2185 [ #  # ][ #  # ]:          0 :                                              rFactoryParms );
    2186                 :            :                     }
    2187                 :          0 :                     break;
    2188                 :            : 
    2189                 :            :                     case META_BMP_ACTION:
    2190                 :            :                     {
    2191                 :          0 :                         MetaBmpAction* pAct = static_cast<MetaBmpAction*>(pCurrAct);
    2192                 :            : 
    2193                 :            :                         ActionSharedPtr pBmpAction(
    2194                 :            :                                 internal::BitmapActionFactory::createBitmapAction(
    2195                 :          0 :                                     pAct->GetBitmap(),
    2196         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2197                 :          0 :                                     ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2198                 :            :                                     rCanvas,
    2199   [ #  #  #  # ]:          0 :                                     rStates.getState() ) );
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    2200                 :            : 
    2201         [ #  # ]:          0 :                         if( pBmpAction )
    2202                 :            :                         {
    2203                 :            :                             maActions.push_back(
    2204                 :            :                                 MtfAction(
    2205                 :            :                                     pBmpAction,
    2206 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2207                 :            : 
    2208         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2209         [ #  # ]:          0 :                         }
    2210                 :            :                     }
    2211                 :          0 :                     break;
    2212                 :            : 
    2213                 :            :                     case META_BMPSCALE_ACTION:
    2214                 :            :                     {
    2215                 :          0 :                         MetaBmpScaleAction* pAct = static_cast<MetaBmpScaleAction*>(pCurrAct);
    2216                 :            : 
    2217                 :            :                         ActionSharedPtr pBmpAction(
    2218                 :            :                                 internal::BitmapActionFactory::createBitmapAction(
    2219                 :          0 :                                     pAct->GetBitmap(),
    2220         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2221                 :          0 :                                     ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2222         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2223                 :          0 :                                     ::vcl::unotools::b2DSizeFromSize( pAct->GetSize() ),
    2224                 :            :                                     rCanvas,
    2225   [ #  #  #  # ]:          0 :                                     rStates.getState() ) );
           [ #  #  #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    2226                 :            : 
    2227         [ #  # ]:          0 :                         if( pBmpAction )
    2228                 :            :                         {
    2229                 :            :                             maActions.push_back(
    2230                 :            :                                 MtfAction(
    2231                 :            :                                     pBmpAction,
    2232 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2233                 :            : 
    2234         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2235         [ #  # ]:          0 :                         }
    2236                 :            :                     }
    2237                 :          0 :                     break;
    2238                 :            : 
    2239                 :            :                     case META_BMPSCALEPART_ACTION:
    2240                 :            :                     {
    2241                 :          0 :                         MetaBmpScalePartAction* pAct = static_cast<MetaBmpScalePartAction*>(pCurrAct);
    2242                 :            : 
    2243                 :            :                         // crop bitmap to given source rectangle (no
    2244                 :            :                         // need to copy and convert the whole bitmap)
    2245         [ #  # ]:          0 :                         Bitmap aBmp( pAct->GetBitmap() );
    2246                 :          0 :                         const Rectangle aCropRect( pAct->GetSrcPoint(),
    2247         [ #  # ]:          0 :                                                     pAct->GetSrcSize() );
    2248         [ #  # ]:          0 :                         aBmp.Crop( aCropRect );
    2249                 :            : 
    2250                 :            :                         ActionSharedPtr pBmpAction(
    2251                 :            :                                 internal::BitmapActionFactory::createBitmapAction(
    2252                 :            :                                     aBmp,
    2253         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2254                 :          0 :                                     ::vcl::unotools::b2DPointFromPoint( pAct->GetDestPoint() ),
    2255         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2256                 :          0 :                                     ::vcl::unotools::b2DSizeFromSize( pAct->GetDestSize() ),
    2257                 :            :                                     rCanvas,
    2258   [ #  #  #  # ]:          0 :                                     rStates.getState() ) );
           [ #  #  #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2259                 :            : 
    2260         [ #  # ]:          0 :                         if( pBmpAction )
    2261                 :            :                         {
    2262                 :            :                             maActions.push_back(
    2263                 :            :                                 MtfAction(
    2264                 :            :                                     pBmpAction,
    2265 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2266                 :            : 
    2267         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2268 [ #  # ][ #  # ]:          0 :                         }
    2269                 :            :                     }
    2270                 :          0 :                     break;
    2271                 :            : 
    2272                 :            :                     case META_BMPEX_ACTION:
    2273                 :            :                     {
    2274                 :          0 :                         MetaBmpExAction* pAct = static_cast<MetaBmpExAction*>(pCurrAct);
    2275                 :            : 
    2276                 :            :                         ActionSharedPtr pBmpAction(
    2277                 :            :                                 internal::BitmapActionFactory::createBitmapAction(
    2278                 :          0 :                                     pAct->GetBitmapEx(),
    2279         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2280                 :          0 :                                     ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2281                 :            :                                     rCanvas,
    2282   [ #  #  #  # ]:          0 :                                     rStates.getState() ) );
           [ #  #  #  # ]
    2283                 :            : 
    2284         [ #  # ]:          0 :                         if( pBmpAction )
    2285                 :            :                         {
    2286                 :            :                             maActions.push_back(
    2287                 :            :                                 MtfAction(
    2288                 :            :                                     pBmpAction,
    2289 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2290                 :            : 
    2291         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2292         [ #  # ]:          0 :                         }
    2293                 :            :                     }
    2294                 :          0 :                     break;
    2295                 :            : 
    2296                 :            :                     case META_BMPEXSCALE_ACTION:
    2297                 :            :                     {
    2298                 :          0 :                         MetaBmpExScaleAction* pAct = static_cast<MetaBmpExScaleAction*>(pCurrAct);
    2299                 :            : 
    2300                 :            :                         ActionSharedPtr pBmpAction(
    2301                 :            :                                 internal::BitmapActionFactory::createBitmapAction(
    2302                 :          0 :                                     pAct->GetBitmapEx(),
    2303         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2304                 :          0 :                                     ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2305         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2306                 :          0 :                                     ::vcl::unotools::b2DSizeFromSize( pAct->GetSize() ),
    2307                 :            :                                     rCanvas,
    2308   [ #  #  #  # ]:          0 :                                     rStates.getState() ) );
           [ #  #  #  # ]
           [ #  #  #  # ]
    2309                 :            : 
    2310         [ #  # ]:          0 :                         if( pBmpAction )
    2311                 :            :                         {
    2312                 :            :                             maActions.push_back(
    2313                 :            :                                 MtfAction(
    2314                 :            :                                     pBmpAction,
    2315 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2316                 :            : 
    2317         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2318         [ #  # ]:          0 :                         }
    2319                 :            :                     }
    2320                 :          0 :                     break;
    2321                 :            : 
    2322                 :            :                     case META_BMPEXSCALEPART_ACTION:
    2323                 :            :                     {
    2324                 :          0 :                         MetaBmpExScalePartAction* pAct = static_cast<MetaBmpExScalePartAction*>(pCurrAct);
    2325                 :            : 
    2326                 :            :                         // crop bitmap to given source rectangle (no
    2327                 :            :                         // need to copy and convert the whole bitmap)
    2328         [ #  # ]:          0 :                         BitmapEx aBmp( pAct->GetBitmapEx() );
    2329                 :          0 :                         const Rectangle aCropRect( pAct->GetSrcPoint(),
    2330         [ #  # ]:          0 :                                                    pAct->GetSrcSize() );
    2331         [ #  # ]:          0 :                         aBmp.Crop( aCropRect );
    2332                 :            : 
    2333                 :            :                         ActionSharedPtr pBmpAction(
    2334                 :            :                             internal::BitmapActionFactory::createBitmapAction(
    2335                 :            :                                 aBmp,
    2336         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2337                 :          0 :                                 ::vcl::unotools::b2DPointFromPoint( pAct->GetDestPoint() ),
    2338         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2339                 :          0 :                                 ::vcl::unotools::b2DSizeFromSize( pAct->GetDestSize() ),
    2340                 :            :                                 rCanvas,
    2341   [ #  #  #  # ]:          0 :                                 rStates.getState() ) );
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    2342                 :            : 
    2343         [ #  # ]:          0 :                         if( pBmpAction )
    2344                 :            :                         {
    2345                 :            :                             maActions.push_back(
    2346                 :            :                                 MtfAction(
    2347                 :            :                                     pBmpAction,
    2348 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2349                 :            : 
    2350         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2351 [ #  # ][ #  # ]:          0 :                         }
    2352                 :            :                     }
    2353                 :          0 :                     break;
    2354                 :            : 
    2355                 :            :                     case META_MASK_ACTION:
    2356                 :            :                     {
    2357                 :          0 :                         MetaMaskAction* pAct = static_cast<MetaMaskAction*>(pCurrAct);
    2358                 :            : 
    2359                 :            :                         // create masked BitmapEx right here, as the
    2360                 :            :                         // canvas does not provide equivalent
    2361                 :            :                         // functionality
    2362                 :          0 :                         BitmapEx aBmp( createMaskBmpEx( pAct->GetBitmap(),
    2363         [ #  # ]:          0 :                                                         pAct->GetColor() ));
    2364                 :            : 
    2365                 :            :                         ActionSharedPtr pBmpAction(
    2366                 :            :                             internal::BitmapActionFactory::createBitmapAction(
    2367                 :            :                                 aBmp,
    2368         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2369                 :          0 :                                 ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2370                 :            :                                 rCanvas,
    2371   [ #  #  #  # ]:          0 :                                 rStates.getState() ) );
         [ #  # ][ #  # ]
    2372                 :            : 
    2373         [ #  # ]:          0 :                         if( pBmpAction )
    2374                 :            :                         {
    2375                 :            :                             maActions.push_back(
    2376                 :            :                                 MtfAction(
    2377                 :            :                                     pBmpAction,
    2378 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2379                 :            : 
    2380         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2381 [ #  # ][ #  # ]:          0 :                         }
    2382                 :            :                     }
    2383                 :          0 :                     break;
    2384                 :            : 
    2385                 :            :                     case META_MASKSCALE_ACTION:
    2386                 :            :                     {
    2387                 :          0 :                         MetaMaskScaleAction* pAct = static_cast<MetaMaskScaleAction*>(pCurrAct);
    2388                 :            : 
    2389                 :            :                         // create masked BitmapEx right here, as the
    2390                 :            :                         // canvas does not provide equivalent
    2391                 :            :                         // functionality
    2392                 :          0 :                         BitmapEx aBmp( createMaskBmpEx( pAct->GetBitmap(),
    2393         [ #  # ]:          0 :                                                         pAct->GetColor() ));
    2394                 :            : 
    2395                 :            :                         ActionSharedPtr pBmpAction(
    2396                 :            :                             internal::BitmapActionFactory::createBitmapAction(
    2397                 :            :                                 aBmp,
    2398         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2399                 :          0 :                                 ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2400         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2401                 :          0 :                                 ::vcl::unotools::b2DSizeFromSize( pAct->GetSize() ),
    2402                 :            :                                 rCanvas,
    2403   [ #  #  #  # ]:          0 :                                 rStates.getState() ) );
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    2404                 :            : 
    2405         [ #  # ]:          0 :                         if( pBmpAction )
    2406                 :            :                         {
    2407                 :            :                             maActions.push_back(
    2408                 :            :                                 MtfAction(
    2409                 :            :                                     pBmpAction,
    2410 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2411                 :            : 
    2412         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2413 [ #  # ][ #  # ]:          0 :                         }
    2414                 :            :                     }
    2415                 :          0 :                     break;
    2416                 :            : 
    2417                 :            :                     case META_MASKSCALEPART_ACTION:
    2418                 :            :                     {
    2419                 :          0 :                         MetaMaskScalePartAction* pAct = static_cast<MetaMaskScalePartAction*>(pCurrAct);
    2420                 :            : 
    2421                 :            :                         // create masked BitmapEx right here, as the
    2422                 :            :                         // canvas does not provide equivalent
    2423                 :            :                         // functionality
    2424                 :          0 :                         BitmapEx aBmp( createMaskBmpEx( pAct->GetBitmap(),
    2425         [ #  # ]:          0 :                                                         pAct->GetColor() ));
    2426                 :            : 
    2427                 :            :                         // crop bitmap to given source rectangle (no
    2428                 :            :                         // need to copy and convert the whole bitmap)
    2429                 :          0 :                         const Rectangle aCropRect( pAct->GetSrcPoint(),
    2430         [ #  # ]:          0 :                                                    pAct->GetSrcSize() );
    2431         [ #  # ]:          0 :                         aBmp.Crop( aCropRect );
    2432                 :            : 
    2433                 :            :                         ActionSharedPtr pBmpAction(
    2434                 :            :                             internal::BitmapActionFactory::createBitmapAction(
    2435                 :            :                                 aBmp,
    2436         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2437                 :          0 :                                 ::vcl::unotools::b2DPointFromPoint( pAct->GetDestPoint() ),
    2438         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2439                 :          0 :                                 ::vcl::unotools::b2DSizeFromSize( pAct->GetDestSize() ),
    2440                 :            :                                 rCanvas,
    2441   [ #  #  #  # ]:          0 :                                 rStates.getState() ) );
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    2442                 :            : 
    2443         [ #  # ]:          0 :                         if( pBmpAction )
    2444                 :            :                         {
    2445                 :            :                             maActions.push_back(
    2446                 :            :                                 MtfAction(
    2447                 :            :                                     pBmpAction,
    2448 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2449                 :            : 
    2450         [ #  # ]:          0 :                             io_rCurrActionIndex += pBmpAction->getActionCount()-1;
    2451 [ #  # ][ #  # ]:          0 :                         }
    2452                 :            :                     }
    2453                 :          0 :                     break;
    2454                 :            : 
    2455                 :            :                     case META_GRADIENTEX_ACTION:
    2456                 :            :                         // TODO(F1): use native Canvas gradients here
    2457                 :            :                         // action is ignored here, because redundant to META_GRADIENT_ACTION
    2458                 :          0 :                         break;
    2459                 :            : 
    2460                 :            :                     case META_WALLPAPER_ACTION:
    2461                 :            :                         // TODO(F2): NYI
    2462                 :          0 :                         break;
    2463                 :            : 
    2464                 :            :                     case META_TRANSPARENT_ACTION:
    2465                 :            :                     {
    2466                 :          0 :                         const OutDevState& rState( rStates.getState() );
    2467         [ #  # ]:          0 :                         if( rState.lineColor.getLength() ||
           [ #  #  #  # ]
    2468                 :          0 :                             rState.fillColor.getLength() )
    2469                 :            :                         {
    2470                 :          0 :                             MetaTransparentAction* pAct = static_cast<MetaTransparentAction*>(pCurrAct);
    2471         [ #  # ]:          0 :                             ::basegfx::B2DPolyPolygon aPoly( pAct->GetPolyPolygon().getB2DPolyPolygon() );
    2472         [ #  # ]:          0 :                             aPoly.transform( rState.mapModeTransform );
    2473                 :            : 
    2474                 :            :                             ActionSharedPtr pPolyAction(
    2475                 :            :                                 internal::PolyPolyActionFactory::createPolyPolyAction(
    2476                 :            :                                     aPoly,
    2477                 :            :                                     rCanvas,
    2478                 :            :                                     rState,
    2479         [ #  # ]:          0 :                                     pAct->GetTransparence() ) );
    2480                 :            : 
    2481         [ #  # ]:          0 :                             if( pPolyAction )
    2482                 :            :                             {
    2483                 :            :                                 maActions.push_back(
    2484                 :            :                                     MtfAction(
    2485                 :            :                                         pPolyAction,
    2486 [ #  # ][ #  # ]:          0 :                                         io_rCurrActionIndex ) );
                 [ #  # ]
    2487                 :            : 
    2488         [ #  # ]:          0 :                                 io_rCurrActionIndex += pPolyAction->getActionCount()-1;
    2489 [ #  # ][ #  # ]:          0 :                             }
    2490                 :            :                         }
    2491                 :            :                     }
    2492                 :          0 :                     break;
    2493                 :            : 
    2494                 :            :                     case META_FLOATTRANSPARENT_ACTION:
    2495                 :            :                     {
    2496                 :          0 :                         MetaFloatTransparentAction* pAct = static_cast<MetaFloatTransparentAction*>(pCurrAct);
    2497                 :            : 
    2498                 :            :                         internal::MtfAutoPtr pMtf(
    2499 [ #  # ][ #  # ]:          0 :                             new ::GDIMetaFile( pAct->GetGDIMetaFile() ) );
    2500                 :            : 
    2501                 :            :                         // TODO(P2): Use native canvas gradients here (saves a lot of UNO calls)
    2502                 :            :                         internal::GradientAutoPtr pGradient(
    2503 [ #  # ][ #  # ]:          0 :                             new Gradient( pAct->GetGradient() ) );
    2504                 :            : 
    2505                 :            :                         DBG_TESTSOLARMUTEX();
    2506                 :            : 
    2507                 :            :                         ActionSharedPtr pFloatTransAction(
    2508                 :            :                             internal::TransparencyGroupActionFactory::createTransparencyGroupAction(
    2509                 :            :                                 pMtf,
    2510                 :            :                                 pGradient,
    2511                 :            :                                 rParms,
    2512         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2513                 :          0 :                                 ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2514         [ #  # ]:          0 :                                 rStates.getState().mapModeTransform *
    2515                 :          0 :                                 ::vcl::unotools::b2DSizeFromSize( pAct->GetSize() ),
    2516                 :            :                                 rCanvas,
    2517   [ #  #  #  # ]:          0 :                                 rStates.getState() ) );
         [ #  # ][ #  # ]
           [ #  #  #  # ]
    2518                 :            : 
    2519         [ #  # ]:          0 :                         if( pFloatTransAction )
    2520                 :            :                         {
    2521                 :            :                             maActions.push_back(
    2522                 :            :                                 MtfAction(
    2523                 :            :                                     pFloatTransAction,
    2524 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2525                 :            : 
    2526         [ #  # ]:          0 :                             io_rCurrActionIndex += pFloatTransAction->getActionCount()-1;
    2527 [ #  # ][ #  # ]:          0 :                         }
                 [ #  # ]
    2528                 :            :                     }
    2529                 :          0 :                     break;
    2530                 :            : 
    2531                 :            :                     case META_TEXT_ACTION:
    2532                 :            :                     {
    2533                 :          0 :                         MetaTextAction* pAct = static_cast<MetaTextAction*>(pCurrAct);
    2534         [ #  # ]:          0 :                         XubString sText = XubString( pAct->GetText() );
    2535                 :            : 
    2536         [ #  # ]:          0 :                         if( rVDev.GetDigitLanguage())
    2537         [ #  # ]:          0 :                             convertToLocalizedNumerals ( sText,rVDev.GetDigitLanguage() );
    2538                 :            : 
    2539                 :            :                         createTextAction(
    2540                 :          0 :                             pAct->GetPoint(),
    2541                 :            :                             sText,
    2542                 :          0 :                             pAct->GetIndex(),
    2543                 :          0 :                             pAct->GetLen() == (sal_uInt16)STRING_LEN ? pAct->GetText().getLength() - pAct->GetIndex() : pAct->GetLen(),
    2544                 :            :                             NULL,
    2545                 :            :                             rFactoryParms,
    2546 [ #  # ][ #  # ]:          0 :                             bSubsettableActions );
           [ #  #  #  #  
                   #  # ]
    2547                 :            :                     }
    2548                 :          0 :                     break;
    2549                 :            : 
    2550                 :            :                     case META_TEXTARRAY_ACTION:
    2551                 :            :                     {
    2552                 :          0 :                         MetaTextArrayAction* pAct = static_cast<MetaTextArrayAction*>(pCurrAct);
    2553         [ #  # ]:          0 :                         XubString sText = XubString( pAct->GetText() );
    2554                 :            : 
    2555         [ #  # ]:          0 :                         if( rVDev.GetDigitLanguage())
    2556         [ #  # ]:          0 :                             convertToLocalizedNumerals ( sText,rVDev.GetDigitLanguage() );
    2557                 :            : 
    2558                 :            :                         createTextAction(
    2559                 :          0 :                             pAct->GetPoint(),
    2560                 :            :                             sText,
    2561                 :          0 :                             pAct->GetIndex(),
    2562                 :          0 :                             pAct->GetLen() == (sal_uInt16)STRING_LEN ? pAct->GetText().getLength() - pAct->GetIndex() : pAct->GetLen(),
    2563                 :          0 :                             pAct->GetDXArray(),
    2564                 :            :                             rFactoryParms,
    2565 [ #  # ][ #  # ]:          0 :                             bSubsettableActions );
           [ #  #  #  #  
                   #  # ]
    2566                 :            :                     }
    2567                 :          0 :                     break;
    2568                 :            : 
    2569                 :            :                     case META_TEXTLINE_ACTION:
    2570                 :            :                     {
    2571                 :          0 :                         MetaTextLineAction*      pAct = static_cast<MetaTextLineAction*>(pCurrAct);
    2572                 :            : 
    2573         [ #  # ]:          0 :                         const OutDevState&       rState( rStates.getState() );
    2574                 :            :                         const ::Size             aBaselineOffset( tools::getBaselineOffset( rState,
    2575         [ #  # ]:          0 :                                                                                             rVDev ) );
    2576                 :            :                         const ::basegfx::B2DSize aSize( rState.mapModeTransform *
    2577                 :          0 :                                                         ::basegfx::B2DSize(pAct->GetWidth(),
    2578         [ #  # ]:          0 :                                                                            0 ));
    2579                 :            : 
    2580                 :            :                         ActionSharedPtr pPolyAction(
    2581                 :            :                             PolyPolyActionFactory::createPolyPolyAction(
    2582                 :            :                                 tools::createTextLinesPolyPolygon(
    2583                 :            :                                     rState.mapModeTransform *
    2584                 :            :                                     ::basegfx::B2DPoint(
    2585                 :          0 :                                         ::vcl::unotools::b2DPointFromPoint(pAct->GetStartPoint()) +
    2586                 :            :                                         ::vcl::unotools::b2DSizeFromSize(aBaselineOffset)),
    2587                 :          0 :                                     aSize.getX(),
    2588                 :            :                                     tools::createTextLineInfo( rVDev,
    2589                 :            :                                                                rState )),
    2590                 :            :                                 rCanvas,
    2591 [ #  # ][ #  # ]:          0 :                                 rState ) );
         [ #  # ][ #  # ]
           [ #  #  #  #  
                   #  # ]
    2592                 :            : 
    2593         [ #  # ]:          0 :                         if( pPolyAction.get() )
    2594                 :            :                         {
    2595                 :            :                             maActions.push_back(
    2596                 :            :                                 MtfAction(
    2597                 :            :                                     pPolyAction,
    2598 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2599                 :            : 
    2600         [ #  # ]:          0 :                             io_rCurrActionIndex += pPolyAction->getActionCount()-1;
    2601         [ #  # ]:          0 :                         }
    2602                 :            :                     }
    2603                 :          0 :                     break;
    2604                 :            : 
    2605                 :            :                     case META_TEXTRECT_ACTION:
    2606                 :            :                     {
    2607                 :          0 :                         MetaTextRectAction* pAct = static_cast<MetaTextRectAction*>(pCurrAct);
    2608                 :            : 
    2609         [ #  # ]:          0 :                         rStates.pushState(PUSH_ALL);
    2610                 :            : 
    2611                 :            :                         // use the VDev to break up the text rect
    2612                 :            :                         // action into readily formatted lines
    2613         [ #  # ]:          0 :                         GDIMetaFile aTmpMtf;
    2614                 :          0 :                         rVDev.AddTextRectActions( pAct->GetRect(),
    2615                 :          0 :                                                   pAct->GetText(),
    2616                 :          0 :                                                   pAct->GetStyle(),
    2617         [ #  # ]:          0 :                                                   aTmpMtf );
           [ #  #  #  # ]
    2618                 :            : 
    2619                 :            :                         createActions( aTmpMtf,
    2620                 :            :                                        rFactoryParms,
    2621         [ #  # ]:          0 :                                        bSubsettableActions );
    2622                 :            : 
    2623         [ #  # ]:          0 :                         rStates.popState();
    2624                 :            : 
    2625         [ #  # ]:          0 :                         break;
    2626                 :            :                     }
    2627                 :            : 
    2628                 :            :                     case META_STRETCHTEXT_ACTION:
    2629                 :            :                     {
    2630                 :          0 :                         MetaStretchTextAction* pAct = static_cast<MetaStretchTextAction*>(pCurrAct);
    2631         [ #  # ]:          0 :                         XubString sText = XubString( pAct->GetText() );
    2632                 :            : 
    2633         [ #  # ]:          0 :                         if( rVDev.GetDigitLanguage())
    2634         [ #  # ]:          0 :                             convertToLocalizedNumerals ( sText,rVDev.GetDigitLanguage() );
    2635                 :            : 
    2636                 :          0 :                         const sal_uInt16 nLen( pAct->GetLen() == (sal_uInt16)STRING_LEN ?
    2637         [ #  # ]:          0 :                                            pAct->GetText().getLength() - pAct->GetIndex() : pAct->GetLen() );
    2638                 :            : 
    2639                 :            :                         // #i70897# Nothing to do, actually...
    2640         [ #  # ]:          0 :                         if( nLen == 0 )
    2641                 :            :                             break;
    2642                 :            : 
    2643                 :            :                         // have to fit the text into the given
    2644                 :            :                         // width. This is achieved by internally
    2645                 :            :                         // generating a DX array, and uniformly
    2646                 :            :                         // distributing the excess/insufficient width
    2647                 :            :                         // to every logical character.
    2648         [ #  # ]:          0 :                         ::boost::scoped_array< sal_Int32 > pDXArray( new sal_Int32[nLen] );
    2649                 :            : 
    2650                 :          0 :                         rVDev.GetTextArray( pAct->GetText(), pDXArray.get(),
    2651 [ #  # ][ #  # ]:          0 :                                             pAct->GetIndex(), pAct->GetLen() );
                 [ #  # ]
    2652                 :            : 
    2653                 :          0 :                         const sal_Int32 nWidthDifference( pAct->GetWidth() - pDXArray[ nLen-1 ] );
    2654                 :            : 
    2655                 :            :                         // Last entry of pDXArray contains total width of the text
    2656                 :          0 :                         sal_Int32* p=pDXArray.get();
    2657         [ #  # ]:          0 :                         for( sal_uInt16 i=1; i<=nLen; ++i )
    2658                 :            :                         {
    2659                 :            :                             // calc ratio for every array entry, to
    2660                 :            :                             // distribute rounding errors 'evenly'
    2661                 :            :                             // across the characters. Note that each
    2662                 :            :                             // entry represents the 'end' position of
    2663                 :            :                             // the corresponding character, thus, we
    2664                 :            :                             // let i run from 1 to nLen.
    2665                 :          0 :                             *p++ += (sal_Int32)i*nWidthDifference/nLen;
    2666                 :            :                         }
    2667                 :            : 
    2668                 :            :                         createTextAction(
    2669                 :          0 :                             pAct->GetPoint(),
    2670                 :            :                             sText,
    2671                 :          0 :                             pAct->GetIndex(),
    2672                 :          0 :                             pAct->GetLen() == (sal_uInt16)STRING_LEN ? pAct->GetText().getLength() - pAct->GetIndex() : pAct->GetLen(),
    2673                 :          0 :                             pDXArray.get(),
    2674                 :            :                             rFactoryParms,
    2675 [ #  # ][ #  # ]:          0 :                             bSubsettableActions );
         [ #  # ][ #  # ]
           [ #  #  #  #  
                   #  # ]
    2676                 :            :                     }
    2677                 :          0 :                     break;
    2678                 :            : 
    2679                 :            :                     case META_RENDERGRAPHIC_ACTION:
    2680                 :            :                     {
    2681                 :          0 :                         MetaRenderGraphicAction* pAct = static_cast<MetaRenderGraphicAction*>(pCurrAct);
    2682                 :            : 
    2683                 :            :                         ActionSharedPtr pRenderGraphicAction(
    2684                 :            :                                 internal::RenderGraphicActionFactory::createRenderGraphicAction(
    2685                 :          0 :                                     pAct->GetRenderGraphic(),
    2686         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2687                 :          0 :                                     ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
    2688         [ #  # ]:          0 :                                     rStates.getState().mapModeTransform *
    2689                 :          0 :                                     ::vcl::unotools::b2DSizeFromSize( pAct->GetSize() ),
    2690                 :            :                                     rCanvas,
    2691   [ #  #  #  # ]:          0 :                                     rStates.getState() ) );
           [ #  #  #  # ]
           [ #  #  #  # ]
    2692                 :            : 
    2693         [ #  # ]:          0 :                         if( pRenderGraphicAction )
    2694                 :            :                         {
    2695                 :            :                             maActions.push_back(
    2696                 :            :                                 MtfAction(
    2697                 :            :                                     pRenderGraphicAction,
    2698 [ #  # ][ #  # ]:          0 :                                     io_rCurrActionIndex ) );
                 [ #  # ]
    2699                 :            : 
    2700         [ #  # ]:          0 :                             io_rCurrActionIndex += pRenderGraphicAction->getActionCount()-1;
    2701         [ #  # ]:          0 :                         }
    2702                 :            :                     }
    2703                 :          0 :                     break;
    2704                 :            : 
    2705                 :            :                     default:
    2706                 :            :                         OSL_FAIL( "Unknown meta action type encountered" );
    2707                 :          0 :                         break;
    2708                 :            :                 }
    2709                 :            : 
    2710                 :            :                 // increment action index (each mtf action counts _at
    2711                 :            :                 // least_ one. Some count for more, therefore,
    2712                 :            :                 // io_rCurrActionIndex is sometimes incremented by
    2713                 :            :                 // pAct->getActionCount()-1 above, the -1 being the
    2714                 :            :                 // correction for the unconditional increment here).
    2715                 :          0 :                 ++io_rCurrActionIndex;
    2716                 :            :             }
    2717                 :            : 
    2718                 :          0 :             return true;
    2719                 :            :         }
    2720                 :            : 
    2721                 :            : 
    2722                 :            :         namespace
    2723                 :            :         {
    2724                 :          0 :             class ActionRenderer
    2725                 :            :             {
    2726                 :            :             public:
    2727                 :          0 :                 ActionRenderer( const ::basegfx::B2DHomMatrix& rTransformation ) :
    2728                 :            :                     maTransformation( rTransformation ),
    2729                 :          0 :                     mbRet( true )
    2730                 :            :                 {
    2731                 :          0 :                 }
    2732                 :            : 
    2733                 :          0 :                 bool result() const
    2734                 :            :                 {
    2735                 :          0 :                     return mbRet;
    2736                 :            :                 }
    2737                 :            : 
    2738                 :          0 :                 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rAction )
    2739                 :            :                 {
    2740                 :            :                     // ANDing the result. We want to fail if at least
    2741                 :            :                     // one action failed.
    2742                 :          0 :                     mbRet &= rAction.mpAction->render( maTransformation );
    2743                 :          0 :                 }
    2744                 :            : 
    2745                 :          0 :                 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction&  rAction,
    2746                 :            :                                  const Action::Subset&                                  rSubset )
    2747                 :            :                 {
    2748                 :            :                     // ANDing the result. We want to fail if at least
    2749                 :            :                     // one action failed.
    2750                 :          0 :                     mbRet &= rAction.mpAction->renderSubset( maTransformation,
    2751                 :          0 :                                                              rSubset );
    2752                 :          0 :                 }
    2753                 :            : 
    2754                 :            :             private:
    2755                 :            :                 ::basegfx::B2DHomMatrix maTransformation;
    2756                 :            :                 bool                    mbRet;
    2757                 :            :             };
    2758                 :            : 
    2759                 :          0 :             class AreaQuery
    2760                 :            :             {
    2761                 :            :             public:
    2762                 :          0 :                 AreaQuery( const ::basegfx::B2DHomMatrix& rTransformation ) :
    2763                 :            :                     maTransformation( rTransformation ),
    2764         [ #  # ]:          0 :                     maBounds()
    2765                 :            :                 {
    2766                 :          0 :                 }
    2767                 :            : 
    2768                 :          0 :                 bool result() const
    2769                 :            :                 {
    2770                 :          0 :                     return true; // nothing can fail here
    2771                 :            :                 }
    2772                 :            : 
    2773                 :          0 :                 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rAction )
    2774                 :            :                 {
    2775         [ #  # ]:          0 :                     maBounds.expand( rAction.mpAction->getBounds( maTransformation ) );
    2776                 :          0 :                 }
    2777                 :            : 
    2778                 :          0 :                 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction&  rAction,
    2779                 :            :                                  const Action::Subset&                                  rSubset )
    2780                 :            :                 {
    2781                 :          0 :                     maBounds.expand( rAction.mpAction->getBounds( maTransformation,
    2782         [ #  # ]:          0 :                                                                   rSubset ) );
    2783                 :          0 :                 }
    2784                 :            : 
    2785                 :          0 :                 ::basegfx::B2DRange getBounds() const
    2786                 :            :                 {
    2787                 :          0 :                     return maBounds;
    2788                 :            :                 }
    2789                 :            : 
    2790                 :            :             private:
    2791                 :            :                 ::basegfx::B2DHomMatrix maTransformation;
    2792                 :            :                 ::basegfx::B2DRange     maBounds;
    2793                 :            :             };
    2794                 :            : 
    2795                 :            :             // Doing that via inline class. Compilers tend to not inline free
    2796                 :            :             // functions.
    2797                 :            :             struct UpperBoundActionIndexComparator
    2798                 :            :             {
    2799                 :          0 :                 bool operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rLHS,
    2800                 :            :                                  const ::cppcanvas::internal::ImplRenderer::MtfAction& rRHS )
    2801                 :            :                 {
    2802                 :            :                     const sal_Int32 nLHSCount( rLHS.mpAction ?
    2803         [ #  # ]:          0 :                                                rLHS.mpAction->getActionCount() : 0 );
    2804                 :            :                     const sal_Int32 nRHSCount( rRHS.mpAction ?
    2805         [ #  # ]:          0 :                                                rRHS.mpAction->getActionCount() : 0 );
    2806                 :            : 
    2807                 :            :                     // compare end of action range, to have an action selected
    2808                 :            :                     // by lower_bound even if the requested index points in
    2809                 :            :                     // the middle of the action's range
    2810                 :          0 :                     return rLHS.mnOrigIndex + nLHSCount < rRHS.mnOrigIndex + nRHSCount;
    2811                 :            :                 }
    2812                 :            :             };
    2813                 :            : 
    2814                 :            :             /** Algorithm to apply given functor to a subset range
    2815                 :            : 
    2816                 :            :                 @tpl Functor
    2817                 :            : 
    2818                 :            :                 Functor to call for each element of the subset
    2819                 :            :                 range. Must provide the following method signatures:
    2820                 :            :                 bool result() (returning false if operation failed)
    2821                 :            : 
    2822                 :            :              */
    2823                 :            :             template< typename Functor > bool
    2824                 :          0 :                 forSubsetRange( Functor&                                            rFunctor,
    2825                 :            :                                 ImplRenderer::ActionVector::const_iterator          aRangeBegin,
    2826                 :            :                                 ImplRenderer::ActionVector::const_iterator          aRangeEnd,
    2827                 :            :                                 sal_Int32                                           nStartIndex,
    2828                 :            :                                 sal_Int32                                           nEndIndex,
    2829                 :            :                                 const ImplRenderer::ActionVector::const_iterator&   rEnd )
    2830                 :            :             {
    2831 [ #  # ][ #  # ]:          0 :                 if( aRangeBegin == aRangeEnd )
    2832                 :            :                 {
    2833                 :            :                     // only a single action. Setup subset, and call functor
    2834                 :            :                     Action::Subset aSubset;
    2835 [ #  # ][ #  # ]:          0 :                     aSubset.mnSubsetBegin = ::std::max( sal_Int32( 0 ),
    2836                 :            :                                                         nStartIndex - aRangeBegin->mnOrigIndex );
    2837 [ #  # ][ #  # ]:          0 :                     aSubset.mnSubsetEnd   = ::std::min( aRangeBegin->mpAction->getActionCount(),
         [ #  # ][ #  # ]
    2838                 :            :                                                         nEndIndex - aRangeBegin->mnOrigIndex );
    2839                 :            : 
    2840 [ #  # ][ #  # ]:          0 :                     ENSURE_OR_RETURN_FALSE( aSubset.mnSubsetBegin >= 0 && aSubset.mnSubsetEnd >= 0,
         [ #  # ][ #  # ]
    2841                 :            :                                       "ImplRenderer::forSubsetRange(): Invalid indices" );
    2842                 :            : 
    2843 [ #  # ][ #  # ]:          0 :                     rFunctor( *aRangeBegin, aSubset );
    2844                 :            :                 }
    2845                 :            :                 else
    2846                 :            :                 {
    2847                 :            :                     // more than one action.
    2848                 :            : 
    2849                 :            :                     // render partial first, full intermediate, and
    2850                 :            :                     // partial last action
    2851                 :            :                     Action::Subset aSubset;
    2852 [ #  # ][ #  # ]:          0 :                     aSubset.mnSubsetBegin = ::std::max( sal_Int32( 0 ),
    2853                 :            :                                                         nStartIndex - aRangeBegin->mnOrigIndex );
    2854 [ #  # ][ #  # ]:          0 :                     aSubset.mnSubsetEnd   = aRangeBegin->mpAction->getActionCount();
    2855                 :            : 
    2856 [ #  # ][ #  # ]:          0 :                     ENSURE_OR_RETURN_FALSE( aSubset.mnSubsetBegin >= 0 && aSubset.mnSubsetEnd >= 0,
         [ #  # ][ #  # ]
    2857                 :            :                                       "ImplRenderer::forSubsetRange(): Invalid indices" );
    2858                 :            : 
    2859 [ #  # ][ #  # ]:          0 :                     rFunctor( *aRangeBegin, aSubset );
    2860                 :            : 
    2861                 :            :                     // first action rendered, skip to next
    2862                 :          0 :                     ++aRangeBegin;
    2863                 :            : 
    2864                 :            :                     // render full middle actions
    2865 [ #  # ][ #  # ]:          0 :                     while( aRangeBegin != aRangeEnd )
         [ #  # ][ #  # ]
    2866 [ #  # ][ #  # ]:          0 :                         rFunctor( *aRangeBegin++ );
    2867                 :            : 
    2868 [ #  # ][ #  # ]:          0 :                     if( aRangeEnd == rEnd ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2869                 :            :                         aRangeEnd->mnOrigIndex > nEndIndex )
    2870                 :            :                     {
    2871                 :            :                         // aRangeEnd denotes end of action vector,
    2872                 :            :                         //
    2873                 :            :                         // or
    2874                 :            :                         //
    2875                 :            :                         // nEndIndex references something _after_
    2876                 :            :                         // aRangeBegin, but _before_ aRangeEnd
    2877                 :            :                         //
    2878                 :            :                         // either way: no partial action left
    2879                 :          0 :                         return rFunctor.result();
    2880                 :            :                     }
    2881                 :            : 
    2882                 :          0 :                     aSubset.mnSubsetBegin = 0;
    2883                 :          0 :                     aSubset.mnSubsetEnd   = nEndIndex - aRangeEnd->mnOrigIndex;
    2884                 :            : 
    2885 [ #  # ][ #  # ]:          0 :                     ENSURE_OR_RETURN_FALSE( aSubset.mnSubsetBegin >= 0 && aSubset.mnSubsetEnd >= 0,
         [ #  # ][ #  # ]
    2886                 :            :                                       "ImplRenderer::forSubsetRange(): Invalid indices" );
    2887                 :            : 
    2888 [ #  # ][ #  # ]:          0 :                     rFunctor( *aRangeEnd, aSubset );
    2889                 :            :                 }
    2890                 :            : 
    2891                 :          0 :                 return rFunctor.result();
    2892                 :            :             }
    2893                 :            :         }
    2894                 :            : 
    2895                 :          0 :         bool ImplRenderer::getSubsetIndices( sal_Int32&                     io_rStartIndex,
    2896                 :            :                                              sal_Int32&                     io_rEndIndex,
    2897                 :            :                                              ActionVector::const_iterator&  o_rRangeBegin,
    2898                 :            :                                              ActionVector::const_iterator&  o_rRangeEnd ) const
    2899                 :            :         {
    2900         [ #  # ]:          0 :             ENSURE_OR_RETURN_FALSE( io_rStartIndex<=io_rEndIndex,
    2901                 :            :                               "ImplRenderer::getSubsetIndices(): invalid action range" );
    2902                 :            : 
    2903         [ #  # ]:          0 :             ENSURE_OR_RETURN_FALSE( !maActions.empty(),
    2904                 :            :                               "ImplRenderer::getSubsetIndices(): no actions to render" );
    2905                 :            : 
    2906         [ #  # ]:          0 :             const sal_Int32 nMinActionIndex( maActions.front().mnOrigIndex );
    2907         [ #  # ]:          0 :             const sal_Int32 nMaxActionIndex( maActions.back().mnOrigIndex +
    2908 [ #  # ][ #  # ]:          0 :                                              maActions.back().mpAction->getActionCount() );
    2909                 :            : 
    2910                 :            :             // clip given range to permissible values (there might be
    2911                 :            :             // ranges before and behind the valid indices)
    2912                 :            :             io_rStartIndex = ::std::max( nMinActionIndex,
    2913         [ #  # ]:          0 :                                          io_rStartIndex );
    2914                 :            :             io_rEndIndex = ::std::min( nMaxActionIndex,
    2915         [ #  # ]:          0 :                                        io_rEndIndex );
    2916                 :            : 
    2917 [ #  # ][ #  # ]:          0 :             if( io_rStartIndex == io_rEndIndex ||
    2918                 :            :                 io_rStartIndex > io_rEndIndex )
    2919                 :            :             {
    2920                 :            :                 // empty range, don't render anything. The second
    2921                 :            :                 // condition e.g. happens if the requested range lies
    2922                 :            :                 // fully before or behind the valid action indices.
    2923                 :          0 :                 return false;
    2924                 :            :             }
    2925                 :            : 
    2926                 :            : 
    2927                 :          0 :             const ActionVector::const_iterator aBegin( maActions.begin() );
    2928                 :          0 :             const ActionVector::const_iterator aEnd( maActions.end() );
    2929                 :            : 
    2930                 :            : 
    2931                 :            :             // find start and end action
    2932                 :            :             // =========================
    2933                 :            :             o_rRangeBegin = ::std::lower_bound( aBegin, aEnd,
    2934                 :            :                                                 MtfAction( ActionSharedPtr(), io_rStartIndex ),
    2935 [ #  # ][ #  # ]:          0 :                                                 UpperBoundActionIndexComparator() );
         [ #  # ][ #  # ]
                 [ #  # ]
    2936                 :            :             o_rRangeEnd   = ::std::lower_bound( aBegin, aEnd,
    2937                 :            :                                                 MtfAction( ActionSharedPtr(), io_rEndIndex ),
    2938 [ #  # ][ #  # ]:          0 :                                                 UpperBoundActionIndexComparator() );
         [ #  # ][ #  # ]
                 [ #  # ]
    2939                 :          0 :             return true;
    2940                 :            :         }
    2941                 :            : 
    2942                 :            : 
    2943                 :            :         // Public methods
    2944                 :            :         // ====================================================================
    2945                 :            : 
    2946                 :          0 :         ImplRenderer::ImplRenderer( const CanvasSharedPtr&  rCanvas,
    2947                 :            :                                     const GDIMetaFile&      rMtf,
    2948                 :            :                                     const Parameters&       rParams ) :
    2949                 :            :             CanvasGraphicHelper( rCanvas ),
    2950 [ #  # ][ #  # ]:          0 :             maActions()
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2951                 :            :         {
    2952                 :            :             RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::ImplRenderer::ImplRenderer(mtf)" );
    2953                 :            : 
    2954                 :            :             OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(),
    2955                 :            :                         "ImplRenderer::ImplRenderer(): Invalid canvas" );
    2956                 :            :             OSL_ENSURE( rCanvas->getUNOCanvas()->getDevice().is(),
    2957                 :            :                         "ImplRenderer::ImplRenderer(): Invalid graphic device" );
    2958                 :            : 
    2959                 :            :             // make sure canvas and graphic device are valid; action
    2960                 :            :             // creation don't check that every time
    2961   [ #  #  #  #  :          0 :             if( rCanvas.get() == NULL ||
           #  # ][ #  # ]
           [ #  #  #  #  
           #  # ][ #  # ]
    2962 [ #  # ][ #  # ]:          0 :                 !rCanvas->getUNOCanvas().is() ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2963 [ #  # ][ #  # ]:          0 :                 !rCanvas->getUNOCanvas()->getDevice().is() )
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
    2964                 :            :             {
    2965                 :            :                 // leave actions empty
    2966                 :          0 :                 return;
    2967                 :            :             }
    2968                 :            : 
    2969 [ #  # ][ #  # ]:          0 :             VectorOfOutDevStates    aStateStack;
    2970                 :            : 
    2971 [ #  # ][ #  # ]:          0 :             VirtualDevice aVDev;
    2972 [ #  # ][ #  # ]:          0 :             aVDev.EnableOutput( sal_False );
    2973                 :            : 
    2974                 :            :             // Setup VDev for state tracking and mapping
    2975                 :            :             // =========================================
    2976                 :            : 
    2977 [ #  # ][ #  # ]:          0 :             aVDev.SetMapMode( rMtf.GetPrefMapMode() );
    2978                 :            : 
    2979                 :          0 :             const Size aMtfSize( rMtf.GetPrefSize() );
    2980                 :            :             const Size aMtfSizePixPre( aVDev.LogicToPixel( aMtfSize,
    2981   [ #  #  #  # ]:          0 :                                                            rMtf.GetPrefMapMode() ) );
    2982                 :            : 
    2983                 :            :             // #i44110# correct null-sized output - there are shapes
    2984                 :            :             // which have zero size in at least one dimension
    2985 [ #  # ][ #  # ]:          0 :             const Size aMtfSizePix( ::std::max( aMtfSizePixPre.Width(), 1L ),
    2986 [ #  # ][ #  # ]:          0 :                                     ::std::max( aMtfSizePixPre.Height(), 1L ) );
    2987                 :            : 
    2988                 :          0 :             sal_Int32 nCurrActions(0);
    2989                 :            :             ActionFactoryParameters aParms(aStateStack,
    2990                 :            :                                            rCanvas,
    2991                 :            :                                            aVDev,
    2992                 :            :                                            rParams,
    2993                 :          0 :                                            nCurrActions );
    2994                 :            : 
    2995                 :            :             // init state stack
    2996   [ #  #  #  # ]:          0 :             aStateStack.clearStateStack();
    2997                 :            : 
    2998                 :            :             // Setup local state, such that the metafile renders
    2999                 :            :             // itself into a one-by-one square at the origin for
    3000                 :            :             // identity view and render transformations
    3001   [ #  #  #  # ]:          0 :             aStateStack.getState().transform.scale( 1.0 / aMtfSizePix.Width(),
    3002 [ #  # ][ #  # ]:          0 :                                                      1.0 / aMtfSizePix.Height() );
    3003                 :            : 
    3004 [ #  # ][ #  # ]:          0 :             tools::calcLogic2PixelAffineTransform( aStateStack.getState().mapModeTransform,
    3005 [ #  # ][ #  # ]:          0 :                                                    aVDev );
    3006                 :            : 
    3007 [ #  # ][ #  # ]:          0 :             ColorSharedPtr pColor( getCanvas()->createColor() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3008                 :            : 
    3009                 :            :             {
    3010 [ #  # ][ #  # ]:          0 :                 ::cppcanvas::internal::OutDevState& rState = aStateStack.getState();
    3011                 :            :                 // setup default text color to black
    3012                 :            :                 rState.textColor =
    3013                 :            :                     rState.textFillColor =
    3014 [ #  # ][ #  # ]:          0 :                     rState.textLineColor = pColor->getDeviceColor( 0x000000FF );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3015                 :            :             }
    3016                 :            : 
    3017                 :            :             // apply overrides from the Parameters struct
    3018 [ #  # ][ #  # ]:          0 :             if( rParams.maFillColor.is_initialized() )
    3019                 :            :             {
    3020 [ #  # ][ #  # ]:          0 :                 ::cppcanvas::internal::OutDevState& rState = aStateStack.getState();
    3021                 :          0 :                 rState.isFillColorSet = true;
    3022 [ #  # ][ #  # ]:          0 :                 rState.fillColor = pColor->getDeviceColor( *rParams.maFillColor );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3023                 :            :             }
    3024 [ #  # ][ #  # ]:          0 :             if( rParams.maLineColor.is_initialized() )
    3025                 :            :             {
    3026 [ #  # ][ #  # ]:          0 :                 ::cppcanvas::internal::OutDevState& rState = aStateStack.getState();
    3027                 :          0 :                 rState.isLineColorSet = true;
    3028 [ #  # ][ #  # ]:          0 :                 rState.lineColor = pColor->getDeviceColor( *rParams.maLineColor );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3029                 :            :             }
    3030 [ #  # ][ #  # ]:          0 :             if( rParams.maTextColor.is_initialized() )
    3031                 :            :             {
    3032 [ #  # ][ #  # ]:          0 :                 ::cppcanvas::internal::OutDevState& rState = aStateStack.getState();
    3033                 :          0 :                 rState.isTextFillColorSet = true;
    3034                 :          0 :                 rState.isTextLineColorSet = true;
    3035                 :            :                 rState.textColor =
    3036                 :            :                     rState.textFillColor =
    3037 [ #  # ][ #  # ]:          0 :                     rState.textLineColor = pColor->getDeviceColor( *rParams.maTextColor );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3038                 :            :             }
    3039   [ #  #  #  #  :          0 :             if( rParams.maFontName.is_initialized() ||
          #  #  #  #  #  
              # ][ #  # ]
           [ #  #  #  #  
          #  #  #  #  #  
              # ][ #  # ]
    3040                 :          0 :                 rParams.maFontWeight.is_initialized() ||
    3041                 :          0 :                 rParams.maFontLetterForm.is_initialized() ||
    3042                 :          0 :                 rParams.maFontUnderline.is_initialized() ||
    3043                 :          0 :                 rParams.maFontProportion.is_initialized() )
    3044                 :            :             {
    3045 [ #  # ][ #  # ]:          0 :                 ::cppcanvas::internal::OutDevState& rState = aStateStack.getState();
    3046                 :            : 
    3047                 :            :                 rState.xFont = createFont( rState.fontRotation,
    3048                 :            :                                            ::Font(), // default font
    3049 [ #  # ][ #  # ]:          0 :                                            aParms );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3050                 :            :             }
    3051                 :            : 
    3052                 :            :             /* EMF+ */
    3053                 :          0 :             memset (aObjects, 0, sizeof (aObjects));
    3054                 :          0 :             mbMultipart = false;
    3055                 :            : 
    3056                 :            :             createActions( const_cast<GDIMetaFile&>(rMtf), // HACK(Q2):
    3057                 :            :                                                            // we're
    3058                 :            :                                                            // changing
    3059                 :            :                                                               // the
    3060                 :            :                                                               // current
    3061                 :            :                                                               // action
    3062                 :            :                                                               // in
    3063                 :            :                                                               // createActions!
    3064                 :            :                            aParms,
    3065                 :            :                            true // TODO(P1): make subsettability configurable
    3066 [ #  # ][ #  # ]:          0 :                             );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3067                 :            :         }
    3068                 :            : 
    3069 [ #  # ][ #  # ]:          0 :         ImplRenderer::~ImplRenderer()
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3070                 :            :         {
    3071 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
    3072                 :            : 
    3073                 :          0 :         bool ImplRenderer::drawSubset( sal_Int32    nStartIndex,
    3074                 :            :                                        sal_Int32    nEndIndex ) const
    3075                 :            :         {
    3076                 :            :             RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::ImplRenderer::drawSubset()" );
    3077                 :            : 
    3078                 :          0 :             ActionVector::const_iterator aRangeBegin;
    3079                 :          0 :             ActionVector::const_iterator aRangeEnd;
    3080                 :            : 
    3081                 :            :             try
    3082                 :            :             {
    3083         [ #  # ]:          0 :                 if( !getSubsetIndices( nStartIndex, nEndIndex,
    3084         [ #  # ]:          0 :                                        aRangeBegin, aRangeEnd ) )
    3085                 :          0 :                     return true; // nothing to render (but _that_ was successful)
    3086                 :            : 
    3087                 :            :                 // now, aRangeBegin references the action in which the
    3088                 :            :                 // subset rendering must start, and aRangeEnd references
    3089                 :            :                 // the action in which the subset rendering must end (it
    3090                 :            :                 // might also end right at the start of the referenced
    3091                 :            :                 // action, such that zero of that action needs to be
    3092                 :            :                 // rendered).
    3093                 :            : 
    3094                 :            : 
    3095                 :            :                 // render subset of actions
    3096                 :            :                 // ========================
    3097                 :            : 
    3098         [ #  # ]:          0 :                 ::basegfx::B2DHomMatrix aMatrix;
    3099                 :            :                 ::canvas::tools::getRenderStateTransform( aMatrix,
    3100 [ #  # ][ #  # ]:          0 :                                                           getRenderState() );
    3101                 :            : 
    3102         [ #  # ]:          0 :                 ActionRenderer aRenderer( aMatrix );
    3103                 :            : 
    3104                 :            :                 return forSubsetRange( aRenderer,
    3105                 :            :                                        aRangeBegin,
    3106                 :            :                                        aRangeEnd,
    3107                 :            :                                        nStartIndex,
    3108                 :            :                                        nEndIndex,
    3109 [ #  # ][ #  # ]:          0 :                                        maActions.end() );
         [ #  # ][ #  # ]
    3110                 :            :             }
    3111         [ #  # ]:          0 :             catch( uno::Exception& )
    3112                 :            :             {
    3113                 :            :                 OSL_FAIL( rtl::OUStringToOString(
    3114                 :            :                                 comphelper::anyToString( cppu::getCaughtException() ),
    3115                 :            :                                 RTL_TEXTENCODING_UTF8 ).getStr() );
    3116                 :            : 
    3117                 :            :                 // convert error to return value
    3118                 :          0 :                 return false;
    3119                 :            :             }
    3120                 :            :         }
    3121                 :            : 
    3122                 :          0 :         ::basegfx::B2DRange ImplRenderer::getSubsetArea( sal_Int32  nStartIndex,
    3123                 :            :                                                          sal_Int32  nEndIndex ) const
    3124                 :            :         {
    3125                 :            :             RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::ImplRenderer::getSubsetArea()" );
    3126                 :            : 
    3127                 :          0 :             ActionVector::const_iterator aRangeBegin;
    3128                 :          0 :             ActionVector::const_iterator aRangeEnd;
    3129                 :            : 
    3130         [ #  # ]:          0 :             if( !getSubsetIndices( nStartIndex, nEndIndex,
    3131         [ #  # ]:          0 :                                    aRangeBegin, aRangeEnd ) )
    3132         [ #  # ]:          0 :                 return ::basegfx::B2DRange(); // nothing to render -> empty range
    3133                 :            : 
    3134                 :            :             // now, aRangeBegin references the action in which the
    3135                 :            :             // subset querying must start, and aRangeEnd references
    3136                 :            :             // the action in which the subset querying must end (it
    3137                 :            :             // might also end right at the start of the referenced
    3138                 :            :             // action, such that zero of that action needs to be
    3139                 :            :             // queried).
    3140                 :            : 
    3141                 :            : 
    3142                 :            :             // query bounds for subset of actions
    3143                 :            :             // ==================================
    3144                 :            : 
    3145         [ #  # ]:          0 :             ::basegfx::B2DHomMatrix aMatrix;
    3146                 :            :             ::canvas::tools::getRenderStateTransform( aMatrix,
    3147 [ #  # ][ #  # ]:          0 :                                                       getRenderState() );
    3148                 :            : 
    3149         [ #  # ]:          0 :             AreaQuery aQuery( aMatrix );
    3150                 :            :             forSubsetRange( aQuery,
    3151                 :            :                             aRangeBegin,
    3152                 :            :                             aRangeEnd,
    3153                 :            :                             nStartIndex,
    3154                 :            :                             nEndIndex,
    3155         [ #  # ]:          0 :                             maActions.end() );
    3156                 :            : 
    3157 [ #  # ][ #  # ]:          0 :             return aQuery.getBounds();
    3158                 :            :         }
    3159                 :            : 
    3160                 :          0 :         bool ImplRenderer::draw() const
    3161                 :            :         {
    3162                 :            :             RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::ImplRenderer::draw()" );
    3163                 :            : 
    3164         [ #  # ]:          0 :             ::basegfx::B2DHomMatrix aMatrix;
    3165                 :            :             ::canvas::tools::getRenderStateTransform( aMatrix,
    3166 [ #  # ][ #  # ]:          0 :                                                       getRenderState() );
    3167                 :            : 
    3168                 :            :             try
    3169                 :            :             {
    3170 [ #  # ][ #  # ]:          0 :                 return ::std::for_each( maActions.begin(), maActions.end(), ActionRenderer( aMatrix ) ).result();
         [ #  # ][ #  # ]
                 [ #  # ]
    3171                 :            :             }
    3172         [ #  # ]:          0 :             catch( uno::Exception& )
    3173                 :            :             {
    3174                 :            :                 OSL_FAIL( rtl::OUStringToOString(
    3175                 :            :                                 comphelper::anyToString( cppu::getCaughtException() ),
    3176                 :            :                                 RTL_TEXTENCODING_UTF8 ).getStr() );
    3177                 :            : 
    3178                 :          0 :                 return false;
    3179         [ #  # ]:          0 :             }
    3180                 :            :         }
    3181                 :            :     }
    3182                 :            : }
    3183                 :            : 
    3184                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10