LCOV - code coverage report
Current view: top level - drawinglayer/source/processor2d - vclmetafileprocessor2d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 278 708 39.3 %
Date: 2012-08-25 Functions: 13 16 81.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 331 1591 20.8 %

           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                 :            : #include <drawinglayer/processor2d/vclmetafileprocessor2d.hxx>
      30                 :            : #include <tools/gen.hxx>
      31                 :            : #include <vcl/virdev.hxx>
      32                 :            : #include <vcl/gdimtf.hxx>
      33                 :            : #include <vcl/gradient.hxx>
      34                 :            : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
      35                 :            : #include <drawinglayer/primitive2d/textprimitive2d.hxx>
      36                 :            : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
      37                 :            : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
      38                 :            : #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
      39                 :            : #include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
      40                 :            : #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
      41                 :            : #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
      42                 :            : #include <basegfx/polygon/b2dpolygonclipper.hxx>
      43                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      44                 :            : #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
      45                 :            : #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
      46                 :            : #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
      47                 :            : #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
      48                 :            : #include <drawinglayer/processor2d/vclpixelprocessor2d.hxx>
      49                 :            : #include <tools/stream.hxx>
      50                 :            : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
      51                 :            : #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
      52                 :            : #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
      53                 :            : #include <vcl/graphictools.hxx>
      54                 :            : #include <vcl/metaact.hxx>
      55                 :            : #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
      56                 :            : #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
      57                 :            : #include <comphelper/processfactory.hxx>
      58                 :            : #include <rtl/ustring.hxx>
      59                 :            : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
      60                 :            : #include <com/sun/star/i18n/WordType.hpp>
      61                 :            : #include <drawinglayer/primitive2d/controlprimitive2d.hxx>
      62                 :            : #include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
      63                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      64                 :            : #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
      65                 :            : #include <helperchartrenderer.hxx>
      66                 :            : #include <drawinglayer/primitive2d/epsprimitive2d.hxx>
      67                 :            : #include <basegfx/polygon/b2dlinegeometry.hxx>
      68                 :            : 
      69                 :            : //////////////////////////////////////////////////////////////////////////////
      70                 :            : // for PDFExtOutDevData Graphic support
      71                 :            : 
      72                 :            : #include <vcl/graph.hxx>
      73                 :            : #include <vcl/svapp.hxx>
      74                 :            : #include <toolkit/helper/formpdfexport.hxx>
      75                 :            : 
      76                 :            : //////////////////////////////////////////////////////////////////////////////
      77                 :            : // for Control printing
      78                 :            : 
      79                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      80                 :            : 
      81                 :            : //////////////////////////////////////////////////////////////////////////////
      82                 :            : // for current chart PrettyPrinting support
      83                 :            : 
      84                 :            : #include <drawinglayer/primitive2d/chartprimitive2d.hxx>
      85                 :            : 
      86                 :            : //////////////////////////////////////////////////////////////////////////////
      87                 :            : // for StructureTagPrimitive support in sd's unomodel.cxx
      88                 :            : 
      89                 :            : #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
      90                 :            : 
      91                 :            : //////////////////////////////////////////////////////////////////////////////
      92                 :            : 
      93                 :            : using namespace com::sun::star;
      94                 :            : 
      95                 :            : //////////////////////////////////////////////////////////////////////////////
      96                 :            : // #112245# definition for maximum allowed point count due to Metafile target.
      97                 :            : // To be on the safe side with the old tools polygon, use slightly less then
      98                 :            : // the theoretical maximum (bad experiences with tools polygon)
      99                 :            : 
     100                 :            : #define MAX_POLYGON_POINT_COUNT_METAFILE    (0x0000fff0)
     101                 :            : 
     102                 :            : //////////////////////////////////////////////////////////////////////////////
     103                 :            : 
     104                 :            : namespace
     105                 :            : {
     106                 :            :     // #112245# helper to split line polygon in half
     107                 :          0 :     void splitLinePolygon(
     108                 :            :         const basegfx::B2DPolygon& rBasePolygon,
     109                 :            :         basegfx::B2DPolygon& o_aLeft,
     110                 :            :         basegfx::B2DPolygon& o_aRight)
     111                 :            :     {
     112                 :          0 :         const sal_uInt32 nCount(rBasePolygon.count());
     113                 :            : 
     114         [ #  # ]:          0 :         if(nCount)
     115                 :            :         {
     116                 :          0 :             const sal_uInt32 nHalfCount((nCount - 1) >> 1);
     117                 :            : 
     118         [ #  # ]:          0 :             o_aLeft = basegfx::B2DPolygon(rBasePolygon, 0, nHalfCount + 1);
     119                 :          0 :             o_aLeft.setClosed(false);
     120                 :            : 
     121         [ #  # ]:          0 :             o_aRight = basegfx::B2DPolygon(rBasePolygon, nHalfCount, nCount - nHalfCount);
     122                 :          0 :             o_aRight.setClosed(false);
     123                 :            : 
     124         [ #  # ]:          0 :             if(rBasePolygon.isClosed())
     125                 :            :             {
     126         [ #  # ]:          0 :                 o_aRight.append(rBasePolygon.getB2DPoint(0));
     127                 :            : 
     128         [ #  # ]:          0 :                 if(rBasePolygon.areControlPointsUsed())
     129                 :            :                 {
     130                 :            :                     o_aRight.setControlPoints(
     131         [ #  # ]:          0 :                         o_aRight.count() - 1,
     132                 :            :                         rBasePolygon.getPrevControlPoint(0),
     133 [ #  # ][ #  # ]:          0 :                         rBasePolygon.getNextControlPoint(0));
     134                 :            :                 }
     135                 :            :             }
     136                 :            :         }
     137                 :            :         else
     138                 :            :         {
     139                 :          0 :             o_aLeft.clear();
     140                 :          0 :             o_aRight.clear();
     141                 :            :         }
     142                 :          0 :     }
     143                 :            : 
     144                 :            :     // #112245# helper to evtl. split filled polygons to maximum metafile point count
     145                 :       1195 :     bool fillPolyPolygonNeededToBeSplit(basegfx::B2DPolyPolygon& rPolyPolygon)
     146                 :            :     {
     147                 :       1195 :         bool bRetval(false);
     148                 :       1195 :         const sal_uInt32 nPolyCount(rPolyPolygon.count());
     149                 :            : 
     150         [ +  - ]:       1195 :         if(nPolyCount)
     151                 :            :         {
     152         [ +  - ]:       1195 :             basegfx::B2DPolyPolygon aSplitted;
     153                 :            : 
     154         [ +  + ]:       2390 :             for(sal_uInt32 a(0); a < nPolyCount; a++)
     155                 :            :             {
     156         [ +  - ]:       1195 :                 const basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(a));
     157         [ +  - ]:       1195 :                 const sal_uInt32 nPointCount(aCandidate.count());
     158                 :       1195 :                 bool bNeedToSplit(false);
     159                 :            : 
     160 [ +  - ][ -  + ]:       1195 :                 if(aCandidate.areControlPointsUsed())
     161                 :            :                 {
     162                 :            :                     // compare with the maximum for bezier curved polygons
     163                 :          0 :                     bNeedToSplit = nPointCount > ((MAX_POLYGON_POINT_COUNT_METAFILE / 3L) - 1L);
     164                 :            :                 }
     165                 :            :                 else
     166                 :            :                 {
     167                 :            :                     // compare with the maximum for simple point polygons
     168                 :       1195 :                     bNeedToSplit = nPointCount > (MAX_POLYGON_POINT_COUNT_METAFILE - 1);
     169                 :            :                 }
     170                 :            : 
     171         [ -  + ]:       1195 :                 if(bNeedToSplit)
     172                 :            :                 {
     173                 :            :                     // need to split the partial polygon
     174         [ #  # ]:          0 :                     const basegfx::B2DRange aRange(aCandidate.getB2DRange());
     175         [ #  # ]:          0 :                     const basegfx::B2DPoint aCenter(aRange.getCenter());
     176                 :            : 
     177 [ #  # ][ #  # ]:          0 :                     if(aRange.getWidth() > aRange.getHeight())
                 [ #  # ]
     178                 :            :                     {
     179                 :            :                         // clip in left and right
     180                 :            :                         const basegfx::B2DPolyPolygon aLeft(
     181                 :            :                             basegfx::tools::clipPolygonOnParallelAxis(
     182                 :            :                                 aCandidate,
     183                 :            :                                 false,
     184                 :            :                                 true,
     185                 :            :                                 aCenter.getX(),
     186         [ #  # ]:          0 :                                 false));
     187                 :            :                         const basegfx::B2DPolyPolygon aRight(
     188                 :            :                             basegfx::tools::clipPolygonOnParallelAxis(
     189                 :            :                                 aCandidate,
     190                 :            :                                 false,
     191                 :            :                                 false,
     192                 :            :                                 aCenter.getX(),
     193         [ #  # ]:          0 :                                 false));
     194                 :            : 
     195         [ #  # ]:          0 :                         aSplitted.append(aLeft);
     196 [ #  # ][ #  # ]:          0 :                         aSplitted.append(aRight);
                 [ #  # ]
     197                 :            :                     }
     198                 :            :                     else
     199                 :            :                     {
     200                 :            :                         // clip in top and bottom
     201                 :            :                         const basegfx::B2DPolyPolygon aTop(
     202                 :            :                             basegfx::tools::clipPolygonOnParallelAxis(
     203                 :            :                                 aCandidate,
     204                 :            :                                 true,
     205                 :            :                                 true,
     206                 :            :                                 aCenter.getY(),
     207         [ #  # ]:          0 :                                 false));
     208                 :            :                         const basegfx::B2DPolyPolygon aBottom(
     209                 :            :                             basegfx::tools::clipPolygonOnParallelAxis(
     210                 :            :                                 aCandidate,
     211                 :            :                                 true,
     212                 :            :                                 false,
     213                 :            :                                 aCenter.getY(),
     214         [ #  # ]:          0 :                                 false));
     215                 :            : 
     216         [ #  # ]:          0 :                         aSplitted.append(aTop);
     217 [ #  # ][ #  # ]:          0 :                         aSplitted.append(aBottom);
                 [ #  # ]
     218                 :          0 :                     }
     219                 :            :                 }
     220                 :            :                 else
     221                 :            :                 {
     222         [ +  - ]:       1195 :                     aSplitted.append(aCandidate);
     223                 :            :                 }
     224         [ +  - ]:       1195 :             }
     225                 :            : 
     226 [ +  - ][ -  + ]:       1195 :             if(aSplitted.count() != nPolyCount)
     227                 :            :             {
     228         [ #  # ]:          0 :                 rPolyPolygon = aSplitted;
     229         [ +  - ]:       1195 :             }
     230                 :            :         }
     231                 :            : 
     232                 :       1195 :         return bRetval;
     233                 :            :     }
     234                 :            : 
     235                 :            :     /** Filter input polypolygon for effectively empty sub-fills
     236                 :            : 
     237                 :            :         Needed to fix fdo#37559
     238                 :            : 
     239                 :            :         @param rPoly
     240                 :            :         PolyPolygon to filter
     241                 :            : 
     242                 :            :         @return converted tools PolyPolygon, w/o one-point fills
     243                 :            :      */
     244                 :       1195 :     PolyPolygon getFillPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly )
     245                 :            :     {
     246                 :            :         // filter input rPoly
     247         [ +  - ]:       1195 :         basegfx::B2DPolyPolygon aPoly;
     248         [ +  - ]:       1195 :         sal_uInt32 nCount(rPoly.count());
     249         [ +  + ]:       2390 :         for( sal_uInt32 i=0; i<nCount; ++i )
     250                 :            :         {
     251         [ +  - ]:       1195 :             basegfx::B2DPolygon aCandidate(rPoly.getB2DPolygon(i));
     252 [ +  - ][ +  - ]:       1195 :             if( !aCandidate.isClosed() || aCandidate.count() > 1 )
         [ +  - ][ +  - ]
                 [ +  - ]
     253         [ +  - ]:       1195 :                 aPoly.append(aCandidate);
     254         [ +  - ]:       1195 :         }
     255 [ +  - ][ +  - ]:       1195 :         return PolyPolygon(aPoly);
     256                 :            :     }
     257                 :            : 
     258                 :            : } // end of anonymous namespace
     259                 :            : 
     260                 :            : //////////////////////////////////////////////////////////////////////////////
     261                 :            : 
     262                 :            : namespace drawinglayer
     263                 :            : {
     264                 :            :     namespace processor2d
     265                 :            :     {
     266                 :          0 :         Rectangle VclMetafileProcessor2D::impDumpToMetaFile(
     267                 :            :             const primitive2d::Primitive2DSequence& rContent,
     268                 :            :             GDIMetaFile& o_rContentMetafile)
     269                 :            :         {
     270                 :            :             // Prepare VDev, MetaFile and connections
     271                 :          0 :             OutputDevice* pLastOutputDevice = mpOutputDevice;
     272                 :          0 :             GDIMetaFile* pLastMetafile = mpMetaFile;
     273         [ #  # ]:          0 :             basegfx::B2DRange aPrimitiveRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D()));
     274                 :            : 
     275                 :            :             // transform primitive range with current transformation (e.g shadow offset)
     276         [ #  # ]:          0 :             aPrimitiveRange.transform(maCurrentTransformation);
     277                 :            : 
     278                 :            :             const Rectangle aPrimitiveRectangle(
     279                 :            :                 basegfx::fround(aPrimitiveRange.getMinX()), basegfx::fround(aPrimitiveRange.getMinY()),
     280 [ #  # ][ #  # ]:          0 :                 basegfx::fround(aPrimitiveRange.getMaxX()), basegfx::fround(aPrimitiveRange.getMaxY()));
         [ #  # ][ #  # ]
                 [ #  # ]
     281         [ #  # ]:          0 :             VirtualDevice aContentVDev;
     282         [ #  # ]:          0 :             MapMode aNewMapMode(pLastOutputDevice->GetMapMode());
     283                 :            : 
     284                 :          0 :             mpOutputDevice = &aContentVDev;
     285                 :          0 :             mpMetaFile = &o_rContentMetafile;
     286         [ #  # ]:          0 :             aContentVDev.EnableOutput(false);
     287         [ #  # ]:          0 :             aContentVDev.SetMapMode(pLastOutputDevice->GetMapMode());
     288         [ #  # ]:          0 :             o_rContentMetafile.Record(&aContentVDev);
     289         [ #  # ]:          0 :             aContentVDev.SetLineColor(pLastOutputDevice->GetLineColor());
     290         [ #  # ]:          0 :             aContentVDev.SetFillColor(pLastOutputDevice->GetFillColor());
     291         [ #  # ]:          0 :             aContentVDev.SetFont(pLastOutputDevice->GetFont());
     292         [ #  # ]:          0 :             aContentVDev.SetDrawMode(pLastOutputDevice->GetDrawMode());
     293         [ #  # ]:          0 :             aContentVDev.SetSettings(pLastOutputDevice->GetSettings());
     294         [ #  # ]:          0 :             aContentVDev.SetRefPoint(pLastOutputDevice->GetRefPoint());
     295                 :            : 
     296                 :            :             // dump to MetaFile
     297         [ #  # ]:          0 :             process(rContent);
     298                 :            : 
     299                 :            :             // cleanups
     300         [ #  # ]:          0 :             o_rContentMetafile.Stop();
     301         [ #  # ]:          0 :             o_rContentMetafile.WindStart();
     302         [ #  # ]:          0 :             aNewMapMode.SetOrigin(aPrimitiveRectangle.TopLeft());
     303         [ #  # ]:          0 :             o_rContentMetafile.SetPrefMapMode(aNewMapMode);
     304         [ #  # ]:          0 :             o_rContentMetafile.SetPrefSize(aPrimitiveRectangle.GetSize());
     305                 :          0 :             mpOutputDevice = pLastOutputDevice;
     306                 :          0 :             mpMetaFile = pLastMetafile;
     307                 :            : 
     308 [ #  # ][ #  # ]:          0 :             return aPrimitiveRectangle;
     309                 :            :         }
     310                 :            : 
     311                 :          0 :         void VclMetafileProcessor2D::impConvertFillGradientAttributeToVCLGradient(
     312                 :            :             Gradient& o_rVCLGradient,
     313                 :            :             const attribute::FillGradientAttribute& rFiGrAtt,
     314                 :            :             bool bIsTransparenceGradient)
     315                 :            :         {
     316         [ #  # ]:          0 :             if(bIsTransparenceGradient)
     317                 :            :             {
     318                 :            :                 // it's about transparence channel intensities (black/white), do not use color modifier
     319         [ #  # ]:          0 :                 o_rVCLGradient.SetStartColor(Color(rFiGrAtt.getStartColor()));
     320         [ #  # ]:          0 :                 o_rVCLGradient.SetEndColor(Color(rFiGrAtt.getEndColor()));
     321                 :            :             }
     322                 :            :             else
     323                 :            :             {
     324                 :            :                 // use color modifier to influence start/end color of gradient
     325         [ #  # ]:          0 :                 o_rVCLGradient.SetStartColor(Color(maBColorModifierStack.getModifiedColor(rFiGrAtt.getStartColor())));
     326         [ #  # ]:          0 :                 o_rVCLGradient.SetEndColor(Color(maBColorModifierStack.getModifiedColor(rFiGrAtt.getEndColor())));
     327                 :            :             }
     328                 :            : 
     329                 :          0 :             o_rVCLGradient.SetAngle(static_cast< sal_uInt16 >(rFiGrAtt.getAngle() * (1.0 / F_PI1800)));
     330                 :          0 :             o_rVCLGradient.SetBorder(static_cast< sal_uInt16 >(rFiGrAtt.getBorder() * 100.0));
     331                 :          0 :             o_rVCLGradient.SetOfsX(static_cast< sal_uInt16 >(rFiGrAtt.getOffsetX() * 100.0));
     332                 :          0 :             o_rVCLGradient.SetOfsY(static_cast< sal_uInt16 >(rFiGrAtt.getOffsetY() * 100.0));
     333                 :          0 :             o_rVCLGradient.SetSteps(rFiGrAtt.getSteps());
     334                 :            : 
     335                 :            :             // defaults for intensity; those were computed into the start/end colors already
     336                 :          0 :             o_rVCLGradient.SetStartIntensity(100);
     337                 :          0 :             o_rVCLGradient.SetEndIntensity(100);
     338                 :            : 
     339   [ #  #  #  #  :          0 :             switch(rFiGrAtt.getStyle())
                   #  # ]
     340                 :            :             {
     341                 :            :                 default : // attribute::GRADIENTSTYLE_LINEAR :
     342                 :            :                 {
     343                 :          0 :                     o_rVCLGradient.SetStyle(GradientStyle_LINEAR);
     344                 :          0 :                     break;
     345                 :            :                 }
     346                 :            :                 case attribute::GRADIENTSTYLE_AXIAL :
     347                 :            :                 {
     348                 :          0 :                     o_rVCLGradient.SetStyle(GradientStyle_AXIAL);
     349                 :          0 :                     break;
     350                 :            :                 }
     351                 :            :                 case attribute::GRADIENTSTYLE_RADIAL :
     352                 :            :                 {
     353                 :          0 :                     o_rVCLGradient.SetStyle(GradientStyle_RADIAL);
     354                 :          0 :                     break;
     355                 :            :                 }
     356                 :            :                 case attribute::GRADIENTSTYLE_ELLIPTICAL :
     357                 :            :                 {
     358                 :          0 :                     o_rVCLGradient.SetStyle(GradientStyle_ELLIPTICAL);
     359                 :          0 :                     break;
     360                 :            :                 }
     361                 :            :                 case attribute::GRADIENTSTYLE_SQUARE :
     362                 :            :                 {
     363                 :          0 :                     o_rVCLGradient.SetStyle(GradientStyle_SQUARE);
     364                 :          0 :                     break;
     365                 :            :                 }
     366                 :            :                 case attribute::GRADIENTSTYLE_RECT :
     367                 :            :                 {
     368                 :          0 :                     o_rVCLGradient.SetStyle(GradientStyle_RECT);
     369                 :          0 :                     break;
     370                 :            :                 }
     371                 :            :             }
     372                 :          0 :         }
     373                 :            : 
     374                 :       1195 :         void VclMetafileProcessor2D::impStartSvtGraphicFill(SvtGraphicFill* pSvtGraphicFill)
     375                 :            :         {
     376 [ +  - ][ +  - ]:       1195 :             if(pSvtGraphicFill && !mnSvtGraphicFillCount)
     377                 :            :             {
     378         [ +  - ]:       1195 :                 SvMemoryStream aMemStm;
     379                 :            : 
     380         [ +  - ]:       1195 :                 aMemStm << *pSvtGraphicFill;
     381 [ +  - ][ +  - ]:       1195 :                 mpMetaFile->AddAction(new MetaCommentAction("XPATHFILL_SEQ_BEGIN", 0, static_cast< const sal_uInt8* >(aMemStm.GetData()), aMemStm.Seek(STREAM_SEEK_TO_END)));
         [ +  - ][ +  - ]
                 [ +  - ]
     382         [ +  - ]:       1195 :                 mnSvtGraphicFillCount++;
     383                 :            :             }
     384                 :       1195 :         }
     385                 :            : 
     386                 :       1195 :         void VclMetafileProcessor2D::impEndSvtGraphicFill(SvtGraphicFill* pSvtGraphicFill)
     387                 :            :         {
     388 [ +  - ][ +  - ]:       1195 :             if(pSvtGraphicFill && mnSvtGraphicFillCount)
     389                 :            :             {
     390                 :       1195 :                 mnSvtGraphicFillCount--;
     391 [ +  - ][ +  - ]:       1195 :                 mpMetaFile->AddAction(new MetaCommentAction("XPATHFILL_SEQ_END"));
                 [ +  - ]
     392         [ +  - ]:       1195 :                 delete pSvtGraphicFill;
     393                 :            :             }
     394                 :       1195 :         }
     395                 :            : 
     396                 :      11246 :         SvtGraphicStroke* VclMetafileProcessor2D::impTryToCreateSvtGraphicStroke(
     397                 :            :             const basegfx::B2DPolygon& rB2DPolygon,
     398                 :            :             const basegfx::BColor* pColor,
     399                 :            :             const attribute::LineAttribute* pLineAttribute,
     400                 :            :             const attribute::StrokeAttribute* pStrokeAttribute,
     401                 :            :             const attribute::LineStartEndAttribute* pStart,
     402                 :            :             const attribute::LineStartEndAttribute* pEnd)
     403                 :            :         {
     404                 :      11246 :             SvtGraphicStroke* pRetval = 0;
     405                 :            : 
     406 [ +  - ][ +  + ]:      11246 :             if(rB2DPolygon.count() && !mnSvtGraphicStrokeCount)
                 [ +  + ]
     407                 :            :             {
     408                 :       4735 :                 basegfx::BColor aStrokeColor;
     409         [ +  - ]:       4735 :                 basegfx::B2DPolyPolygon aStartArrow;
     410         [ +  - ]:       4735 :                 basegfx::B2DPolyPolygon aEndArrow;
     411                 :            : 
     412         [ -  + ]:       4735 :                 if(pColor)
     413                 :            :                 {
     414         [ #  # ]:          0 :                     aStrokeColor = *pColor;
     415                 :            :                 }
     416         [ +  - ]:       4735 :                 else if(pLineAttribute)
     417                 :            :                 {
     418 [ +  - ][ +  - ]:       4735 :                     aStrokeColor = maBColorModifierStack.getModifiedColor(pLineAttribute->getColor());
                 [ +  - ]
     419                 :            :                 }
     420                 :            : 
     421                 :            :                 // It IS needed to record the stroke color at all in the metafile,
     422                 :            :                 // SvtGraphicStroke has NO entry for stroke color(!)
     423         [ +  - ]:       4735 :                 mpOutputDevice->SetLineColor(Color(aStrokeColor));
     424                 :            : 
     425 [ +  - ][ +  + ]:       4735 :                 if(!rB2DPolygon.isClosed())
     426                 :            :                 {
     427                 :       4440 :                     double fPolyLength(0.0);
     428                 :            : 
     429 [ +  + ][ +  - ]:       4440 :                     if(pStart && pStart->isActive())
         [ -  + ][ -  + ]
     430                 :            :                     {
     431         [ #  # ]:          0 :                         fPolyLength = basegfx::tools::getLength(rB2DPolygon);
     432                 :            : 
     433                 :            :                         aStartArrow = basegfx::tools::createAreaGeometryForLineStartEnd(
     434         [ #  # ]:          0 :                             rB2DPolygon, pStart->getB2DPolyPolygon(), true, pStart->getWidth(),
     435 [ #  # ][ #  # ]:          0 :                             fPolyLength, pStart->isCentered() ? 0.5 : 0.0, 0);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     436                 :            :                     }
     437                 :            : 
     438 [ +  + ][ +  - ]:       4440 :                     if(pEnd && pEnd->isActive())
         [ +  - ][ +  + ]
     439                 :            :                     {
     440         [ +  - ]:          3 :                         if(basegfx::fTools::equalZero(fPolyLength))
     441                 :            :                         {
     442         [ +  - ]:          3 :                             fPolyLength = basegfx::tools::getLength(rB2DPolygon);
     443                 :            :                         }
     444                 :            : 
     445                 :            :                         aEndArrow = basegfx::tools::createAreaGeometryForLineStartEnd(
     446         [ +  - ]:          3 :                             rB2DPolygon, pEnd->getB2DPolyPolygon(), false, pEnd->getWidth(),
     447 [ +  - ][ -  + ]:       4443 :                             fPolyLength, pEnd->isCentered() ? 0.5 : 0.0, 0);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     448                 :            :                     }
     449                 :            :                 }
     450                 :            : 
     451                 :       4735 :                 SvtGraphicStroke::JoinType eJoin(SvtGraphicStroke::joinNone);
     452                 :       4735 :                 double fLineWidth(0.0);
     453                 :       4735 :                 double fMiterLength(0.0);
     454         [ +  - ]:       4735 :                 SvtGraphicStroke::DashArray aDashArray;
     455                 :            : 
     456         [ +  - ]:       4735 :                 if(pLineAttribute)
     457                 :            :                 {
     458                 :            :                     // pre-fill fLineWidth
     459         [ +  - ]:       4735 :                     fLineWidth = pLineAttribute->getWidth();
     460                 :            : 
     461                 :            :                     // pre-fill fMiterLength
     462                 :       4735 :                     fMiterLength = fLineWidth;
     463                 :            : 
     464                 :            :                     // get Join
     465         [ +  - ]:       4735 :                     switch(pLineAttribute->getLineJoin())
           [ -  -  -  + ]
     466                 :            :                     {
     467                 :            :                         default : // basegfx::B2DLINEJOIN_NONE :
     468                 :            :                         {
     469                 :          0 :                             eJoin = SvtGraphicStroke::joinNone;
     470                 :          0 :                             break;
     471                 :            :                         }
     472                 :            :                         case basegfx::B2DLINEJOIN_BEVEL :
     473                 :            :                         {
     474                 :          0 :                             eJoin = SvtGraphicStroke::joinBevel;
     475                 :          0 :                             break;
     476                 :            :                         }
     477                 :            :                         case basegfx::B2DLINEJOIN_MIDDLE :
     478                 :            :                         case basegfx::B2DLINEJOIN_MITER :
     479                 :            :                         {
     480                 :          0 :                             eJoin = SvtGraphicStroke::joinMiter;
     481                 :            :                             // ATM 15 degrees is assumed
     482                 :          0 :                             fMiterLength /= rtl::math::sin(M_PI * (15.0 / 360.0));
     483                 :          0 :                             break;
     484                 :            :                         }
     485                 :            :                         case basegfx::B2DLINEJOIN_ROUND :
     486                 :            :                         {
     487                 :       4735 :                             eJoin = SvtGraphicStroke::joinRound;
     488                 :       4735 :                             break;
     489                 :            :                         }
     490                 :            :                     }
     491                 :            :                 }
     492                 :            : 
     493         [ +  - ]:       4735 :                 if(pStrokeAttribute)
     494                 :            :                 {
     495                 :            :                     // copy dash array
     496 [ +  - ][ +  - ]:       4735 :                     aDashArray = pStrokeAttribute->getDotDashArray();
     497                 :            :                 }
     498                 :            : 
     499                 :            :                 // #i101734# apply current object transformation to created geometry.
     500                 :            :                 // This is a partial fix. When a object transformation is used which
     501                 :            :                 // e.g. contains a scaleX != scaleY, an unproportional scaling would
     502                 :            :                 // have to be applied to the evtl. existing fat line. The current
     503                 :            :                 // concept of PDF export and SvtGraphicStroke usage does simply not
     504                 :            :                 // allow handling such definitions. The only clean way would be to
     505                 :            :                 // add the transformation to SvtGraphicStroke and to handle it there
     506         [ +  - ]:       4735 :                 basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
     507                 :            : 
     508         [ +  - ]:       4735 :                 aB2DPolygon.transform(maCurrentTransformation);
     509         [ +  - ]:       4735 :                 aStartArrow.transform(maCurrentTransformation);
     510         [ +  - ]:       4735 :                 aEndArrow.transform(maCurrentTransformation);
     511                 :            : 
     512                 :            :                 pRetval = new SvtGraphicStroke(
     513                 :            :                     Polygon(aB2DPolygon),
     514                 :            :                     PolyPolygon(aStartArrow),
     515                 :            :                     PolyPolygon(aEndArrow),
     516                 :            :                     mfCurrentUnifiedTransparence,
     517                 :            :                     fLineWidth,
     518                 :            :                     SvtGraphicStroke::capButt,
     519                 :            :                     eJoin,
     520                 :            :                     fMiterLength,
     521 [ +  - ][ +  - ]:       4735 :                     aDashArray);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     522                 :            :             }
     523                 :            : 
     524                 :      11246 :             return pRetval;
     525                 :            :         }
     526                 :            : 
     527                 :      11246 :         void VclMetafileProcessor2D::impStartSvtGraphicStroke(SvtGraphicStroke* pSvtGraphicStroke)
     528                 :            :         {
     529 [ +  + ][ +  - ]:      11246 :             if(pSvtGraphicStroke && !mnSvtGraphicStrokeCount)
     530                 :            :             {
     531         [ +  - ]:       4735 :                 SvMemoryStream aMemStm;
     532                 :            : 
     533         [ +  - ]:       4735 :                 aMemStm << *pSvtGraphicStroke;
     534 [ +  - ][ +  - ]:       4735 :                 mpMetaFile->AddAction(new MetaCommentAction("XPATHSTROKE_SEQ_BEGIN", 0, static_cast< const sal_uInt8* >(aMemStm.GetData()), aMemStm.Seek(STREAM_SEEK_TO_END)));
         [ +  - ][ +  - ]
                 [ +  - ]
     535         [ +  - ]:       4735 :                 mnSvtGraphicStrokeCount++;
     536                 :            :             }
     537                 :      11246 :         }
     538                 :            : 
     539                 :      11246 :         void VclMetafileProcessor2D::impEndSvtGraphicStroke(SvtGraphicStroke* pSvtGraphicStroke)
     540                 :            :         {
     541 [ +  + ][ +  - ]:      11246 :             if(pSvtGraphicStroke && mnSvtGraphicStrokeCount)
     542                 :            :             {
     543                 :       4735 :                 mnSvtGraphicStrokeCount--;
     544 [ +  - ][ +  - ]:       4735 :                 mpMetaFile->AddAction(new MetaCommentAction("XPATHSTROKE_SEQ_END"));
                 [ +  - ]
     545         [ +  - ]:       4735 :                 delete pSvtGraphicStroke;
     546                 :            :             }
     547                 :      11246 :         }
     548                 :            : 
     549                 :            :         // init static break iterator
     550                 :        245 :         uno::Reference< ::com::sun::star::i18n::XBreakIterator > VclMetafileProcessor2D::mxBreakIterator;
     551                 :            : 
     552                 :        145 :         VclMetafileProcessor2D::VclMetafileProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev)
     553                 :            :         :   VclProcessor2D(rViewInformation, rOutDev),
     554                 :        145 :             mpMetaFile(rOutDev.GetConnectMetaFile()),
     555                 :            :             mnSvtGraphicFillCount(0),
     556                 :            :             mnSvtGraphicStrokeCount(0),
     557                 :            :             mfCurrentUnifiedTransparence(0.0),
     558   [ +  -  +  - ]:        290 :             mpPDFExtOutDevData(dynamic_cast< vcl::PDFExtOutDevData* >(rOutDev.GetExtOutDevData()))
     559                 :            :         {
     560                 :            :             OSL_ENSURE(rOutDev.GetConnectMetaFile(), "VclMetafileProcessor2D: Used on OutDev which has no MetaFile Target (!)");
     561                 :            :             // draw to logic coordinates, do not initialize maCurrentTransformation to viewTransformation
     562                 :            :             // but only to ObjectTransformation. Do not change MapMode of destination.
     563 [ +  - ][ +  - ]:        145 :             maCurrentTransformation = rViewInformation.getObjectTransformation();
     564                 :        145 :         }
     565                 :            : 
     566         [ +  - ]:        145 :         VclMetafileProcessor2D::~VclMetafileProcessor2D()
     567                 :            :         {
     568                 :            :             // MapMode was not changed, no restore necessary
     569         [ -  + ]:        290 :         }
     570                 :            : 
     571                 :            :         /***********************************************************************************************
     572                 :            : 
     573                 :            :             Support of MetaCommentActions in the VclMetafileProcessor2D
     574                 :            :             Found MetaCommentActions and how they are supported:
     575                 :            : 
     576                 :            :             XGRAD_SEQ_BEGIN, XGRAD_SEQ_END:
     577                 :            : 
     578                 :            :             Used inside OutputDevice::DrawGradient to mark the start and end of a MetaGradientEx action.
     579                 :            :             It is used in various exporters/importers to have direct access to the gradient before it
     580                 :            :             is rendered by VCL (and thus fragmented to polygon color actions and others). On that base, e.g.
     581                 :            :             the Metafile to SdrObject import creates it's gradient objects.
     582                 :            :             Best (and safest) way to support it here is to use PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D,
     583                 :            :             map it back to the corresponding tools PolyPolygon and the Gradient and just call
     584                 :            :             OutputDevice::DrawGradient which creates the necessary compatible actions.
     585                 :            : 
     586                 :            :             XPATHFILL_SEQ_BEGIN, XPATHFILL_SEQ_END:
     587                 :            : 
     588                 :            :             Two producers, one is vcl/source/gdi/gdimtf.cxx, line 1273. There, it is transformed
     589                 :            :             inside GDIMetaFile::Rotate, nothing to take care of here.
     590                 :            :             The second producer is in graphics/svx/source/svdraw/impgrfll.cxx, line 374. This is used
     591                 :            :             with each incarnation of Imp_GraphicFill when a metafile is recorded, fillstyle is not
     592                 :            :             XFILL_NONE and not completely transparent. It creates a SvtGraphicFill and streams it
     593                 :            :             to the comment action. A closing end token is created in the destructor.
     594                 :            :             Usages of Imp_GraphicFill are in Do_Paint_Object-methods of SdrCircObj, SdrPathObj and
     595                 :            :             SdrRectObj.
     596                 :            :             The token users pick various actions from SvtGraphicFill, so it may need to be added for all kind
     597                 :            :             of filled objects, even simple colored polygons. It is added as extra information; the
     598                 :            :             Metafile actions between the two tokens are interpreted as output generated from those
     599                 :            :             fills. Thus, users have the choice to use the SvtGraphicFill info or the created output
     600                 :            :             actions.
     601                 :            :             Even for XFillTransparenceItem it is used, thus it may need to be supported in
     602                 :            :             UnifiedTransparencePrimitive2D, too, when interpreted as normally filled PolyPolygon.
     603                 :            :             Implemented for:
     604                 :            :                 PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D,
     605                 :            :                 PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D,
     606                 :            :                 PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D,
     607                 :            :                 PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D,
     608                 :            :                 and for PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D when detected unified transparence
     609                 :            : 
     610                 :            :             XPATHSTROKE_SEQ_BEGIN, XPATHSTROKE_SEQ_END:
     611                 :            : 
     612                 :            :             Similar to pathfill, but using SvtGraphicStroke instead. It also has two producers where one
     613                 :            :             is also the GDIMetaFile::Rotate. Another user is MetaCommentAction::Move which modifies the
     614                 :            :             contained path accordingly.
     615                 :            :             The other one is SdrObject::Imp_DrawLineGeometry. It's done when MetaFile is set at OutDev and
     616                 :            :             only when geometry is a single polygon (!). I see no reason for that; in the PS exporter this
     617                 :            :             would hinder to make use of PolyPolygon strokes. I will need to add support at:
     618                 :            :                 PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D
     619                 :            :                 PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D
     620                 :            :                 PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D
     621                 :            :             This can be done hierarchical, too.
     622                 :            :             Okay, base implementation done based on those three primitives.
     623                 :            : 
     624                 :            :             FIELD_SEQ_BEGIN, FIELD_SEQ_END
     625                 :            : 
     626                 :            :             Used from slideshow for URLs, created from diverse SvxField implementations inside
     627                 :            :             createBeginComment()/createEndComment(). createBeginComment() is used from editeng\impedit3.cxx
     628                 :            :             inside ImpEditEngine::Paint.
     629                 :            :             Created TextHierarchyFieldPrimitive2D and added needed infos there; it is an group primitive and wraps
     630                 :            :             text primitives (but is not limited to that). It contains the field type if special actions for the
     631                 :            :             support of FIELD_SEQ_BEGIN/END are needed; this is the case for Page and URL fields. If more is
     632                 :            :             needed, it may be supported there.
     633                 :            :             FIELD_SEQ_BEGIN;PageField
     634                 :            :             FIELD_SEQ_END
     635                 :            :             Okay, these are now completely supported by TextHierarchyFieldPrimitive2D. URL works, too.
     636                 :            : 
     637                 :            :             XTEXT
     638                 :            : 
     639                 :            :             XTEXT_EOC(i) end of character
     640                 :            :             XTEXT_EOW(i) end of word
     641                 :            :             XTEXT_EOS(i) end of sentence
     642                 :            : 
     643                 :            :             this three are with index and are created with the help of a i18n::XBreakIterator in
     644                 :            :             ImplDrawWithComments. Simplifying, moving out text painting, reworking to create some
     645                 :            :             data structure for holding those TEXT infos.
     646                 :            :             Supported directly by TextSimplePortionPrimitive2D with adding a Locale to the basic text
     647                 :            :             primitive. In the MetaFileRenderer, the creation is now done (see below). This has the advantage
     648                 :            :             that this creations do not need to be done for all paints all the time. This would be
     649                 :            :             expensive since the BreakIterator and it's usage is expensive and for each paint also the
     650                 :            :             whole character stops would need to be created.
     651                 :            :             Created only for TextDecoratedPortionPrimitive2D due to XTEXT_EOL and XTEXT_EOP (see below)
     652                 :            : 
     653                 :            :             XTEXT_EOL() end of line
     654                 :            :             XTEXT_EOP() end of paragraph
     655                 :            : 
     656                 :            :             First try with boolean marks at TextDecoratedPortionPrimitive2D did not work too well,
     657                 :            :             i decided to solve it with structure. I added the TextHierarchyPrimitives for this,
     658                 :            :             namely:
     659                 :            :             - TextHierarchyLinePrimitive2D: Encapsulates single line
     660                 :            :             - TextHierarchyParagraphPrimitive2D: Encapsulates single paragraph
     661                 :            :             - TextHierarchyBlockPrimitive2D: encapsulates object texts (only one ATM)
     662                 :            :             Those are now supported in hierarchy. This means the MetaFile renderer will support them
     663                 :            :             by using them, reculrively using their content and adding MetaFile comments as needed.
     664                 :            :             This also means that when another text layouter will be used it will be necessary to
     665                 :            :             create/support the same HierarchyPrimitives to support users.
     666                 :            :             To transport the information using this hierarchy is best suited to all future needs;
     667                 :            :             the slideshow will be able to profit from it directly when using primitives; all other
     668                 :            :             renderers not interested in the text structure will just ignore the encapsulations.
     669                 :            : 
     670                 :            :             XTEXT_PAINTSHAPE_BEGIN, XTEXT_PAINTSHAPE_END
     671                 :            :             Supported now by the TextHierarchyBlockPrimitive2D.
     672                 :            : 
     673                 :            :             EPSReplacementGraphic:
     674                 :            :             Only used in goodies\source\filter.vcl\ieps\ieps.cxx and svx\source\xml\xmlgrhlp.cxx to
     675                 :            :             hold the original EPS which was imported in the same MetaFile as first 2 entries. Only
     676                 :            :             used to export the original again (if exists).
     677                 :            :             Not necessary to support with MetaFuleRenderer.
     678                 :            : 
     679                 :            :             XTEXT_SCROLLRECT, XTEXT_PAINTRECT
     680                 :            :             Currently used to get extra MetaFile infos using GraphicExporter which again uses
     681                 :            :             SdrTextObj::GetTextScrollMetaFileAndRectangle(). ATM works with primitives since
     682                 :            :             the rectangle data is added directly by the GraphicsExporter as comment. Does not need
     683                 :            :             to be adapted at once.
     684                 :            :             When adapting later, the only user - the diashow - should directly use the provided
     685                 :            :             Anination infos in the appropriate primitives (e.g. AnimatedSwitchPrimitive2D)
     686                 :            : 
     687                 :            :             PRNSPOOL_TRANSPARENTBITMAP_BEGIN, PRNSPOOL_TRANSPARENTBITMAP_END
     688                 :            :             VCL usage when printing PL -> THB. Okay, THB confirms that it is only used as
     689                 :            :             a fix (hack) while VCL printing. It is needed to not downscale a bitmap which
     690                 :            :             was explicitly created for the printer already again to some default maximum
     691                 :            :             bitmap sizes.
     692                 :            :             Nothing to do here for the primitive renderer.
     693                 :            : 
     694                 :            :             Support for vcl::PDFExtOutDevData:
     695                 :            :             PL knows that SJ did that stuff, it's used to hold a pointer to PDFExtOutDevData at
     696                 :            :             the OutDev. When set, some extra data is written there. Trying simple PDF export and
     697                 :            :             watching if i get those infos.
     698                 :            :             Well, a PDF export does not use e.g. ImpEditEngine::Paint since the PdfFilter uses
     699                 :            :             the SdXImpressDocument::render and thus uses the VclMetafileProcessor2D. I will check
     700                 :            :             if i get a PDFExtOutDevData at the target output device.
     701                 :            :             Indeed, i get one. Checking what all may be done when that extra-device-info is there.
     702                 :            : 
     703                 :            :             All in all i have to talk to SJ. I will need to emulate some of those actions, but
     704                 :            :             i need to discuss which ones.
     705                 :            :             In the future, all those infos would be taken from the primitive sequence anyways,
     706                 :            :             thus these extensions would potentially be temporary, too.
     707                 :            :             Discussed with SJ, added the necessary support and tested it. Details follow.
     708                 :            : 
     709                 :            :             - In ImpEditEngine::Paint, paragraph infos and URL stuff is added.
     710                 :            :               Added in primitive MetaFile renderer.
     711                 :            :               Checking URL: Indeed, current version exports it, but it is missing in primitive
     712                 :            :               CWS version. Adding support.
     713                 :            :               Okay, URLs work. Checked, Done.
     714                 :            : 
     715                 :            :             - UnoControlPDFExportContact is only created when PDFExtOutDevData is used at the
     716                 :            :               target and uno control data is created in UnoControlPDFExportContact::do_PaintObject.
     717                 :            :               This may be added in primitive MetaFile renderer.
     718                 :            :               Adding support...
     719                 :            :               OOps, the necessary helper stuff is in svx/source/form/formpdxexport.cxx in namespace
     720                 :            :               svxform. Have to talk to FS if this has to be like that. Especially since
     721                 :            :               ::vcl::PDFWriter::AnyWidget is filled out, which is already part of vcl.
     722                 :            :               Wrote an eMail to FS, he is on vacation currently. I see no reason why not to move
     723                 :            :               that stuff to somewhere else, maybe tools or svtools ?!? We will see...
     724                 :            :               Moved to toolkit, so i have to link against it. I tried VCL first, but it did
     725                 :            :               not work since VCLUnoHelper::CreateFont is unresolved in VCL (!). Other then the name
     726                 :            :               may imply, it is defined in toolkit (!). Since toolkit is linked against VCL itself,
     727                 :            :               the lowest move,ment plave is toolkit.
     728                 :            :               Checked form control export, it works well. Done.
     729                 :            : 
     730                 :            :             - In goodies, in GraphicObject::Draw, when the used Graphic is linked, infos are
     731                 :            :               generated. I will need to check what happens here with primitives.
     732                 :            :               To support, use of GraphicPrimitive2D (PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D) may be needed.
     733                 :            :               Added support, but feature is broken in main version, so i cannot test at all.
     734                 :            :               Writing a bug to CL (or SJ) and seeing what happens (#i80380#).
     735                 :            :               SJ took a look and we got it working. Tested VCL MetaFile Renderer based export,
     736                 :            :               as intended, the original file is exported. Works, Done.
     737                 :            : 
     738                 :            : 
     739                 :            : 
     740                 :            : 
     741                 :            :             To be done:
     742                 :            : 
     743                 :            :             - Maybe there are more places to take care of for vcl::PDFExtOutDevData!
     744                 :            : 
     745                 :            : 
     746                 :            : 
     747                 :            :         ****************************************************************************************************/
     748                 :            : 
     749                 :      49334 :         void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
     750                 :            :         {
     751   [ -  +  +  +  :      49334 :             switch(rCandidate.getPrimitive2DID())
          +  -  +  +  +  
          +  +  +  +  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
                -  -  + ]
     752                 :            :             {
     753                 :            :                 case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
     754                 :            :                 {
     755                 :            :                     // directdraw of wrong spell primitive
     756                 :            :                     // Ignore for VclMetafileProcessor2D, this is for printing and MetaFile recording only
     757                 :          0 :                     break;
     758                 :            :                 }
     759                 :            :                 case PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D :
     760                 :            :                 {
     761                 :         12 :                     const primitive2d::GraphicPrimitive2D& rGraphicPrimitive = static_cast< const primitive2d::GraphicPrimitive2D& >(rCandidate);
     762                 :         12 :                     bool bUsingPDFExtOutDevData(false);
     763                 :         12 :                     basegfx::B2DVector aTranslate, aScale;
     764                 :            :                     static bool bSuppressPDFExtOutDevDataSupport(false);
     765                 :            : 
     766 [ #  # ][ -  + ]:         12 :                     if(mpPDFExtOutDevData && !bSuppressPDFExtOutDevDataSupport)
     767                 :            :                     {
     768                 :            :                         // emulate data handling from UnoControlPDFExportContact, original see
     769                 :            :                         // svtools/source/graphic/grfmgr.cxx
     770         [ #  # ]:          0 :                         const Graphic& rGraphic = rGraphicPrimitive.getGraphicObject().GetGraphic();
     771                 :            : 
     772 [ #  # ][ #  # ]:          0 :                         if(rGraphic.IsLink())
     773                 :            :                         {
     774                 :          0 :                             const GraphicAttr& rAttr = rGraphicPrimitive.getGraphicAttr();
     775                 :            : 
     776 [ #  # ][ #  # ]:          0 :                             if(!rAttr.IsSpecialDrawMode() && !rAttr.IsAdjusted())
                 [ #  # ]
     777                 :            :                             {
     778                 :          0 :                                 const basegfx::B2DHomMatrix& rTransform = rGraphicPrimitive.getTransform();
     779                 :            :                                 double fRotate, fShearX;
     780         [ #  # ]:          0 :                                 rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
     781                 :            : 
     782 [ #  # ][ #  # ]:          0 :                                 if( basegfx::fTools::equalZero( fRotate ) && ( aScale.getX() > 0.0 ) && ( aScale.getY() > 0.0 ) )
         [ #  # ][ #  # ]
     783                 :            :                                 {
     784                 :          0 :                                     bUsingPDFExtOutDevData = true;
     785         [ #  # ]:          0 :                                     mpPDFExtOutDevData->BeginGroup();
     786                 :            :                                 }
     787                 :            :                             }
     788                 :            :                         }
     789                 :            :                     }
     790                 :            : 
     791                 :            :                     // process recursively and add MetaFile comment
     792 [ +  - ][ +  - ]:         12 :                     process(rGraphicPrimitive.get2DDecomposition(getViewInformation2D()));
                 [ +  - ]
     793                 :            : 
     794         [ -  + ]:         12 :                     if(bUsingPDFExtOutDevData)
     795                 :            :                     {
     796                 :            :                         // emulate data handling from UnoControlPDFExportContact, original see
     797                 :            :                         // svtools/source/graphic/grfmgr.cxx
     798                 :            :                         const basegfx::B2DRange aCurrentRange(
     799                 :            :                             aTranslate.getX(), aTranslate.getY(),
     800         [ #  # ]:          0 :                             aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
     801                 :            :                         const Rectangle aCurrentRect(
     802 [ #  # ][ #  # ]:          0 :                             sal_Int32(floor(aCurrentRange.getMinX())), sal_Int32(floor(aCurrentRange.getMinY())),
     803 [ #  # ][ #  # ]:          0 :                             sal_Int32(ceil(aCurrentRange.getMaxX())), sal_Int32(ceil(aCurrentRange.getMaxY())));
                 [ #  # ]
     804                 :          0 :                         const GraphicAttr& rAttr = rGraphicPrimitive.getGraphicAttr();
     805         [ #  # ]:          0 :                         Rectangle aCropRect;
     806                 :            : 
     807         [ #  # ]:          0 :                         if(rAttr.IsCropped())
     808                 :            :                         {
     809                 :            :                             // calculate scalings between real image size and logic object size. This
     810                 :            :                             // is necessary since the crop values are relative to original bitmap size
     811                 :          0 :                             double fFactorX(1.0);
     812                 :          0 :                             double fFactorY(1.0);
     813                 :            : 
     814                 :            :                             {
     815         [ #  # ]:          0 :                                 const MapMode aMapMode100thmm(MAP_100TH_MM);
     816         [ #  # ]:          0 :                                 const Size aBitmapSize(Application::GetDefaultDevice()->LogicToLogic(
     817                 :          0 :                                     rGraphicPrimitive.getGraphicObject().GetPrefSize(),
     818         [ #  # ]:          0 :                                     rGraphicPrimitive.getGraphicObject().GetPrefMapMode(), aMapMode100thmm));
     819                 :          0 :                                 const double fDivX(aBitmapSize.Width() - rAttr.GetLeftCrop() - rAttr.GetRightCrop());
     820                 :          0 :                                 const double fDivY(aBitmapSize.Height() - rAttr.GetTopCrop() - rAttr.GetBottomCrop());
     821                 :            : 
     822         [ #  # ]:          0 :                                 if(!basegfx::fTools::equalZero(fDivX))
     823                 :            :                                 {
     824                 :          0 :                                     fFactorX = aScale.getX() / fDivX;
     825                 :            :                                 }
     826                 :            : 
     827         [ #  # ]:          0 :                                 if(!basegfx::fTools::equalZero(fDivY))
     828                 :            :                                 {
     829                 :          0 :                                     fFactorY = aScale.getY() / fDivY;
     830         [ #  # ]:          0 :                                 }
     831                 :            :                             }
     832                 :            : 
     833                 :            :                             // calculate crop range and rect
     834         [ #  # ]:          0 :                             basegfx::B2DRange aCropRange;
     835 [ #  # ][ #  # ]:          0 :                             aCropRange.expand(aCurrentRange.getMinimum() - basegfx::B2DPoint(rAttr.GetLeftCrop() * fFactorX, rAttr.GetTopCrop() * fFactorY));
     836 [ #  # ][ #  # ]:          0 :                             aCropRange.expand(aCurrentRange.getMaximum() + basegfx::B2DPoint(rAttr.GetRightCrop() * fFactorX, rAttr.GetBottomCrop() * fFactorY));
     837                 :            : 
     838                 :            :                             aCropRect = Rectangle(
     839 [ #  # ][ #  # ]:          0 :                                 sal_Int32(floor(aCropRange.getMinX())), sal_Int32(floor(aCropRange.getMinY())),
     840 [ #  # ][ #  # ]:          0 :                                 sal_Int32(ceil(aCropRange.getMaxX())), sal_Int32(ceil(aCropRange.getMaxY())));
                 [ #  # ]
     841                 :            :                         }
     842                 :            : 
     843         [ #  # ]:          0 :                         mpPDFExtOutDevData->EndGroup(rGraphicPrimitive.getGraphicObject().GetGraphic(),
     844                 :          0 :                             rAttr.GetTransparency(),
     845                 :            :                             aCurrentRect,
     846         [ #  # ]:          0 :                             aCropRect);
     847                 :            :                     }
     848                 :            : 
     849                 :         12 :                     break;
     850                 :            :                 }
     851                 :            :                 case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D :
     852                 :            :                 {
     853                 :          3 :                     const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate);
     854         [ +  - ]:          3 :                     const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl());
     855                 :          3 :                     bool bIsPrintableControl(false);
     856                 :            : 
     857                 :            :                     // find out if control is printable
     858         [ +  - ]:          3 :                     if(rXControl.is())
     859                 :            :                     {
     860                 :            :                         try
     861                 :            :                         {
     862 [ +  - ][ +  - ]:          3 :                             uno::Reference< beans::XPropertySet > xModelProperties(rXControl->getModel(), uno::UNO_QUERY);
                 [ +  - ]
     863                 :          3 :                             uno::Reference< beans::XPropertySetInfo > xPropertyInfo(xModelProperties.is()
     864         [ +  - ]:          3 :                                 ? xModelProperties->getPropertySetInfo()
     865 [ +  - ][ +  - ]:          6 :                                 : uno::Reference< beans::XPropertySetInfo >());
     866                 :          3 :                             const ::rtl::OUString sPrintablePropertyName("Printable");
     867                 :            : 
     868 [ +  - ][ +  - ]:          3 :                             if(xPropertyInfo.is() && xPropertyInfo->hasPropertyByName(sPrintablePropertyName))
         [ +  - ][ +  - ]
                 [ +  - ]
     869                 :            :                             {
     870 [ +  - ][ +  - ]:          3 :                                 OSL_VERIFY(xModelProperties->getPropertyValue(sPrintablePropertyName) >>= bIsPrintableControl);
     871         [ #  # ]:          3 :                             }
     872                 :            :                         }
     873         [ #  # ]:          0 :                         catch(const uno::Exception&)
     874                 :            :                         {
     875                 :            :                             OSL_FAIL("VclMetafileProcessor2D: No access to printable flag of Control, caught an exception!");
     876                 :            :                         }
     877                 :            :                     }
     878                 :            : 
     879                 :            :                     // PDF export and printing only for printable controls
     880         [ +  - ]:          3 :                     if(bIsPrintableControl)
     881                 :            :                     {
     882 [ -  + ][ #  # ]:          3 :                         const bool bPDFExport(mpPDFExtOutDevData && mpPDFExtOutDevData->GetIsExportFormFields());
                 [ #  # ]
     883                 :          3 :                         bool bDoProcessRecursively(true);
     884                 :            : 
     885         [ -  + ]:          3 :                         if(bPDFExport)
     886                 :            :                         {
     887                 :            :                             // PDF export. Emulate data handling from UnoControlPDFExportContact
     888                 :            :                             // I have now moved describePDFControl to toolkit, thus i can implement the PDF
     889                 :            :                             // form control support now as follows
     890                 :          0 :                             ::std::auto_ptr< ::vcl::PDFWriter::AnyWidget > pPDFControl;
     891         [ #  # ]:          0 :                             ::toolkitform::describePDFControl( rXControl, pPDFControl, *mpPDFExtOutDevData );
     892                 :            : 
     893         [ #  # ]:          0 :                             if(pPDFControl.get())
     894                 :            :                             {
     895                 :            :                                 // still need to fill in the location (is a class Rectangle)
     896         [ #  # ]:          0 :                                 const basegfx::B2DRange aRangeLogic(rControlPrimitive.getB2DRange(getViewInformation2D()));
     897                 :            :                                 const Rectangle aRectLogic(
     898 [ #  # ][ #  # ]:          0 :                                     (sal_Int32)floor(aRangeLogic.getMinX()), (sal_Int32)floor(aRangeLogic.getMinY()),
     899 [ #  # ][ #  # ]:          0 :                                     (sal_Int32)ceil(aRangeLogic.getMaxX()), (sal_Int32)ceil(aRangeLogic.getMaxY()));
                 [ #  # ]
     900                 :          0 :                                 pPDFControl->Location = aRectLogic;
     901                 :            : 
     902         [ #  # ]:          0 :                                 Size aFontSize(pPDFControl->TextFont.GetSize());
     903 [ #  # ][ #  # ]:          0 :                                 aFontSize = mpOutputDevice->LogicToLogic(aFontSize, MapMode(MAP_POINT), mpOutputDevice->GetMapMode());
                 [ #  # ]
     904         [ #  # ]:          0 :                                 pPDFControl->TextFont.SetSize(aFontSize);
     905                 :            : 
     906         [ #  # ]:          0 :                                 mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::Form);
     907         [ #  # ]:          0 :                                 mpPDFExtOutDevData->CreateControl(*pPDFControl.get());
     908         [ #  # ]:          0 :                                 mpPDFExtOutDevData->EndStructureElement();
     909                 :            : 
     910                 :            :                                 // no normal paint needed (see original UnoControlPDFExportContact::do_PaintObject);
     911                 :            :                                 // do not process recursively
     912                 :          0 :                                 bDoProcessRecursively = false;
     913                 :            :                             }
     914                 :            :                             else
     915                 :            :                             {
     916                 :            :                                 // PDF export did not work, try simple output.
     917                 :            :                                 // Fallback to printer output by not setting bDoProcessRecursively
     918                 :            :                                 // to false.
     919         [ #  # ]:          0 :                             }
     920                 :            :                         }
     921                 :            : 
     922                 :            :                         // #i93169# used flag the wrong way; true means that nothing was done yet
     923         [ +  - ]:          3 :                         if(bDoProcessRecursively)
     924                 :            :                         {
     925                 :            :                             // printer output
     926                 :            :                             try
     927                 :            :                             {
     928                 :            :                                 // remember old graphics and create new
     929         [ +  - ]:          3 :                                 uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW);
     930 [ +  - ][ +  - ]:          3 :                                 const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics());
     931         [ +  - ]:          3 :                                 const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics());
     932                 :            : 
     933         [ +  - ]:          3 :                                 if(xNewGraphics.is())
     934                 :            :                                 {
     935                 :            :                                     // link graphics and view
     936 [ +  - ][ +  - ]:          3 :                                     xControlView->setGraphics(xNewGraphics);
     937                 :            : 
     938                 :            :                                     // get position
     939 [ +  - ][ +  - ]:          3 :                                     const basegfx::B2DHomMatrix aObjectToDiscrete(getViewInformation2D().getObjectToViewTransformation() * rControlPrimitive.getTransform());
     940         [ +  - ]:          3 :                                     const basegfx::B2DPoint aTopLeftDiscrete(aObjectToDiscrete * basegfx::B2DPoint(0.0, 0.0));
     941                 :            : 
     942                 :            :                                     // draw it
     943 [ +  - ][ +  - ]:          3 :                                     xControlView->draw(basegfx::fround(aTopLeftDiscrete.getX()), basegfx::fround(aTopLeftDiscrete.getY()));
     944                 :          3 :                                     bDoProcessRecursively = false;
     945                 :            : 
     946                 :            :                                     // restore original graphics
     947 [ +  - ][ +  - ]:          3 :                                     xControlView->setGraphics(xOriginalGraphics);
                 [ +  - ]
     948         [ #  # ]:          3 :                                 }
     949                 :            :                             }
     950         [ #  # ]:          0 :                             catch( const uno::Exception& )
     951                 :            :                             {
     952                 :            :                                 OSL_FAIL("VclMetafileProcessor2D: Printing of Control failed, caught an exception!");
     953                 :            :                             }
     954                 :            :                         }
     955                 :            : 
     956                 :            :                         // process recursively if not done yet to export as decomposition (bitmap)
     957         [ -  + ]:          3 :                         if(bDoProcessRecursively)
     958                 :            :                         {
     959 [ #  # ][ #  # ]:          3 :                             process(rControlPrimitive.get2DDecomposition(getViewInformation2D()));
                 [ #  # ]
     960                 :            :                         }
     961                 :            :                     }
     962                 :            : 
     963                 :            :                     break;
     964                 :            :                 }
     965                 :            :                 case PRIMITIVE2D_ID_TEXTHIERARCHYFIELDPRIMITIVE2D :
     966                 :            :                 {
     967                 :            :                     // support for FIELD_SEQ_BEGIN, FIELD_SEQ_END and URL. It wraps text primitives (but is not limited to)
     968                 :            :                     // thus do the MetafileAction embedding stuff but just handle recursively.
     969                 :          8 :                     const primitive2d::TextHierarchyFieldPrimitive2D& rFieldPrimitive = static_cast< const primitive2d::TextHierarchyFieldPrimitive2D& >(rCandidate);
     970                 :          8 :                     const rtl::OString aCommentStringCommon(RTL_CONSTASCII_STRINGPARAM("FIELD_SEQ_BEGIN"));
     971                 :          8 :                     const rtl::OString aCommentStringPage(RTL_CONSTASCII_STRINGPARAM("FIELD_SEQ_BEGIN;PageField"));
     972                 :          8 :                     const rtl::OString aCommentStringEnd(RTL_CONSTASCII_STRINGPARAM("FIELD_SEQ_END"));
     973                 :            : 
     974      [ +  -  - ]:          8 :                     switch(rFieldPrimitive.getType())
     975                 :            :                     {
     976                 :            :                         default : // case drawinglayer::primitive2d::FIELD_TYPE_COMMON :
     977                 :            :                         {
     978 [ +  - ][ +  - ]:          8 :                             mpMetaFile->AddAction(new MetaCommentAction(aCommentStringCommon));
                 [ +  - ]
     979                 :          8 :                             break;
     980                 :            :                         }
     981                 :            :                         case drawinglayer::primitive2d::FIELD_TYPE_PAGE :
     982                 :            :                         {
     983 [ #  # ][ #  # ]:          0 :                             mpMetaFile->AddAction(new MetaCommentAction(aCommentStringPage));
                 [ #  # ]
     984                 :          0 :                             break;
     985                 :            :                         }
     986                 :            :                         case drawinglayer::primitive2d::FIELD_TYPE_URL :
     987                 :            :                         {
     988                 :          0 :                             const rtl::OUString& rURL = rFieldPrimitive.getString();
     989         [ #  # ]:          0 :                             const String aOldString(rURL);
     990 [ #  # ][ #  # ]:          0 :                             mpMetaFile->AddAction(new MetaCommentAction(aCommentStringCommon, 0, reinterpret_cast< const sal_uInt8* >(aOldString.GetBuffer()), 2 * aOldString.Len()));
                 [ #  # ]
     991         [ #  # ]:          0 :                             break;
     992                 :            :                         }
     993                 :            :                     }
     994                 :            : 
     995                 :            :                     // process recursively
     996         [ +  - ]:          8 :                     const primitive2d::Primitive2DSequence rContent = rFieldPrimitive.get2DDecomposition(getViewInformation2D());
     997         [ +  - ]:          8 :                     process(rContent);
     998                 :            : 
     999                 :            :                     // for the end comment the type is not relevant yet, they are all the same. Just add.
    1000 [ +  - ][ +  - ]:          8 :                     mpMetaFile->AddAction(new MetaCommentAction(aCommentStringEnd));
                 [ +  - ]
    1001                 :            : 
    1002 [ -  + ][ #  # ]:          8 :                     if(mpPDFExtOutDevData && drawinglayer::primitive2d::FIELD_TYPE_URL == rFieldPrimitive.getType())
                 [ -  + ]
    1003                 :            :                     {
    1004                 :            :                         // emulate data handling from ImpEditEngine::Paint
    1005         [ #  # ]:          0 :                         const basegfx::B2DRange aViewRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D()));
    1006                 :            :                         const Rectangle aRectLogic(
    1007 [ #  # ][ #  # ]:          0 :                             (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()),
    1008 [ #  # ][ #  # ]:          0 :                             (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY()));
                 [ #  # ]
    1009                 :          0 :                         vcl::PDFExtOutDevBookmarkEntry aBookmark;
    1010         [ #  # ]:          0 :                         aBookmark.nLinkId = mpPDFExtOutDevData->CreateLink(aRectLogic);
    1011                 :          0 :                         aBookmark.aBookmark = rFieldPrimitive.getString();
    1012         [ #  # ]:          0 :                         std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = mpPDFExtOutDevData->GetBookmarks();
    1013         [ #  # ]:          0 :                         rBookmarks.push_back( aBookmark );
    1014                 :            :                     }
    1015                 :            : 
    1016         [ +  - ]:          8 :                     break;
    1017                 :            :                 }
    1018                 :            :                 case PRIMITIVE2D_ID_TEXTHIERARCHYLINEPRIMITIVE2D :
    1019                 :            :                 {
    1020                 :       3844 :                     const primitive2d::TextHierarchyLinePrimitive2D& rLinePrimitive = static_cast< const primitive2d::TextHierarchyLinePrimitive2D& >(rCandidate);
    1021                 :       3844 :                     const rtl::OString aCommentString(RTL_CONSTASCII_STRINGPARAM("XTEXT_EOL"));
    1022                 :            : 
    1023                 :            :                     // process recursively and add MetaFile comment
    1024 [ +  - ][ +  - ]:       3844 :                     process(rLinePrimitive.get2DDecomposition(getViewInformation2D()));
                 [ +  - ]
    1025 [ +  - ][ +  - ]:       3844 :                     mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
                 [ +  - ]
    1026                 :            : 
    1027                 :       3844 :                     break;
    1028                 :            :                 }
    1029                 :            :                 case PRIMITIVE2D_ID_TEXTHIERARCHYBULLETPRIMITIVE2D :
    1030                 :            :                 {
    1031                 :            :                     // in Outliner::PaintBullet(), a MetafileComment for bullets is added, too. The
    1032                 :            :                     // "XTEXT_EOC" is used, use here, too.
    1033                 :          0 :                     const primitive2d::TextHierarchyBulletPrimitive2D& rBulletPrimitive = static_cast< const primitive2d::TextHierarchyBulletPrimitive2D& >(rCandidate);
    1034                 :          0 :                     const rtl::OString aCommentString(RTL_CONSTASCII_STRINGPARAM("XTEXT_EOC"));
    1035                 :            : 
    1036                 :            :                     // process recursively and add MetaFile comment
    1037 [ #  # ][ #  # ]:          0 :                     process(rBulletPrimitive.get2DDecomposition(getViewInformation2D()));
                 [ #  # ]
    1038 [ #  # ][ #  # ]:          0 :                     mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
                 [ #  # ]
    1039                 :            : 
    1040                 :          0 :                     break;
    1041                 :            :                 }
    1042                 :            :                 case PRIMITIVE2D_ID_TEXTHIERARCHYPARAGRAPHPRIMITIVE2D :
    1043                 :            :                 {
    1044                 :       3844 :                     const primitive2d::TextHierarchyParagraphPrimitive2D& rParagraphPrimitive = static_cast< const primitive2d::TextHierarchyParagraphPrimitive2D& >(rCandidate);
    1045                 :       3844 :                     const rtl::OString aCommentString(RTL_CONSTASCII_STRINGPARAM("XTEXT_EOP"));
    1046                 :            : 
    1047         [ -  + ]:       3844 :                     if(mpPDFExtOutDevData)
    1048                 :            :                     {
    1049                 :            :                         // emulate data handling from ImpEditEngine::Paint
    1050         [ #  # ]:          0 :                         mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::Paragraph );
    1051                 :            :                     }
    1052                 :            : 
    1053                 :            :                     // process recursively and add MetaFile comment
    1054 [ +  - ][ +  - ]:       3844 :                     process(rParagraphPrimitive.get2DDecomposition(getViewInformation2D()));
                 [ +  - ]
    1055 [ +  - ][ +  - ]:       3844 :                     mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
                 [ +  - ]
    1056                 :            : 
    1057         [ -  + ]:       3844 :                     if(mpPDFExtOutDevData)
    1058                 :            :                     {
    1059                 :            :                         // emulate data handling from ImpEditEngine::Paint
    1060         [ #  # ]:          0 :                         mpPDFExtOutDevData->EndStructureElement();
    1061                 :            :                     }
    1062                 :            : 
    1063                 :       3844 :                     break;
    1064                 :            :                 }
    1065                 :            :                 case PRIMITIVE2D_ID_TEXTHIERARCHYBLOCKPRIMITIVE2D :
    1066                 :            :                 {
    1067                 :       3844 :                     const primitive2d::TextHierarchyBlockPrimitive2D& rBlockPrimitive = static_cast< const primitive2d::TextHierarchyBlockPrimitive2D& >(rCandidate);
    1068                 :       3844 :                     const rtl::OString aCommentStringA(RTL_CONSTASCII_STRINGPARAM("XTEXT_PAINTSHAPE_BEGIN"));
    1069                 :       3844 :                     const rtl::OString aCommentStringB(RTL_CONSTASCII_STRINGPARAM("XTEXT_PAINTSHAPE_END"));
    1070                 :            : 
    1071                 :            :                     // add MetaFile comment, process recursively and add MetaFile comment
    1072 [ +  - ][ +  - ]:       3844 :                     mpMetaFile->AddAction(new MetaCommentAction(aCommentStringA));
                 [ +  - ]
    1073 [ +  - ][ +  - ]:       3844 :                     process(rBlockPrimitive.get2DDecomposition(getViewInformation2D()));
                 [ +  - ]
    1074 [ +  - ][ +  - ]:       3844 :                     mpMetaFile->AddAction(new MetaCommentAction(aCommentStringB));
                 [ +  - ]
    1075                 :            : 
    1076                 :       3844 :                     break;
    1077                 :            :                 }
    1078                 :            :                 case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
    1079                 :            :                 case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D :
    1080                 :            :                 {
    1081                 :            :                     // for supporting TEXT_ MetaFile actions there is more to do here; get the candidate
    1082                 :       3844 :                     const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate = static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate);
    1083                 :            :                     // const primitive2d::TextDecoratedPortionPrimitive2D* pTextDecoratedCandidate = dynamic_cast< const primitive2d::TextDecoratedPortionPrimitive2D* >(&rCandidate);
    1084                 :            : 
    1085                 :            :                     // Adapt evtl. used special DrawMode
    1086                 :       3844 :                     const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
    1087                 :       3844 :                     adaptTextToFillDrawMode();
    1088                 :            : 
    1089                 :            :                     // directdraw of text simple portion; use default processing
    1090                 :       3844 :                     RenderTextSimpleOrDecoratedPortionPrimitive2D(rTextCandidate);
    1091                 :            : 
    1092                 :            :                     // restore DrawMode
    1093                 :       3844 :                     mpOutputDevice->SetDrawMode(nOriginalDrawMode);
    1094                 :            : 
    1095                 :            :                     // #i101169# if(pTextDecoratedCandidate)
    1096                 :            :                     {
    1097                 :            :                         // support for TEXT_ MetaFile actions only for decorated texts
    1098         [ +  + ]:       3844 :                         if(!mxBreakIterator.is())
    1099                 :            :                         {
    1100         [ +  - ]:         11 :                             uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(::comphelper::getProcessServiceFactory());
    1101 [ +  - ][ +  - ]:         11 :                             mxBreakIterator.set(xMSF->createInstance("com.sun.star.i18n.BreakIterator"), uno::UNO_QUERY);
                 [ +  - ]
    1102                 :            :                         }
    1103                 :            : 
    1104         [ +  - ]:       3844 :                         if(mxBreakIterator.is())
    1105                 :            :                         {
    1106                 :       3844 :                             const rtl::OUString& rTxt = rTextCandidate.getText();
    1107                 :       3844 :                             const sal_Int32 nTextLength(rTextCandidate.getTextLength()); // rTxt.getLength());
    1108                 :            : 
    1109         [ +  - ]:       3844 :                             if(nTextLength)
    1110                 :            :                             {
    1111                 :       3844 :                                 const ::com::sun::star::lang::Locale& rLocale = rTextCandidate.getLocale();
    1112                 :       3844 :                                 const sal_Int32 nTextPosition(rTextCandidate.getTextPosition());
    1113                 :            : 
    1114                 :            :                                 sal_Int32 nDone;
    1115 [ +  - ][ +  - ]:       3844 :                                 sal_Int32 nNextCellBreak(mxBreakIterator->nextCharacters(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 0, nDone));
    1116 [ +  - ][ +  - ]:       3844 :                                 ::com::sun::star::i18n::Boundary nNextWordBoundary(mxBreakIterator->getWordBoundary(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True));
    1117 [ +  - ][ +  - ]:       3844 :                                 sal_Int32 nNextSentenceBreak(mxBreakIterator->endOfSentence(rTxt, nTextPosition, rLocale));
    1118                 :       3844 :                                 const rtl::OString aCommentStringA(RTL_CONSTASCII_STRINGPARAM("XTEXT_EOC"));
    1119                 :       3844 :                                 const rtl::OString aCommentStringB(RTL_CONSTASCII_STRINGPARAM("XTEXT_EOW"));
    1120                 :       3844 :                                 const rtl::OString aCommentStringC(RTL_CONSTASCII_STRINGPARAM("XTEXT_EOS"));
    1121                 :            : 
    1122         [ +  + ]:      35195 :                                 for(sal_Int32 i(nTextPosition); i < nTextPosition + nTextLength; i++)
    1123                 :            :                                 {
    1124                 :            :                                     // create the entries for the respective break positions
    1125         [ +  - ]:      31351 :                                     if(i == nNextCellBreak)
    1126                 :            :                                     {
    1127 [ +  - ][ +  - ]:      31351 :                                         mpMetaFile->AddAction(new MetaCommentAction(aCommentStringA, i - nTextPosition));
                 [ +  - ]
    1128 [ +  - ][ +  - ]:      31351 :                                         nNextCellBreak = mxBreakIterator->nextCharacters(rTxt, i, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
    1129                 :            :                                     }
    1130         [ +  + ]:      31351 :                                     if(i == nNextWordBoundary.endPos)
    1131                 :            :                                     {
    1132 [ +  - ][ +  - ]:       2748 :                                         mpMetaFile->AddAction(new MetaCommentAction(aCommentStringB, i - nTextPosition));
                 [ +  - ]
    1133 [ +  - ][ +  - ]:       2748 :                                         nNextWordBoundary = mxBreakIterator->getWordBoundary(rTxt, i + 1, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True);
    1134                 :            :                                     }
    1135         [ +  + ]:      31351 :                                     if(i == nNextSentenceBreak)
    1136                 :            :                                     {
    1137 [ +  - ][ +  - ]:         12 :                                         mpMetaFile->AddAction(new MetaCommentAction(aCommentStringC, i - nTextPosition));
                 [ +  - ]
    1138 [ +  - ][ +  - ]:         12 :                                         nNextSentenceBreak = mxBreakIterator->endOfSentence(rTxt, i + 1, rLocale);
    1139                 :            :                                     }
    1140                 :       3844 :                                 }
    1141                 :       3844 :                             }
    1142                 :            :                         }
    1143                 :            :                     }
    1144                 :            : 
    1145                 :       3844 :                     break;
    1146                 :            :                 }
    1147                 :            :                 case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
    1148                 :            :                 {
    1149                 :       6508 :                     const primitive2d::PolygonHairlinePrimitive2D& rHairlinePrimitive = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate);
    1150                 :       6508 :                     const basegfx::B2DPolygon& rBasePolygon = rHairlinePrimitive.getB2DPolygon();
    1151                 :            : 
    1152         [ -  + ]:       6508 :                     if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1))
    1153                 :            :                     {
    1154                 :            :                         // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1155                 :            :                         // per polygon. If there are more, split the polygon in half and call recursively
    1156 [ #  # ][ #  # ]:          0 :                         basegfx::B2DPolygon aLeft, aRight;
    1157         [ #  # ]:          0 :                         splitLinePolygon(rBasePolygon, aLeft, aRight);
    1158         [ #  # ]:          0 :                         const primitive2d::PolygonHairlinePrimitive2D aPLeft(aLeft, rHairlinePrimitive.getBColor());
    1159         [ #  # ]:          0 :                         const primitive2d::PolygonHairlinePrimitive2D aPRight(aRight, rHairlinePrimitive.getBColor());
    1160                 :            : 
    1161         [ #  # ]:          0 :                         processBasePrimitive2D(aPLeft);
    1162 [ #  # ][ #  # ]:          0 :                         processBasePrimitive2D(aPRight);
         [ #  # ][ #  # ]
                 [ #  # ]
    1163                 :            :                     }
    1164                 :            :                     else
    1165                 :            :                     {
    1166                 :            :                         // direct draw of hairline; use default processing
    1167                 :            :                         // support SvtGraphicStroke MetaCommentAction
    1168         [ +  - ]:       6508 :                         const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rHairlinePrimitive.getBColor()));
    1169                 :            :                         SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
    1170                 :       6508 :                             rHairlinePrimitive.getB2DPolygon(),
    1171                 :            :                             &aLineColor,
    1172         [ +  - ]:       6508 :                             0, 0, 0, 0);
    1173                 :            : 
    1174         [ +  - ]:       6508 :                         impStartSvtGraphicStroke(pSvtGraphicStroke);
    1175         [ +  - ]:       6508 :                         RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), false);
    1176         [ +  - ]:       6508 :                         impEndSvtGraphicStroke(pSvtGraphicStroke);
    1177                 :            :                     }
    1178                 :       6508 :                     break;
    1179                 :            :                 }
    1180                 :            :                 case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D :
    1181                 :            :                 {
    1182                 :       4735 :                     const primitive2d::PolygonStrokePrimitive2D& rStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);
    1183                 :       4735 :                     const basegfx::B2DPolygon& rBasePolygon = rStrokePrimitive.getB2DPolygon();
    1184                 :            : 
    1185         [ -  + ]:       4735 :                     if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1))
    1186                 :            :                     {
    1187                 :            :                         // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1188                 :            :                         // per polygon. If there are more, split the polygon in half and call recursively
    1189 [ #  # ][ #  # ]:          0 :                         basegfx::B2DPolygon aLeft, aRight;
    1190         [ #  # ]:          0 :                         splitLinePolygon(rBasePolygon, aLeft, aRight);
    1191                 :            :                         const primitive2d::PolygonStrokePrimitive2D aPLeft(
    1192         [ #  # ]:          0 :                             aLeft, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute());
    1193                 :            :                         const primitive2d::PolygonStrokePrimitive2D aPRight(
    1194         [ #  # ]:          0 :                             aRight, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute());
    1195                 :            : 
    1196         [ #  # ]:          0 :                         processBasePrimitive2D(aPLeft);
    1197 [ #  # ][ #  # ]:          0 :                         processBasePrimitive2D(aPRight);
         [ #  # ][ #  # ]
                 [ #  # ]
    1198                 :            :                     }
    1199                 :            :                     else
    1200                 :            :                     {
    1201                 :            :                         // support SvtGraphicStroke MetaCommentAction
    1202                 :            :                         SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
    1203                 :            :                             rBasePolygon, 0,
    1204                 :       4735 :                             &rStrokePrimitive.getLineAttribute(),
    1205                 :       4735 :                             &rStrokePrimitive.getStrokeAttribute(),
    1206                 :       4735 :                             0, 0);
    1207                 :            : 
    1208                 :       4735 :                         impStartSvtGraphicStroke(pSvtGraphicStroke);
    1209                 :       4735 :                         const attribute::LineAttribute& rLine = rStrokePrimitive.getLineAttribute();
    1210                 :            : 
    1211                 :            :                         // create MetaPolyLineActions, but without LINE_DASH
    1212 [ +  + ][ +  - ]:       4735 :                         if(basegfx::fTools::more(rLine.getWidth(), 0.0))
    1213                 :            :                         {
    1214                 :        403 :                             const attribute::StrokeAttribute& rStroke = rStrokePrimitive.getStrokeAttribute();
    1215         [ +  - ]:        403 :                             basegfx::B2DPolyPolygon aHairLinePolyPolygon;
    1216                 :            : 
    1217 [ +  - ][ +  - ]:        403 :                             if(0.0 == rStroke.getFullDotDashLen())
    1218                 :            :                             {
    1219         [ +  - ]:        403 :                                 aHairLinePolyPolygon.append(rBasePolygon);
    1220                 :            :                             }
    1221                 :            :                             else
    1222                 :            :                             {
    1223                 :            :                                 basegfx::tools::applyLineDashing(
    1224         [ #  # ]:          0 :                                     rBasePolygon, rStroke.getDotDashArray(),
    1225 [ #  # ][ #  # ]:          0 :                                     &aHairLinePolyPolygon, 0, rStroke.getFullDotDashLen());
    1226                 :            :                             }
    1227                 :            : 
    1228 [ +  - ][ +  - ]:        403 :                             const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor()));
    1229         [ +  - ]:        403 :                             mpOutputDevice->SetLineColor(Color(aHairlineColor));
    1230         [ +  - ]:        403 :                             mpOutputDevice->SetFillColor();
    1231         [ +  - ]:        403 :                             aHairLinePolyPolygon.transform(maCurrentTransformation);
    1232                 :            : 
    1233                 :            :                             // #i113922# LineWidth needs to be transformed, too
    1234 [ +  - ][ +  - ]:        403 :                             const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(rLine.getWidth(), 0.0));
    1235         [ +  - ]:        403 :                             const double fDiscreteLineWidth(aDiscreteUnit.getLength());
    1236                 :            : 
    1237         [ +  - ]:        403 :                             LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fDiscreteLineWidth));
    1238 [ +  - ][ +  - ]:        403 :                             aLineInfo.SetLineJoin(rLine.getLineJoin());
    1239                 :            : 
    1240 [ +  - ][ +  + ]:        806 :                             for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++)
    1241                 :            :                             {
    1242         [ +  - ]:        403 :                                 const basegfx::B2DPolygon aCandidate(aHairLinePolyPolygon.getB2DPolygon(a));
    1243                 :            : 
    1244 [ +  - ][ +  - ]:        403 :                                 if(aCandidate.count() > 1)
    1245                 :            :                                 {
    1246         [ +  - ]:        403 :                                     const Polygon aToolsPolygon(aCandidate);
    1247                 :            : 
    1248 [ +  - ][ +  - ]:        403 :                                     mpMetaFile->AddAction(new MetaPolyLineAction(aToolsPolygon, aLineInfo));
         [ +  - ][ +  - ]
    1249                 :            :                                 }
    1250 [ +  - ][ +  - ]:        806 :                             }
                 [ +  - ]
    1251                 :            :                         }
    1252                 :            :                         else
    1253                 :            :                         {
    1254         [ +  - ]:       4332 :                             process(rCandidate.get2DDecomposition(getViewInformation2D()));
    1255                 :            :                         }
    1256                 :            : 
    1257                 :       4735 :                         impEndSvtGraphicStroke(pSvtGraphicStroke);
    1258                 :            :                     }
    1259                 :            : 
    1260                 :       4735 :                     break;
    1261                 :            :                 }
    1262                 :            :                 case PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D :
    1263                 :            :                 {
    1264                 :          3 :                     const primitive2d::PolygonStrokeArrowPrimitive2D& rStrokeArrowPrimitive = static_cast< const primitive2d::PolygonStrokeArrowPrimitive2D& >(rCandidate);
    1265                 :          3 :                     const basegfx::B2DPolygon& rBasePolygon = rStrokeArrowPrimitive.getB2DPolygon();
    1266                 :            : 
    1267         [ -  + ]:          3 :                     if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1))
    1268                 :            :                     {
    1269                 :            :                         // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1270                 :            :                         // per polygon. If there are more, split the polygon in half and call recursively
    1271 [ #  # ][ #  # ]:          0 :                         basegfx::B2DPolygon aLeft, aRight;
    1272         [ #  # ]:          0 :                         splitLinePolygon(rBasePolygon, aLeft, aRight);
    1273         [ #  # ]:          0 :                         const attribute::LineStartEndAttribute aEmpty;
    1274                 :            :                         const primitive2d::PolygonStrokeArrowPrimitive2D aPLeft(
    1275                 :            :                             aLeft,
    1276                 :          0 :                             rStrokeArrowPrimitive.getLineAttribute(),
    1277                 :          0 :                             rStrokeArrowPrimitive.getStrokeAttribute(),
    1278                 :          0 :                             rStrokeArrowPrimitive.getStart(),
    1279         [ #  # ]:          0 :                             aEmpty);
    1280                 :            :                         const primitive2d::PolygonStrokeArrowPrimitive2D aPRight(
    1281                 :            :                             aRight,
    1282                 :          0 :                             rStrokeArrowPrimitive.getLineAttribute(),
    1283                 :          0 :                             rStrokeArrowPrimitive.getStrokeAttribute(),
    1284                 :            :                             aEmpty,
    1285         [ #  # ]:          0 :                             rStrokeArrowPrimitive.getEnd());
    1286                 :            : 
    1287         [ #  # ]:          0 :                         processBasePrimitive2D(aPLeft);
    1288 [ #  # ][ #  # ]:          0 :                         processBasePrimitive2D(aPRight);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1289                 :            :                     }
    1290                 :            :                     else
    1291                 :            :                     {
    1292                 :            :                         // support SvtGraphicStroke MetaCommentAction
    1293                 :            :                         SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
    1294                 :            :                             rBasePolygon, 0,
    1295                 :          3 :                             &rStrokeArrowPrimitive.getLineAttribute(),
    1296                 :          3 :                             &rStrokeArrowPrimitive.getStrokeAttribute(),
    1297                 :          3 :                             &rStrokeArrowPrimitive.getStart(),
    1298                 :          6 :                             &rStrokeArrowPrimitive.getEnd());
    1299                 :            : 
    1300                 :          3 :                         impStartSvtGraphicStroke(pSvtGraphicStroke);
    1301         [ +  - ]:          3 :                         process(rCandidate.get2DDecomposition(getViewInformation2D()));
    1302                 :          3 :                         impEndSvtGraphicStroke(pSvtGraphicStroke);
    1303                 :            :                     }
    1304                 :            : 
    1305                 :          3 :                     break;
    1306                 :            :                 }
    1307                 :            :                 case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
    1308                 :            :                 {
    1309                 :            :                     // direct draw of transformed BitmapEx primitive; use default processing
    1310                 :         25 :                     RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
    1311                 :         25 :                     break;
    1312                 :            :                 }
    1313                 :            :                 case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D :
    1314                 :            :                 {
    1315                 :            :                     // direct draw of transformed RenderGraphic primitive; use default processing
    1316                 :          0 :                     RenderRenderGraphicPrimitive2D(static_cast< const primitive2d::RenderGraphicPrimitive2D& >(rCandidate));
    1317                 :          0 :                     break;
    1318                 :            :                 }
    1319                 :            :                 case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D :
    1320                 :            :                 {
    1321                 :            :                     // need to handle PolyPolygonBitmapPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END
    1322                 :          0 :                     const primitive2d::PolyPolygonBitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate);
    1323         [ #  # ]:          0 :                     basegfx::B2DPolyPolygon aLocalPolyPolygon(rBitmapCandidate.getB2DPolyPolygon());
    1324                 :            : 
    1325 [ #  # ][ #  # ]:          0 :                     if(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
    1326                 :            :                     {
    1327                 :            :                         // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1328                 :            :                         // per polygon. If there are more use the splitted polygon and call recursively
    1329                 :            :                         const primitive2d::PolyPolygonBitmapPrimitive2D aSplitted(
    1330                 :            :                             aLocalPolyPolygon,
    1331         [ #  # ]:          0 :                             rBitmapCandidate.getFillBitmap());
    1332                 :            : 
    1333 [ #  # ][ #  # ]:          0 :                         processBasePrimitive2D(aSplitted);
    1334                 :            :                     }
    1335                 :            :                     else
    1336                 :            :                     {
    1337                 :          0 :                         SvtGraphicFill* pSvtGraphicFill = 0;
    1338                 :            : 
    1339 [ #  # ][ #  # ]:          0 :                         if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
         [ #  # ][ #  # ]
    1340                 :            :                         {
    1341         [ #  # ]:          0 :                             aLocalPolyPolygon.transform(maCurrentTransformation);
    1342                 :            :                             // calculate transformation. Get real object size, all values in FillBitmapAttribute
    1343                 :            :                             // are relative to the unified object
    1344                 :          0 :                             const attribute::FillBitmapAttribute& rFillBitmapAttribute = rBitmapCandidate .getFillBitmap();
    1345         [ #  # ]:          0 :                             const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(aLocalPolyPolygon));
    1346         [ #  # ]:          0 :                             const basegfx::B2DVector aOutlineSize(aOutlineRange.getRange());
    1347                 :            : 
    1348                 :            :                             // get absolute values
    1349         [ #  # ]:          0 :                             const basegfx::B2DVector aFillBitmapSize(rFillBitmapAttribute.getSize() * aOutlineSize);
    1350         [ #  # ]:          0 :                             const basegfx::B2DPoint aFillBitmapTopLeft(rFillBitmapAttribute.getTopLeft() * aOutlineSize);
    1351                 :            : 
    1352                 :            :                             // the scaling needs scale from pixel to logic coordinate system
    1353         [ #  # ]:          0 :                             const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx();
    1354                 :          0 :                             Size aBmpSizePixel(rBitmapEx.GetSizePixel());
    1355                 :            : 
    1356         [ #  # ]:          0 :                             if(!aBmpSizePixel.Width())
    1357                 :            :                             {
    1358                 :          0 :                                 aBmpSizePixel.Width() = 1;
    1359                 :            :                             }
    1360                 :            : 
    1361         [ #  # ]:          0 :                             if(!aBmpSizePixel.Height())
    1362                 :            :                             {
    1363                 :          0 :                                 aBmpSizePixel.Height() = 1;
    1364                 :            :                             }
    1365                 :            : 
    1366                 :            :                             // setup transformation like in impgrfll
    1367         [ #  # ]:          0 :                             SvtGraphicFill::Transform aTransform;
    1368                 :            : 
    1369                 :            :                             // scale values are divided by bitmap pixel sizes
    1370                 :          0 :                             aTransform.matrix[0] = aFillBitmapSize.getX() / aBmpSizePixel.Width();
    1371                 :          0 :                             aTransform.matrix[4] = aFillBitmapSize.getY() / aBmpSizePixel.Height();
    1372                 :            : 
    1373                 :            :                             // translates are absolute
    1374                 :          0 :                             aTransform.matrix[2] = aFillBitmapTopLeft.getX();
    1375                 :          0 :                             aTransform.matrix[5] = aFillBitmapTopLeft.getY();
    1376                 :            : 
    1377                 :            :                             // setup fill graphic like in impgrfll
    1378         [ #  # ]:          0 :                             Graphic aFillGraphic = Graphic(rBitmapEx);
    1379 [ #  # ][ #  # ]:          0 :                             aFillGraphic.SetPrefMapMode(MapMode(MAP_PIXEL));
                 [ #  # ]
    1380         [ #  # ]:          0 :                             aFillGraphic.SetPrefSize(aBmpSizePixel);
    1381                 :            : 
    1382                 :            :                             pSvtGraphicFill = new SvtGraphicFill(
    1383                 :            :                                 getFillPolyPolygon(aLocalPolyPolygon),
    1384                 :            :                                 Color(),
    1385                 :            :                                 0.0,
    1386                 :            :                                 SvtGraphicFill::fillEvenOdd,
    1387                 :            :                                 SvtGraphicFill::fillTexture,
    1388                 :            :                                 aTransform,
    1389         [ #  # ]:          0 :                                 rFillBitmapAttribute.getTiling(),
    1390                 :            :                                 SvtGraphicFill::hatchSingle,
    1391                 :            :                                 Color(),
    1392                 :            :                                 SvtGraphicFill::gradientLinear,
    1393                 :            :                                 Color(),
    1394                 :            :                                 Color(),
    1395                 :            :                                 0,
    1396 [ #  # ][ #  # ]:          0 :                                 aFillGraphic);
         [ #  # ][ #  # ]
                 [ #  # ]
    1397                 :            :                         }
    1398                 :            : 
    1399                 :            :                         // Do use decomposition; encapsulate with SvtGraphicFill
    1400         [ #  # ]:          0 :                         impStartSvtGraphicFill(pSvtGraphicFill);
    1401 [ #  # ][ #  # ]:          0 :                         process(rCandidate.get2DDecomposition(getViewInformation2D()));
                 [ #  # ]
    1402         [ #  # ]:          0 :                         impEndSvtGraphicFill(pSvtGraphicFill);
    1403                 :            :                     }
    1404                 :            : 
    1405         [ #  # ]:          0 :                     break;
    1406                 :            :                 }
    1407                 :            :                 case PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D :
    1408                 :            :                 {
    1409                 :            :                     // need to handle PolyPolygonHatchPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END
    1410                 :          0 :                     const primitive2d::PolyPolygonHatchPrimitive2D& rHatchCandidate = static_cast< const primitive2d::PolyPolygonHatchPrimitive2D& >(rCandidate);
    1411                 :          0 :                     const attribute::FillHatchAttribute& rFillHatchAttribute = rHatchCandidate.getFillHatch();
    1412         [ #  # ]:          0 :                     basegfx::B2DPolyPolygon aLocalPolyPolygon(rHatchCandidate.getB2DPolyPolygon());
    1413                 :            : 
    1414                 :            :                     // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1415                 :            :                     // per polygon. Split polygon until there are less than that
    1416 [ #  # ][ #  # ]:          0 :                     while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
    1417                 :            :                         ;
    1418                 :            : 
    1419 [ #  # ][ #  # ]:          0 :                     if(rFillHatchAttribute.isFillBackground())
    1420                 :            :                     {
    1421                 :            :                         // with fixing #i111954# (see below) the possible background
    1422                 :            :                         // fill of a hatched object was lost.Generate a background fill
    1423                 :            :                         // primitive and render it
    1424                 :            :                         const primitive2d::Primitive2DReference xBackground(
    1425                 :            :                             new primitive2d::PolyPolygonColorPrimitive2D(
    1426                 :            :                                 aLocalPolyPolygon,
    1427 [ #  # ][ #  # ]:          0 :                                 rHatchCandidate.getBackgroundColor()));
                 [ #  # ]
    1428                 :            : 
    1429 [ #  # ][ #  # ]:          0 :                         process(primitive2d::Primitive2DSequence(&xBackground, 1));
                 [ #  # ]
    1430                 :            :                     }
    1431                 :            : 
    1432                 :          0 :                     SvtGraphicFill* pSvtGraphicFill = 0;
    1433         [ #  # ]:          0 :                     aLocalPolyPolygon.transform(maCurrentTransformation);
    1434                 :            : 
    1435 [ #  # ][ #  # ]:          0 :                     if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
         [ #  # ][ #  # ]
    1436                 :            :                     {
    1437                 :            :                         // re-create a VCL hatch as base data
    1438                 :          0 :                         SvtGraphicFill::HatchType eHatch(SvtGraphicFill::hatchSingle);
    1439                 :            : 
    1440         [ #  # ]:          0 :                         switch(rFillHatchAttribute.getStyle())
              [ #  #  # ]
    1441                 :            :                         {
    1442                 :            :                             default: // attribute::HATCHSTYLE_SINGLE :
    1443                 :            :                             {
    1444                 :          0 :                                 eHatch = SvtGraphicFill::hatchSingle;
    1445                 :          0 :                                 break;
    1446                 :            :                             }
    1447                 :            :                             case attribute::HATCHSTYLE_DOUBLE :
    1448                 :            :                             {
    1449                 :          0 :                                 eHatch = SvtGraphicFill::hatchDouble;
    1450                 :          0 :                                 break;
    1451                 :            :                             }
    1452                 :            :                             case attribute::HATCHSTYLE_TRIPLE :
    1453                 :            :                             {
    1454                 :          0 :                                 eHatch = SvtGraphicFill::hatchTriple;
    1455                 :          0 :                                 break;
    1456                 :            :                             }
    1457                 :            :                         }
    1458                 :            : 
    1459         [ #  # ]:          0 :                         SvtGraphicFill::Transform aTransform;
    1460                 :            : 
    1461                 :            :                         // scale
    1462         [ #  # ]:          0 :                         aTransform.matrix[0] *= rFillHatchAttribute.getDistance();
    1463         [ #  # ]:          0 :                         aTransform.matrix[4] *= rFillHatchAttribute.getDistance();
    1464                 :            : 
    1465                 :            :                         // rotate (was never correct in impgrfll anyways, use correct angle now)
    1466         [ #  # ]:          0 :                         aTransform.matrix[0] *= cos(rFillHatchAttribute.getAngle());
    1467         [ #  # ]:          0 :                         aTransform.matrix[1] *= -sin(rFillHatchAttribute.getAngle());
    1468         [ #  # ]:          0 :                         aTransform.matrix[3] *= sin(rFillHatchAttribute.getAngle());
    1469         [ #  # ]:          0 :                         aTransform.matrix[4] *= cos(rFillHatchAttribute.getAngle());
    1470                 :            : 
    1471                 :            :                         pSvtGraphicFill = new SvtGraphicFill(
    1472                 :            :                             getFillPolyPolygon(aLocalPolyPolygon),
    1473                 :            :                             Color(),
    1474                 :            :                             0.0,
    1475                 :            :                             SvtGraphicFill::fillEvenOdd,
    1476                 :            :                             SvtGraphicFill::fillHatch,
    1477                 :            :                             aTransform,
    1478                 :            :                             false,
    1479                 :            :                             eHatch,
    1480         [ #  # ]:          0 :                             Color(rFillHatchAttribute.getColor()),
    1481                 :            :                             SvtGraphicFill::gradientLinear,
    1482                 :            :                             Color(),
    1483                 :            :                             Color(),
    1484                 :            :                             0,
    1485 [ #  # ][ #  # ]:          0 :                             Graphic());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1486                 :            :                     }
    1487                 :            : 
    1488                 :            :                     // Do use decomposition; encapsulate with SvtGraphicFill
    1489         [ #  # ]:          0 :                     impStartSvtGraphicFill(pSvtGraphicFill);
    1490                 :            : 
    1491                 :            :                     // #i111954# do NOT use decomposition, but use direct VCL-command
    1492                 :            :                     // process(rCandidate.get2DDecomposition(getViewInformation2D()));
    1493         [ #  # ]:          0 :                     const PolyPolygon aToolsPolyPolygon(aLocalPolyPolygon);
    1494                 :            :                     const HatchStyle aHatchStyle(
    1495         [ #  # ]:          0 :                         attribute::HATCHSTYLE_SINGLE == rFillHatchAttribute.getStyle() ? HATCH_SINGLE :
    1496         [ #  # ]:          0 :                         attribute::HATCHSTYLE_DOUBLE == rFillHatchAttribute.getStyle() ? HATCH_DOUBLE :
    1497 [ #  # ][ #  # ]:          0 :                         HATCH_TRIPLE);
    1498                 :            : 
    1499                 :            :                     mpOutputDevice->DrawHatch(aToolsPolyPolygon,
    1500                 :            :                         Hatch(aHatchStyle,
    1501         [ #  # ]:          0 :                             Color(rFillHatchAttribute.getColor()),
    1502                 :            :                             basegfx::fround(rFillHatchAttribute.getDistance()),
    1503 [ #  # ][ #  # ]:          0 :                             basegfx::fround(rFillHatchAttribute.getAngle() / F_PI1800)));
         [ #  # ][ #  # ]
                 [ #  # ]
    1504                 :            : 
    1505         [ #  # ]:          0 :                     impEndSvtGraphicFill(pSvtGraphicFill);
    1506                 :            : 
    1507 [ #  # ][ #  # ]:          0 :                     break;
    1508                 :            :                 }
    1509                 :            :                 case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D :
    1510                 :            :                 {
    1511                 :          0 :                     const primitive2d::PolyPolygonGradientPrimitive2D& rGradientCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate);
    1512         [ #  # ]:          0 :                     basegfx::B2DPolyPolygon aLocalPolyPolygon(rGradientCandidate.getB2DPolyPolygon());
    1513                 :            : 
    1514                 :            :                     // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1515                 :            :                     // per polygon. Split polygon until there are less than that
    1516 [ #  # ][ #  # ]:          0 :                     while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
    1517                 :            :                         ;
    1518                 :            : 
    1519                 :            :                     // for support of MetaCommentActions of the form XGRAD_SEQ_BEGIN, XGRAD_SEQ_END
    1520                 :            :                     // it is safest to use the VCL OutputDevice::DrawGradient method which creates those.
    1521                 :            :                     // re-create a VCL-gradient from FillGradientPrimitive2D and the needed tools PolyPolygon
    1522         [ #  # ]:          0 :                     Gradient aVCLGradient;
    1523         [ #  # ]:          0 :                     impConvertFillGradientAttributeToVCLGradient(aVCLGradient, rGradientCandidate.getFillGradient(), false);
    1524         [ #  # ]:          0 :                     aLocalPolyPolygon.transform(maCurrentTransformation);
    1525                 :            : 
    1526                 :            :                     // #i82145# ATM VCL printing of gradients using curved shapes does not work,
    1527                 :            :                     // i submitted the bug with the given ID to THB. When that task is fixed it is
    1528                 :            :                     // necessary to again remove this subdivision since it decreases possible
    1529                 :            :                     // printing quality (not even resolution-dependent for now). THB will tell
    1530                 :            :                     // me when that task is fixed in the master
    1531                 :            :                     const PolyPolygon aToolsPolyPolygon(
    1532                 :            :                         getFillPolyPolygon(
    1533 [ #  # ][ #  # ]:          0 :                             basegfx::tools::adaptiveSubdivideByAngle(aLocalPolyPolygon)));
                 [ #  # ]
    1534                 :            : 
    1535                 :            :                     // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
    1536                 :          0 :                     SvtGraphicFill* pSvtGraphicFill = 0;
    1537                 :            : 
    1538 [ #  # ][ #  # ]:          0 :                     if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
         [ #  # ][ #  # ]
    1539                 :            :                     {
    1540                 :            :                         // setup gradient stuff like in like in impgrfll
    1541                 :          0 :                         SvtGraphicFill::GradientType eGrad(SvtGraphicFill::gradientLinear);
    1542                 :            : 
    1543      [ #  #  # ]:          0 :                         switch(aVCLGradient.GetStyle())
    1544                 :            :                         {
    1545                 :            :                             default : // GradientStyle_LINEAR:
    1546                 :            :                             case GradientStyle_AXIAL:
    1547                 :          0 :                                 eGrad = SvtGraphicFill::gradientLinear;
    1548                 :          0 :                                 break;
    1549                 :            :                             case GradientStyle_RADIAL:
    1550                 :            :                             case GradientStyle_ELLIPTICAL:
    1551                 :          0 :                                 eGrad = SvtGraphicFill::gradientRadial;
    1552                 :          0 :                                 break;
    1553                 :            :                             case GradientStyle_SQUARE:
    1554                 :            :                             case GradientStyle_RECT:
    1555                 :          0 :                                 eGrad = SvtGraphicFill::gradientRectangular;
    1556                 :          0 :                                 break;
    1557                 :            :                         }
    1558                 :            : 
    1559                 :            :                         pSvtGraphicFill = new SvtGraphicFill(
    1560                 :            :                             aToolsPolyPolygon,
    1561                 :            :                             Color(),
    1562                 :            :                             0.0,
    1563                 :            :                             SvtGraphicFill::fillEvenOdd,
    1564                 :            :                             SvtGraphicFill::fillGradient,
    1565                 :            :                             SvtGraphicFill::Transform(),
    1566                 :            :                             false,
    1567                 :            :                             SvtGraphicFill::hatchSingle,
    1568                 :            :                             Color(),
    1569                 :            :                             eGrad,
    1570                 :          0 :                             aVCLGradient.GetStartColor(),
    1571                 :          0 :                             aVCLGradient.GetEndColor(),
    1572                 :          0 :                             aVCLGradient.GetSteps(),
    1573 [ #  # ][ #  # ]:          0 :                             Graphic());
         [ #  # ][ #  # ]
                 [ #  # ]
    1574                 :            :                     }
    1575                 :            : 
    1576                 :            :                     // call VCL directly; encapsulate with SvtGraphicFill
    1577         [ #  # ]:          0 :                     impStartSvtGraphicFill(pSvtGraphicFill);
    1578         [ #  # ]:          0 :                     mpOutputDevice->DrawGradient(aToolsPolyPolygon, aVCLGradient);
    1579         [ #  # ]:          0 :                     impEndSvtGraphicFill(pSvtGraphicFill);
    1580                 :            : 
    1581                 :            :                     // NO usage of common own gradient randerer, not used ATM for VCL MetaFile, see text above
    1582                 :            :                     // RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate));
    1583                 :            : 
    1584 [ #  # ][ #  # ]:          0 :                     break;
                 [ #  # ]
    1585                 :            :                 }
    1586                 :            :                 case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
    1587                 :            :                 {
    1588                 :       1195 :                     const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate));
    1589         [ +  - ]:       1195 :                     basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
    1590                 :            : 
    1591                 :            :                     // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1592                 :            :                     // per polygon. Split polygon until there are less than that
    1593 [ +  - ][ -  + ]:       1195 :                     while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
    1594                 :            :                         ;
    1595                 :            : 
    1596         [ +  - ]:       1195 :                     const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor()));
    1597         [ +  - ]:       1195 :                     aLocalPolyPolygon.transform(maCurrentTransformation);
    1598                 :            : 
    1599                 :            :                     // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
    1600                 :       1195 :                     SvtGraphicFill* pSvtGraphicFill = 0;
    1601                 :            : 
    1602 [ +  - ][ +  - ]:       1195 :                     if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
         [ +  - ][ +  - ]
    1603                 :            :                     {
    1604                 :            :                         // setup simple color fill stuff like in impgrfll
    1605                 :            :                         pSvtGraphicFill = new SvtGraphicFill(
    1606                 :            :                             getFillPolyPolygon(aLocalPolyPolygon),
    1607                 :            :                             Color(aPolygonColor),
    1608                 :            :                             0.0,
    1609                 :            :                             SvtGraphicFill::fillEvenOdd,
    1610                 :            :                             SvtGraphicFill::fillSolid,
    1611                 :            :                             SvtGraphicFill::Transform(),
    1612                 :            :                             false,
    1613                 :            :                             SvtGraphicFill::hatchSingle,
    1614                 :            :                             Color(),
    1615                 :            :                             SvtGraphicFill::gradientLinear,
    1616                 :            :                             Color(),
    1617                 :            :                             Color(),
    1618                 :            :                             0,
    1619 [ +  - ][ +  - ]:       1195 :                             Graphic());
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    1620                 :            :                     }
    1621                 :            : 
    1622                 :            :                     // set line and fill color
    1623         [ +  - ]:       1195 :                     mpOutputDevice->SetFillColor(Color(aPolygonColor));
    1624         [ +  - ]:       1195 :                     mpOutputDevice->SetLineColor();
    1625                 :            : 
    1626                 :            :                     // call VCL directly; encapsulate with SvtGraphicFill
    1627         [ +  - ]:       1195 :                     impStartSvtGraphicFill(pSvtGraphicFill);
    1628         [ +  - ]:       1195 :                     mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
    1629         [ +  - ]:       1195 :                     impEndSvtGraphicFill(pSvtGraphicFill);
    1630                 :            : 
    1631         [ +  - ]:       1195 :                     break;
    1632                 :            :                 }
    1633                 :            :                 case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
    1634                 :            :                 {
    1635                 :            :                     // direct draw of MetaFile, use default pocessing
    1636                 :          0 :                     RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate));
    1637                 :          0 :                     break;
    1638                 :            :                 }
    1639                 :            :                 case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
    1640                 :            :                 {
    1641                 :            :                     // mask group. Special handling for MetaFiles.
    1642                 :          0 :                     const primitive2d::MaskPrimitive2D& rMaskCandidate = static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate);
    1643                 :            : 
    1644         [ #  # ]:          0 :                     if(rMaskCandidate.getChildren().hasElements())
    1645                 :            :                     {
    1646         [ #  # ]:          0 :                         basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask());
    1647                 :            : 
    1648 [ #  # ][ #  # ]:          0 :                         if(aMask.count())
    1649                 :            :                         {
    1650                 :            :                             // prepare new mask polygon and rescue current one
    1651         [ #  # ]:          0 :                             aMask.transform(maCurrentTransformation);
    1652         [ #  # ]:          0 :                             const basegfx::B2DPolyPolygon aLastClipPolyPolygon(maClipPolyPolygon);
    1653                 :            : 
    1654 [ #  # ][ #  # ]:          0 :                             if(maClipPolyPolygon.count())
    1655                 :            :                             {
    1656                 :            :                                 // there is already a clip polygon set; build clipped union of
    1657                 :            :                                 // current mask polygon and new one
    1658                 :            :                                 maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
    1659                 :            :                                     aMask,
    1660                 :            :                                     maClipPolyPolygon,
    1661                 :            :                                     true, // #i106516# we want the inside of aMask, not the outside
    1662 [ #  # ][ #  # ]:          0 :                                     false);
                 [ #  # ]
    1663                 :            :                             }
    1664                 :            :                             else
    1665                 :            :                             {
    1666                 :            :                                 // use mask directly
    1667         [ #  # ]:          0 :                                 maClipPolyPolygon = aMask;
    1668                 :            :                             }
    1669                 :            : 
    1670 [ #  # ][ #  # ]:          0 :                             if(maClipPolyPolygon.count())
    1671                 :            :                             {
    1672                 :            :                                 // set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!)
    1673                 :            :                                 // Removed subdivision and fixed in Region::ImplPolyPolyRegionToBandRegionFunc() in VCL where
    1674                 :            :                                 // the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there
    1675         [ #  # ]:          0 :                                 mpOutputDevice->Push(PUSH_CLIPREGION);
    1676                 :            :                                 //mpOutputDevice->SetClipRegion(Region(PolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(maClipPolyPolygon))));
    1677 [ #  # ][ #  # ]:          0 :                                 mpOutputDevice->SetClipRegion(Region(PolyPolygon(maClipPolyPolygon)));
         [ #  # ][ #  # ]
                 [ #  # ]
    1678                 :            :                             }
    1679                 :            : 
    1680                 :            :                             // recursively paint content
    1681         [ #  # ]:          0 :                             process(rMaskCandidate.getChildren());
    1682                 :            : 
    1683 [ #  # ][ #  # ]:          0 :                             if(maClipPolyPolygon.count())
    1684                 :            :                             {
    1685                 :            :                                 // restore VCL clip region
    1686         [ #  # ]:          0 :                                 mpOutputDevice->Pop();
    1687                 :            :                             }
    1688                 :            : 
    1689                 :            :                             // restore to rescued clip polygon
    1690 [ #  # ][ #  # ]:          0 :                             maClipPolyPolygon = aLastClipPolyPolygon;
    1691                 :            :                         }
    1692                 :            :                         else
    1693                 :            :                         {
    1694                 :            :                             // no mask, no clipping. recursively paint content
    1695         [ #  # ]:          0 :                             process(rMaskCandidate.getChildren());
    1696         [ #  # ]:          0 :                         }
    1697                 :            :                     }
    1698                 :            : 
    1699                 :          0 :                     break;
    1700                 :            :                 }
    1701                 :            :                 case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D :
    1702                 :            :                 {
    1703                 :            :                     // modified color group. Force output to unified color. Use default pocessing.
    1704                 :          0 :                     RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate));
    1705                 :          0 :                     break;
    1706                 :            :                 }
    1707                 :            :                 case PRIMITIVE2D_ID_HIDDENGEOMETRYPRIMITIVE2D :
    1708                 :            :                 {
    1709                 :            :                     // HiddenGeometryPrimitive2D; to rebuilt the old MetaFile creation, it is necessary to
    1710                 :            :                     // not ignore them (as it was thought), but to add a MetaFile entry for them.
    1711         [ +  - ]:       5756 :                     basegfx::B2DRange aInvisibleRange(rCandidate.getB2DRange(getViewInformation2D()));
    1712                 :            : 
    1713 [ +  - ][ +  - ]:       5756 :                     if(!aInvisibleRange.isEmpty())
    1714                 :            :                     {
    1715         [ +  - ]:       5756 :                         aInvisibleRange.transform(maCurrentTransformation);
    1716                 :            :                         const Rectangle aRectLogic(
    1717 [ +  - ][ +  - ]:       5756 :                             (sal_Int32)floor(aInvisibleRange.getMinX()), (sal_Int32)floor(aInvisibleRange.getMinY()),
    1718 [ +  - ][ +  - ]:      11512 :                             (sal_Int32)ceil(aInvisibleRange.getMaxX()), (sal_Int32)ceil(aInvisibleRange.getMaxY()));
                 [ +  - ]
    1719                 :            : 
    1720         [ +  - ]:       5756 :                         mpOutputDevice->SetFillColor();
    1721         [ +  - ]:       5756 :                         mpOutputDevice->SetLineColor();
    1722         [ +  - ]:       5756 :                         mpOutputDevice->DrawRect(aRectLogic);
    1723                 :            :                     }
    1724                 :            : 
    1725                 :            :                     break;
    1726                 :            :                 }
    1727                 :            :                 case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D :
    1728                 :            :                 {
    1729                 :            :                     // for metafile: Need to examine what the pure vcl version is doing here actually
    1730                 :            :                     // - uses DrawTransparent with metafile for content and a gradient
    1731                 :            :                     // - uses DrawTransparent for single PolyPoylgons directly. Can be detected by
    1732                 :            :                     //   checking the content for single PolyPolygonColorPrimitive2D
    1733                 :          0 :                     const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate);
    1734         [ #  # ]:          0 :                     const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren();
    1735                 :            : 
    1736         [ #  # ]:          0 :                     if(rContent.hasElements())
    1737                 :            :                     {
    1738         [ #  # ]:          0 :                         if(0.0 == rUniTransparenceCandidate.getTransparence())
    1739                 :            :                         {
    1740                 :            :                             // not transparent at all, use content
    1741         [ #  # ]:          0 :                             process(rUniTransparenceCandidate.getChildren());
    1742                 :            :                         }
    1743 [ #  # ][ #  # ]:          0 :                         else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0)
                 [ #  # ]
    1744                 :            :                         {
    1745                 :            :                             // try to identify a single PolyPolygonColorPrimitive2D in the
    1746                 :            :                             // content part of the transparence primitive
    1747                 :          0 :                             const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = 0;
    1748                 :            :                             static bool bForceToMetafile(false);
    1749                 :            : 
    1750 [ #  # ][ #  # ]:          0 :                             if(!bForceToMetafile && 1 == rContent.getLength())
                 [ #  # ]
    1751                 :            :                             {
    1752                 :          0 :                                 const primitive2d::Primitive2DReference xReference(rContent[0]);
    1753 [ #  # ][ #  # ]:          0 :                                 pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get());
    1754                 :            :                             }
    1755                 :            : 
    1756                 :            :                             // PolyPolygonGradientPrimitive2D, PolyPolygonHatchPrimitive2D and
    1757                 :            :                             // PolyPolygonBitmapPrimitive2D are derived from PolyPolygonColorPrimitive2D.
    1758                 :            :                             // Check also for correct ID to exclude derived implementations
    1759 [ #  # ][ #  # ]:          0 :                             if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID())
         [ #  # ][ #  # ]
    1760                 :            :                             {
    1761                 :            :                                 // single transparent PolyPolygon identified, use directly
    1762         [ #  # ]:          0 :                                 const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor()));
    1763         [ #  # ]:          0 :                                 basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon());
    1764                 :            : 
    1765                 :            :                                 // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
    1766                 :            :                                 // per polygon. Split polygon until there are less than that
    1767 [ #  # ][ #  # ]:          0 :                                 while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon))
    1768                 :            :                                     ;
    1769                 :            : 
    1770                 :            :                                 // now transform
    1771         [ #  # ]:          0 :                                 aLocalPolyPolygon.transform(maCurrentTransformation);
    1772                 :            : 
    1773                 :            :                                 // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
    1774                 :          0 :                                 SvtGraphicFill* pSvtGraphicFill = 0;
    1775                 :            : 
    1776 [ #  # ][ #  # ]:          0 :                                 if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
         [ #  # ][ #  # ]
    1777                 :            :                                 {
    1778                 :            :                                     // setup simple color with transparence fill stuff like in impgrfll
    1779                 :            :                                     pSvtGraphicFill = new SvtGraphicFill(
    1780                 :            :                                         getFillPolyPolygon(aLocalPolyPolygon),
    1781                 :            :                                         Color(aPolygonColor),
    1782                 :            :                                         rUniTransparenceCandidate.getTransparence(),
    1783                 :            :                                         SvtGraphicFill::fillEvenOdd,
    1784                 :            :                                         SvtGraphicFill::fillSolid,
    1785                 :            :                                         SvtGraphicFill::Transform(),
    1786                 :            :                                         false,
    1787                 :            :                                         SvtGraphicFill::hatchSingle,
    1788                 :            :                                         Color(),
    1789                 :            :                                         SvtGraphicFill::gradientLinear,
    1790                 :            :                                         Color(),
    1791                 :            :                                         Color(),
    1792                 :            :                                         0,
    1793 [ #  # ][ #  # ]:          0 :                                         Graphic());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1794                 :            :                                 }
    1795                 :            : 
    1796                 :            :                                 // set line and fill color
    1797                 :          0 :                                 const sal_uInt16 nTransPercentVcl((sal_uInt16)basegfx::fround(rUniTransparenceCandidate.getTransparence() * 100.0));
    1798         [ #  # ]:          0 :                                 mpOutputDevice->SetFillColor(Color(aPolygonColor));
    1799         [ #  # ]:          0 :                                 mpOutputDevice->SetLineColor();
    1800                 :            : 
    1801                 :            :                                 // call VCL directly; encapsulate with SvtGraphicFill
    1802         [ #  # ]:          0 :                                 impStartSvtGraphicFill(pSvtGraphicFill);
    1803                 :            :                                 mpOutputDevice->DrawTransparent(
    1804                 :            :                                     PolyPolygon(aLocalPolyPolygon),
    1805 [ #  # ][ #  # ]:          0 :                                     nTransPercentVcl);
                 [ #  # ]
    1806 [ #  # ][ #  # ]:          0 :                                 impEndSvtGraphicFill(pSvtGraphicFill);
    1807                 :            :                             }
    1808                 :            :                             else
    1809                 :            :                             {
    1810                 :            :                                 // svae old mfCurrentUnifiedTransparence and set new one
    1811                 :            :                                 // so that contained SvtGraphicStroke may use the current one
    1812                 :          0 :                                 const double fLastCurrentUnifiedTransparence(mfCurrentUnifiedTransparence);
    1813                 :            :                                 // #i105377# paint the content metafile opaque as the transparency gets
    1814                 :            :                                 // split of into the gradient below
    1815                 :            :                                 // mfCurrentUnifiedTransparence = rUniTransparenceCandidate.getTransparence();
    1816                 :          0 :                                 mfCurrentUnifiedTransparence = 0;
    1817                 :            : 
    1818                 :            :                                 // various content, create content-metafile
    1819         [ #  # ]:          0 :                                 GDIMetaFile aContentMetafile;
    1820         [ #  # ]:          0 :                                 const Rectangle aPrimitiveRectangle(impDumpToMetaFile(rContent, aContentMetafile));
    1821                 :            : 
    1822                 :            :                                 // restore mfCurrentUnifiedTransparence; it may have been used
    1823                 :            :                                 // while processing the sub-content in impDumpToMetaFile
    1824                 :          0 :                                 mfCurrentUnifiedTransparence = fLastCurrentUnifiedTransparence;
    1825                 :            : 
    1826                 :            :                                 // create uniform VCL gradient for uniform transparency
    1827         [ #  # ]:          0 :                                 Gradient aVCLGradient;
    1828                 :          0 :                                 const sal_uInt8 nTransPercentVcl((sal_uInt8)basegfx::fround(rUniTransparenceCandidate.getTransparence() * 255.0));
    1829                 :          0 :                                 const Color aTransColor(nTransPercentVcl, nTransPercentVcl, nTransPercentVcl);
    1830                 :            : 
    1831         [ #  # ]:          0 :                                 aVCLGradient.SetStyle(GradientStyle_LINEAR);
    1832         [ #  # ]:          0 :                                 aVCLGradient.SetStartColor(aTransColor);
    1833         [ #  # ]:          0 :                                 aVCLGradient.SetEndColor(aTransColor);
    1834         [ #  # ]:          0 :                                 aVCLGradient.SetAngle(0);
    1835         [ #  # ]:          0 :                                 aVCLGradient.SetBorder(0);
    1836         [ #  # ]:          0 :                                 aVCLGradient.SetOfsX(0);
    1837         [ #  # ]:          0 :                                 aVCLGradient.SetOfsY(0);
    1838         [ #  # ]:          0 :                                 aVCLGradient.SetStartIntensity(100);
    1839         [ #  # ]:          0 :                                 aVCLGradient.SetEndIntensity(100);
    1840         [ #  # ]:          0 :                                 aVCLGradient.SetSteps(2);
    1841                 :            : 
    1842                 :            :                                 // render it to VCL
    1843                 :            :                                 mpOutputDevice->DrawTransparent(
    1844                 :            :                                     aContentMetafile, aPrimitiveRectangle.TopLeft(),
    1845 [ #  # ][ #  # ]:          0 :                                     aPrimitiveRectangle.GetSize(), aVCLGradient);
         [ #  # ][ #  # ]
    1846                 :            :                             }
    1847                 :            :                         }
    1848                 :            :                     }
    1849                 :            : 
    1850         [ #  # ]:          0 :                     break;
    1851                 :            :                 }
    1852                 :            :                 case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D :
    1853                 :            :                 {
    1854                 :            :                     // for metafile: Need to examine what the pure vcl version is doing here actually
    1855                 :            :                     // - uses DrawTransparent with metafile for content and a gradient
    1856                 :            :                     // i can detect this here with checking the gradient part for a single
    1857                 :            :                     // FillGradientPrimitive2D and reconstruct the gradient.
    1858                 :            :                     // If that detection goes wrong, i have to create an transparence-blended bitmap. Eventually
    1859                 :            :                     // do that in stripes, else RenderTransparencePrimitive2D may just be used
    1860                 :          0 :                     const primitive2d::TransparencePrimitive2D& rTransparenceCandidate = static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate);
    1861         [ #  # ]:          0 :                     const primitive2d::Primitive2DSequence rContent = rTransparenceCandidate.getChildren();
    1862         [ #  # ]:          0 :                     const primitive2d::Primitive2DSequence rTransparence = rTransparenceCandidate.getTransparence();
    1863                 :            : 
    1864 [ #  # ][ #  # ]:          0 :                     if(rContent.hasElements() && rTransparence.hasElements())
                 [ #  # ]
    1865                 :            :                     {
    1866                 :            :                         // try to identify a single FillGradientPrimitive2D in the
    1867                 :            :                         // transparence part of the primitive
    1868                 :          0 :                         const primitive2d::FillGradientPrimitive2D* pFiGradient = 0;
    1869                 :            :                         static bool bForceToBigTransparentVDev(false);
    1870                 :            : 
    1871 [ #  # ][ #  # ]:          0 :                         if(!bForceToBigTransparentVDev && 1 == rTransparence.getLength())
                 [ #  # ]
    1872                 :            :                         {
    1873                 :          0 :                             const primitive2d::Primitive2DReference xReference(rTransparence[0]);
    1874 [ #  # ][ #  # ]:          0 :                             pFiGradient = dynamic_cast< const primitive2d::FillGradientPrimitive2D* >(xReference.get());
    1875                 :            :                         }
    1876                 :            : 
    1877                 :            :                         // Check also for correct ID to exclude derived implementations
    1878 [ #  # ][ #  # ]:          0 :                         if(pFiGradient && PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D == pFiGradient->getPrimitive2DID())
         [ #  # ][ #  # ]
    1879                 :            :                         {
    1880                 :            :                             // various content, create content-metafile
    1881         [ #  # ]:          0 :                             GDIMetaFile aContentMetafile;
    1882         [ #  # ]:          0 :                             const Rectangle aPrimitiveRectangle(impDumpToMetaFile(rContent, aContentMetafile));
    1883                 :            : 
    1884                 :            :                             // re-create a VCL-gradient from FillGradientPrimitive2D
    1885         [ #  # ]:          0 :                             Gradient aVCLGradient;
    1886         [ #  # ]:          0 :                             impConvertFillGradientAttributeToVCLGradient(aVCLGradient, pFiGradient->getFillGradient(), true);
    1887                 :            : 
    1888                 :            :                             // render it to VCL
    1889                 :            :                             mpOutputDevice->DrawTransparent(
    1890                 :            :                                 aContentMetafile, aPrimitiveRectangle.TopLeft(),
    1891 [ #  # ][ #  # ]:          0 :                                 aPrimitiveRectangle.GetSize(), aVCLGradient);
         [ #  # ][ #  # ]
    1892                 :            :                         }
    1893                 :            :                         else
    1894                 :            :                         {
    1895                 :            :                             // sub-transparence group. Draw to VDev first.
    1896                 :            :                             // this may get refined to tiling when resolution is too big here
    1897                 :            : 
    1898                 :            :                             // need to avoid switching off MapMode stuff here; maybe need another
    1899                 :            :                             // tooling class, cannot just do the same as with the pixel renderer.
    1900                 :            :                             // Need to experiment...
    1901                 :            : 
    1902                 :            :                             // Okay, basic implementation finished and tested. The DPI stuff was hard
    1903                 :            :                             // and not easy to find out that it's needed.
    1904                 :            :                             // Since this will not yet happen normally (as long as noone constructs
    1905                 :            :                             // transparence primitives with non-trivial transparence content) i will for now not
    1906                 :            :                             // refine to tiling here.
    1907                 :            : 
    1908         [ #  # ]:          0 :                             basegfx::B2DRange aViewRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D()));
    1909         [ #  # ]:          0 :                             aViewRange.transform(maCurrentTransformation);
    1910                 :            :                             const Rectangle aRectLogic(
    1911 [ #  # ][ #  # ]:          0 :                                 (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()),
    1912 [ #  # ][ #  # ]:          0 :                                 (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY()));
                 [ #  # ]
    1913         [ #  # ]:          0 :                             const Rectangle aRectPixel(mpOutputDevice->LogicToPixel(aRectLogic));
    1914         [ #  # ]:          0 :                             const Size aSizePixel(aRectPixel.GetSize());
    1915                 :          0 :                             const Point aEmptyPoint;
    1916         [ #  # ]:          0 :                             VirtualDevice aBufferDevice;
    1917                 :            : 
    1918 [ #  # ][ #  # ]:          0 :                             if(aBufferDevice.SetOutputSizePixel(aSizePixel))
    1919                 :            :                             {
    1920                 :            :                                 // create and set MapModes for target devices
    1921         [ #  # ]:          0 :                                 MapMode aNewMapMode(mpOutputDevice->GetMapMode());
    1922         [ #  # ]:          0 :                                 aNewMapMode.SetOrigin(Point(-aRectLogic.Left(), -aRectLogic.Top()));
    1923         [ #  # ]:          0 :                                 aBufferDevice.SetMapMode(aNewMapMode);
    1924                 :            : 
    1925                 :            :                                 // prepare view transformation for target renderers
    1926                 :            :                                 // ATTENTION! Need to apply another scaling because of the potential DPI differences
    1927                 :            :                                 // between Printer and VDev (mpOutputDevice and aBufferDevice here).
    1928                 :            :                                 // To get the DPI, LogicToPixel from (1,1) from MAP_INCH needs to be used.
    1929         [ #  # ]:          0 :                                 basegfx::B2DHomMatrix aViewTransform(aBufferDevice.GetViewTransformation());
    1930 [ #  # ][ #  # ]:          0 :                                 const Size aDPIOld(mpOutputDevice->LogicToPixel(Size(1, 1), MAP_INCH));
                 [ #  # ]
    1931 [ #  # ][ #  # ]:          0 :                                 const Size aDPINew(aBufferDevice.LogicToPixel(Size(1, 1), MAP_INCH));
                 [ #  # ]
    1932                 :          0 :                                 const double fDPIXChange((double)aDPIOld.getWidth() / (double)aDPINew.getWidth());
    1933                 :          0 :                                 const double fDPIYChange((double)aDPIOld.getHeight() / (double)aDPINew.getHeight());
    1934                 :            : 
    1935 [ #  # ][ #  # ]:          0 :                                 if(!basegfx::fTools::equal(fDPIXChange, 1.0) || !basegfx::fTools::equal(fDPIYChange, 1.0))
         [ #  # ][ #  # ]
                 [ #  # ]
    1936                 :            :                                 {
    1937         [ #  # ]:          0 :                                     aViewTransform.scale(fDPIXChange, fDPIYChange);
    1938                 :            :                                 }
    1939                 :            : 
    1940                 :            :                                 // create view information and pixel renderer. Reuse known ViewInformation
    1941                 :            :                                 // except new transformation and range
    1942                 :            :                                 const geometry::ViewInformation2D aViewInfo(
    1943         [ #  # ]:          0 :                                     getViewInformation2D().getObjectTransformation(),
    1944                 :            :                                     aViewTransform,
    1945                 :            :                                     aViewRange,
    1946         [ #  # ]:          0 :                                     getViewInformation2D().getVisualizedPage(),
    1947                 :          0 :                                     getViewInformation2D().getViewTime(),
    1948   [ #  #  #  # ]:          0 :                                     getViewInformation2D().getExtendedInformationSequence());
                 [ #  # ]
    1949                 :            : 
    1950         [ #  # ]:          0 :                                 VclPixelProcessor2D aBufferProcessor(aViewInfo, aBufferDevice);
    1951                 :            : 
    1952                 :            :                                 // draw content using pixel renderer
    1953         [ #  # ]:          0 :                                 aBufferProcessor.process(rContent);
    1954         [ #  # ]:          0 :                                 const Bitmap aBmContent(aBufferDevice.GetBitmap(aEmptyPoint, aSizePixel));
    1955                 :            : 
    1956                 :            :                                 // draw transparence using pixel renderer
    1957         [ #  # ]:          0 :                                 aBufferDevice.Erase();
    1958         [ #  # ]:          0 :                                 aBufferProcessor.process(rTransparence);
    1959 [ #  # ][ #  # ]:          0 :                                 const AlphaMask aBmAlpha(aBufferDevice.GetBitmap(aEmptyPoint, aSizePixel));
                 [ #  # ]
    1960                 :            : 
    1961                 :            :                                 // paint
    1962                 :            :                                 mpOutputDevice->DrawBitmapEx(
    1963                 :            :                                     aRectLogic.TopLeft(),
    1964                 :            :                                     aRectLogic.GetSize(),
    1965 [ #  # ][ #  # ]:          0 :                                     BitmapEx(aBmContent, aBmAlpha));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1966         [ #  # ]:          0 :                             }
    1967                 :            :                         }
    1968                 :            :                     }
    1969                 :            : 
    1970 [ #  # ][ #  # ]:          0 :                     break;
    1971                 :            :                 }
    1972                 :            :                 case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D :
    1973                 :            :                 {
    1974                 :            :                     // use default transform group pocessing
    1975                 :          0 :                     RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate));
    1976                 :          0 :                     break;
    1977                 :            :                 }
    1978                 :            :                 case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D :
    1979                 :            :                 {
    1980                 :            :                     // new XDrawPage for ViewInformation2D
    1981                 :          0 :                     RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate));
    1982                 :          0 :                     break;
    1983                 :            :                 }
    1984                 :            :                 case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
    1985                 :            :                 {
    1986                 :            :                     // use default marker array pocessing
    1987                 :          0 :                     RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate));
    1988                 :          0 :                     break;
    1989                 :            :                 }
    1990                 :            :                 case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
    1991                 :            :                 {
    1992                 :            :                     // use default point array pocessing
    1993                 :          0 :                     RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate));
    1994                 :          0 :                     break;
    1995                 :            :                 }
    1996                 :            :                 case PRIMITIVE2D_ID_CHARTPRIMITIVE2D :
    1997                 :            :                 {
    1998                 :            :                     // ChartPrimitive2D
    1999                 :          0 :                     const primitive2d::ChartPrimitive2D& rChartPrimitive = static_cast< const primitive2d::ChartPrimitive2D& >(rCandidate);
    2000                 :            : 
    2001         [ #  # ]:          0 :                     if(!renderChartPrimitive2D(
    2002                 :            :                         rChartPrimitive,
    2003                 :            :                         *mpOutputDevice,
    2004                 :          0 :                         getViewInformation2D()))
    2005                 :            :                     {
    2006                 :            :                         // fallback to decomposition (MetaFile)
    2007         [ #  # ]:          0 :                         process(rChartPrimitive.get2DDecomposition(getViewInformation2D()));
    2008                 :            :                     }
    2009                 :          0 :                     break;
    2010                 :            :                 }
    2011                 :            :                 case PRIMITIVE2D_ID_STRUCTURETAGPRIMITIVE2D :
    2012                 :            :                 {
    2013                 :            :                     // structured tag primitive
    2014                 :          0 :                     const primitive2d::StructureTagPrimitive2D& rStructureTagCandidate = static_cast< const primitive2d::StructureTagPrimitive2D& >(rCandidate);
    2015                 :          0 :                     const vcl::PDFWriter::StructElement& rTagElement(rStructureTagCandidate.getStructureElement());
    2016                 :          0 :                     const bool bTagUsed(vcl::PDFWriter::NonStructElement != rTagElement);
    2017                 :            : 
    2018 [ #  # ][ #  # ]:          0 :                     if(mpPDFExtOutDevData &&  bTagUsed)
    2019                 :            :                     {
    2020                 :            :                         // write start tag
    2021         [ #  # ]:          0 :                         mpPDFExtOutDevData->BeginStructureElement(rTagElement);
    2022                 :            :                     }
    2023                 :            : 
    2024                 :            :                     // proccess children normally
    2025                 :          0 :                     process(rStructureTagCandidate.getChildren());
    2026                 :            : 
    2027 [ #  # ][ #  # ]:          0 :                     if(mpPDFExtOutDevData &&  bTagUsed)
    2028                 :            :                     {
    2029                 :            :                         // write end tag
    2030                 :          0 :                         mpPDFExtOutDevData->EndStructureElement();
    2031                 :            :                     }
    2032                 :            : 
    2033                 :          0 :                     break;
    2034                 :            :                 }
    2035                 :            :                 case PRIMITIVE2D_ID_EPSPRIMITIVE2D :
    2036                 :            :                 {
    2037                 :          0 :                     RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate));
    2038                 :          0 :                     break;
    2039                 :            :                 }
    2040                 :            :                 default :
    2041                 :            :                 {
    2042                 :            :                     // process recursively
    2043         [ +  - ]:      15713 :                     process(rCandidate.get2DDecomposition(getViewInformation2D()));
    2044                 :      15713 :                     break;
    2045                 :            :                 }
    2046                 :            :             }
    2047                 :      49334 :         }
    2048                 :            :     } // end of namespace processor2d
    2049 [ +  - ][ +  - ]:        735 : } // end of namespace drawinglayer
    2050                 :            : 
    2051                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10