LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/gdi - outdev.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 921 1319 69.8 %
Date: 2013-07-09 Functions: 64 74 86.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <tools/debug.hxx>
      21             : #include <tools/poly.hxx>
      22             : 
      23             : #include <vcl/svapp.hxx>
      24             : #include <vcl/ctrl.hxx>
      25             : #include <vcl/region.hxx>
      26             : #include <vcl/virdev.hxx>
      27             : #include <vcl/window.hxx>
      28             : #include <vcl/metaact.hxx>
      29             : #include <vcl/gdimtf.hxx>
      30             : #include <vcl/print.hxx>
      31             : #include <vcl/outdev.hxx>
      32             : #include <vcl/unowrap.hxx>
      33             : #include <svsys.h>
      34             : #include <vcl/sysdata.hxx>
      35             : 
      36             : #include <salgdi.hxx>
      37             : #include <sallayout.hxx>
      38             : #include <salframe.hxx>
      39             : #include <salvd.hxx>
      40             : #include <salprn.hxx>
      41             : #include <svdata.hxx>
      42             : #include <window.h>
      43             : #include <outdev.h>
      44             : #include <outdata.hxx>
      45             : 
      46             : #include <basegfx/point/b2dpoint.hxx>
      47             : #include <basegfx/vector/b2dvector.hxx>
      48             : #include <basegfx/polygon/b2dpolygon.hxx>
      49             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      50             : #include <basegfx/matrix/b2dhommatrix.hxx>
      51             : #include <basegfx/polygon/b2dpolygontools.hxx>
      52             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      53             : #include <basegfx/polygon/b2dlinegeometry.hxx>
      54             : 
      55             : #include <com/sun/star/awt/XGraphics.hpp>
      56             : #include <com/sun/star/uno/Sequence.hxx>
      57             : #include <com/sun/star/rendering/XCanvas.hpp>
      58             : #include <com/sun/star/rendering/CanvasFactory.hpp>
      59             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      60             : #include <comphelper/processfactory.hxx>
      61             : 
      62             : #include <numeric>
      63             : 
      64             : using namespace ::com::sun::star;
      65             : 
      66             : DBG_NAME( OutputDevice )
      67             : #ifdef DISABLE_DYNLOADING
      68             : // Linking all needed LO code into one .so/executable, these already
      69             : // exist in the tools library, so put them in the anonymous namespace
      70             : // here to avoid clash...
      71             : namespace {
      72             : #endif
      73             : DBG_NAME( Polygon )
      74             : DBG_NAME( PolyPolygon )
      75             : #ifdef DISABLE_DYNLOADING
      76             : }
      77             : #endif
      78             : DBG_NAMEEX( Region )
      79             : 
      80             : #ifdef DBG_UTIL
      81             : const char* ImplDbgCheckOutputDevice( const void* pObj )
      82             : {
      83             :     DBG_TESTSOLARMUTEX();
      84             : 
      85             :     const OutputDevice* pOutDev = (OutputDevice*)pObj;
      86             : 
      87             :     if ( (pOutDev->GetOutDevType() != OUTDEV_DONTKNOW) &&
      88             :          (pOutDev->GetOutDevType() != OUTDEV_WINDOW) &&
      89             :          (pOutDev->GetOutDevType() != OUTDEV_PRINTER) &&
      90             :          (pOutDev->GetOutDevType() != OUTDEV_VIRDEV) )
      91             :         return "OutputDevice data overwrite";
      92             : 
      93             :     return NULL;
      94             : }
      95             : #endif
      96             : 
      97             : // =======================================================================
      98             : 
      99             : #define OUTDEV_POLYPOLY_STACKBUF        32
     100             : 
     101             : // =======================================================================
     102             : 
     103             : struct ImplObjStack
     104             : {
     105             :     ImplObjStack*   mpPrev;
     106             :     MapMode*        mpMapMode;
     107             :     bool            mbMapActive;
     108             :     Region*         mpClipRegion;
     109             :     Color*          mpLineColor;
     110             :     Color*          mpFillColor;
     111             :     Font*           mpFont;
     112             :     Color*          mpTextColor;
     113             :     Color*          mpTextFillColor;
     114             :     Color*          mpTextLineColor;
     115             :     Color*          mpOverlineColor;
     116             :     Point*          mpRefPoint;
     117             :     TextAlign       meTextAlign;
     118             :     RasterOp        meRasterOp;
     119             :     sal_uLong           mnTextLayoutMode;
     120             :     LanguageType    meTextLanguage;
     121             :     sal_uInt16          mnFlags;
     122             : };
     123             : 
     124      618993 : static void ImplDeleteObjStack( ImplObjStack* pObjStack )
     125             : {
     126      618993 :     if ( pObjStack->mnFlags & PUSH_LINECOLOR )
     127             :     {
     128      108238 :         if ( pObjStack->mpLineColor )
     129       78332 :             delete pObjStack->mpLineColor;
     130             :     }
     131      618993 :     if ( pObjStack->mnFlags & PUSH_FILLCOLOR )
     132             :     {
     133       85767 :         if ( pObjStack->mpFillColor )
     134       82397 :             delete pObjStack->mpFillColor;
     135             :     }
     136      618993 :     if ( pObjStack->mnFlags & PUSH_FONT )
     137       74785 :         delete pObjStack->mpFont;
     138      618993 :     if ( pObjStack->mnFlags & PUSH_TEXTCOLOR )
     139       68223 :         delete pObjStack->mpTextColor;
     140      618993 :     if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR )
     141             :     {
     142       34102 :         if ( pObjStack->mpTextFillColor )
     143         396 :             delete pObjStack->mpTextFillColor;
     144             :     }
     145      618993 :     if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR )
     146             :     {
     147       34102 :         if ( pObjStack->mpTextLineColor )
     148         512 :             delete pObjStack->mpTextLineColor;
     149             :     }
     150      618993 :     if ( pObjStack->mnFlags & PUSH_OVERLINECOLOR )
     151             :     {
     152       34102 :         if ( pObjStack->mpOverlineColor )
     153         510 :             delete pObjStack->mpOverlineColor;
     154             :     }
     155      618993 :     if ( pObjStack->mnFlags & PUSH_MAPMODE )
     156             :     {
     157       98390 :         if ( pObjStack->mpMapMode )
     158       98390 :             delete pObjStack->mpMapMode;
     159             :     }
     160      618993 :     if ( pObjStack->mnFlags & PUSH_CLIPREGION )
     161             :     {
     162      306532 :         if ( pObjStack->mpClipRegion )
     163      159409 :             delete pObjStack->mpClipRegion;
     164             :     }
     165      618993 :     if ( pObjStack->mnFlags & PUSH_REFPOINT )
     166             :     {
     167       34102 :         if ( pObjStack->mpRefPoint )
     168           0 :             delete pObjStack->mpRefPoint;
     169             :     }
     170             : 
     171      618993 :     delete pObjStack;
     172      618993 : }
     173             : 
     174      256471 : bool OutputDevice::ImplIsAntiparallel() const
     175             : {
     176      256471 :     bool bRet = false;
     177      256471 :     if( ImplGetGraphics() )
     178             :     {
     179      514201 :         if( ( (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && ! IsRTLEnabled() ) ||
     180      504146 :             ( ! (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && IsRTLEnabled() ) )
     181             :         {
     182        1259 :             bRet = true;
     183             :         }
     184             :     }
     185      256471 :     return bRet;
     186             : }
     187             : 
     188      247495 : bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGraphics )
     189             : {
     190             :     DBG_TESTSOLARMUTEX();
     191             : 
     192      247495 :     if( !pGraphics )
     193             :     {
     194      247247 :         if( !mpGraphics )
     195           0 :             if( !ImplGetGraphics() )
     196           0 :                 return false;
     197      247247 :         pGraphics = mpGraphics;
     198             :     }
     199             : 
     200      247495 :     bool bClipRegion = pGraphics->SetClipRegion( rRegion, this );
     201             :     OSL_ENSURE( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" );
     202      247495 :     return bClipRegion;
     203             : }
     204             : 
     205             : 
     206             : // =======================================================================
     207             : 
     208       16400 : Polygon ImplSubdivideBezier( const Polygon& rPoly )
     209             : {
     210       16400 :     Polygon aPoly;
     211             : 
     212             :     // #100127# Use adaptive subdivide instead of fixed 25 segments
     213       16400 :     rPoly.AdaptiveSubdivide( aPoly );
     214             : 
     215       16400 :     return aPoly;
     216             : }
     217             : 
     218             : // =======================================================================
     219             : 
     220        1610 : PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
     221             : {
     222        1610 :     sal_uInt16 i, nPolys = rPolyPoly.Count();
     223        1610 :     PolyPolygon aPolyPoly( nPolys );
     224        6828 :     for( i=0; i<nPolys; ++i )
     225        5218 :         aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );
     226             : 
     227        1610 :     return aPolyPoly;
     228             : }
     229             : 
     230             : // =======================================================================
     231             : 
     232             : // #100127# Extracted from OutputDevice::DrawPolyPolygon()
     233       51035 : void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
     234             : {
     235             :     // AW: This crashes on empty PolyPolygons, avoid that
     236       51035 :     if(!nPoly)
     237       51035 :         return;
     238             : 
     239             :     sal_uInt32          aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
     240             :     PCONSTSALPOINT      aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
     241             :     sal_uInt8*              aStackAry3[OUTDEV_POLYPOLY_STACKBUF];
     242             :     sal_uInt32*         pPointAry;
     243             :     PCONSTSALPOINT*     pPointAryAry;
     244             :     const sal_uInt8**       pFlagAryAry;
     245       51035 :     sal_uInt16              i = 0, j = 0, last = 0;
     246       51035 :     bool                bHaveBezier = false;
     247       51035 :     if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
     248             :     {
     249          66 :         pPointAry       = new sal_uInt32[nPoly];
     250          66 :         pPointAryAry    = new PCONSTSALPOINT[nPoly];
     251          66 :         pFlagAryAry     = new const sal_uInt8*[nPoly];
     252             :     }
     253             :     else
     254             :     {
     255       50969 :         pPointAry       = aStackAry1;
     256       50969 :         pPointAryAry    = aStackAry2;
     257       50969 :         pFlagAryAry     = (const sal_uInt8**)aStackAry3;
     258             :     }
     259       58953 :     do
     260             :     {
     261       58953 :         const Polygon&  rPoly = rPolyPoly.GetObject( i );
     262       58953 :         sal_uInt16          nSize = rPoly.GetSize();
     263       58953 :         if ( nSize )
     264             :         {
     265       58953 :             pPointAry[j]    = nSize;
     266       58953 :             pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
     267       58953 :             pFlagAryAry[j]  = rPoly.GetConstFlagAry();
     268       58953 :             last            = i;
     269             : 
     270       58953 :             if( pFlagAryAry[j] )
     271        9270 :                 bHaveBezier = true;
     272             : 
     273       58953 :             ++j;
     274             :         }
     275             : 
     276       58953 :         ++i;
     277             :     }
     278             :     while ( i < nPoly );
     279             : 
     280       51035 :     if ( j == 1 )
     281             :     {
     282             :         // #100127# Forward beziers to sal, if any
     283       47627 :         if( bHaveBezier )
     284             :         {
     285        5203 :             if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
     286             :             {
     287        5203 :                 Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
     288        5203 :                 mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
     289             :             }
     290             :         }
     291             :         else
     292             :         {
     293       42424 :             mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
     294             :         }
     295             :     }
     296             :     else
     297             :     {
     298             :         // #100127# Forward beziers to sal, if any
     299        3408 :         if( bHaveBezier )
     300             :         {
     301        1610 :             if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
     302             :             {
     303        1610 :                 PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
     304        1610 :                 ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
     305             :             }
     306             :         }
     307             :         else
     308             :         {
     309        1798 :             mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
     310             :         }
     311             :     }
     312             : 
     313       51035 :     if ( pPointAry != aStackAry1 )
     314             :     {
     315          66 :         delete[] pPointAry;
     316          66 :         delete[] pPointAryAry;
     317          66 :         delete[] pFlagAryAry;
     318             :     }
     319             : }
     320             : 
     321             : // =======================================================================
     322             : 
     323      141800 : OutputDevice::OutputDevice() :
     324             :     maRegion(true),
     325             :     maFillColor( COL_WHITE ),
     326             :     maTextLineColor( COL_TRANSPARENT ),
     327      141800 :     maSettings( Application::GetSettings() )
     328             : {
     329             :     DBG_CTOR( OutputDevice, ImplDbgCheckOutputDevice );
     330             : 
     331      141800 :     mpGraphics          = NULL;
     332      141800 :     mpUnoGraphicsList   = NULL;
     333      141800 :     mpPrevGraphics      = NULL;
     334      141800 :     mpNextGraphics      = NULL;
     335      141800 :     mpMetaFile          = NULL;
     336      141800 :     mpFontEntry         = NULL;
     337      141800 :     mpFontCache         = NULL;
     338      141800 :     mpFontList          = NULL;
     339      141800 :     mpGetDevFontList    = NULL;
     340      141800 :     mpGetDevSizeList    = NULL;
     341      141800 :     mpObjStack          = NULL;
     342      141800 :     mpOutDevData        = NULL;
     343      141800 :     mpPDFWriter         = NULL;
     344      141800 :     mpAlphaVDev         = NULL;
     345      141800 :     mpExtOutDevData     = NULL;
     346      141800 :     mnOutOffX           = 0;
     347      141800 :     mnOutOffY           = 0;
     348      141800 :     mnOutWidth          = 0;
     349      141800 :     mnOutHeight         = 0;
     350      141800 :     mnDPIX              = 0;
     351      141800 :     mnDPIY              = 0;
     352      141800 :     mnTextOffX          = 0;
     353      141800 :     mnTextOffY          = 0;
     354      141800 :     mnOutOffOrigX       = 0;
     355      141800 :     mnOutOffLogicX      = 0;
     356      141800 :     mnOutOffOrigY       = 0;
     357      141800 :     mnOutOffLogicY      = 0;
     358      141800 :     mnEmphasisAscent    = 0;
     359      141800 :     mnEmphasisDescent   = 0;
     360      141800 :     mnDrawMode          = 0;
     361      141800 :     mnTextLayoutMode        = TEXT_LAYOUT_DEFAULT;
     362      141800 :     if( Application::GetSettings().GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
     363           0 :         mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
     364      141800 :     meOutDevType        = OUTDEV_DONTKNOW;
     365      141800 :     meOutDevViewType    = OUTDEV_VIEWTYPE_DONTKNOW;
     366      141800 :     mbMap               = sal_False;
     367      141800 :     mbMapIsDefault      = sal_True;
     368      141800 :     mbClipRegion        = sal_False;
     369      141800 :     mbBackground        = sal_False;
     370      141800 :     mbOutput            = sal_True;
     371      141800 :     mbDevOutput         = sal_False;
     372      141800 :     mbOutputClipped     = sal_False;
     373      141800 :     maTextColor         = Color( COL_BLACK );
     374      141800 :     maOverlineColor     = Color( COL_TRANSPARENT );
     375      141800 :     meTextAlign         = maFont.GetAlign();
     376      141800 :     meRasterOp          = ROP_OVERPAINT;
     377      141800 :     mnAntialiasing      = 0;
     378      141800 :     meTextLanguage      = 0;  // TODO: get default from configuration?
     379      141800 :     mbLineColor         = sal_True;
     380      141800 :     mbFillColor         = sal_True;
     381      141800 :     mbInitLineColor     = sal_True;
     382      141800 :     mbInitFillColor     = sal_True;
     383      141800 :     mbInitFont          = sal_True;
     384      141800 :     mbInitTextColor     = sal_True;
     385      141800 :     mbInitClipRegion    = sal_True;
     386      141800 :     mbClipRegionSet     = sal_False;
     387      141800 :     mbKerning           = sal_False;
     388      141800 :     mbNewFont           = sal_True;
     389      141800 :     mbTextLines         = sal_False;
     390      141800 :     mbTextSpecial       = sal_False;
     391      141800 :     mbRefPoint          = sal_False;
     392      141800 :     mbEnableRTL         = sal_False;    // mirroring must be explicitly allowed (typically for windows only)
     393             : 
     394             :     // struct ImplMapRes
     395      141800 :     maMapRes.mnMapOfsX          = 0;
     396      141800 :     maMapRes.mnMapOfsY          = 0;
     397      141800 :     maMapRes.mnMapScNumX        = 1;
     398      141800 :     maMapRes.mnMapScNumY        = 1;
     399      141800 :     maMapRes.mnMapScDenomX      = 1;
     400      141800 :     maMapRes.mnMapScDenomY      = 1;
     401             :     // struct ImplThresholdRes
     402      141800 :     maThresRes.mnThresLogToPixX = 0;
     403      141800 :     maThresRes.mnThresLogToPixY = 0;
     404      141800 :     maThresRes.mnThresPixToLogX = 0;
     405      141800 :     maThresRes.mnThresPixToLogY = 0;
     406      141800 : }
     407             : 
     408      282704 : OutputDevice::~OutputDevice()
     409             : {
     410             :     DBG_DTOR( OutputDevice, ImplDbgCheckOutputDevice );
     411             : 
     412      141352 :     if ( GetUnoGraphicsList() )
     413             :     {
     414        1149 :         UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False );
     415        1149 :         if ( pWrapper )
     416        1149 :             pWrapper->ReleaseAllGraphics( this );
     417        1149 :         delete mpUnoGraphicsList;
     418        1149 :         mpUnoGraphicsList = NULL;
     419             :     }
     420             : 
     421      141352 :     if ( mpOutDevData )
     422        1272 :         ImplDeInitOutDevData();
     423             : 
     424      141352 :     ImplObjStack* pData = mpObjStack;
     425      141352 :     if ( pData )
     426             :     {
     427             :         SAL_WARN( "vcl.gdi", "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
     428           0 :         while ( pData )
     429             :         {
     430           0 :             ImplObjStack* pTemp = pData;
     431           0 :             pData = pData->mpPrev;
     432           0 :             ImplDeleteObjStack( pTemp );
     433             :         }
     434             :     }
     435             : 
     436             :     // release the active font instance
     437      141352 :     if( mpFontEntry )
     438           0 :         mpFontCache->Release( mpFontEntry );
     439             :     // remove cached results of GetDevFontList/GetDevSizeList
     440             :     // TODO: use smart pointers for them
     441      141352 :     if( mpGetDevFontList )
     442           0 :         delete mpGetDevFontList;
     443      141352 :     if( mpGetDevSizeList )
     444           0 :         delete mpGetDevSizeList;
     445             : 
     446             :     // release ImplFontCache specific to this OutputDevice
     447             :     // TODO: refcount ImplFontCache
     448      141352 :     if( mpFontCache
     449      141272 :     && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
     450      142561 :     && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
     451             :     {
     452        1209 :         delete mpFontCache;
     453        1209 :         mpFontCache = NULL;
     454             :     }
     455             : 
     456             :     // release ImplFontList specific to this OutputDevice
     457             :     // TODO: refcount ImplFontList
     458      141352 :     if( mpFontList
     459      141348 :     && (mpFontList != ImplGetSVData()->maGDIData.mpScreenFontList)
     460      142637 :     && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
     461             :     {
     462        1285 :         mpFontList->Clear();
     463        1285 :         delete mpFontList;
     464        1285 :         mpFontList = NULL;
     465             :     }
     466             : 
     467      141352 :     delete mpAlphaVDev;
     468      141352 : }
     469             : 
     470        8129 : bool OutputDevice::supportsOperation( OutDevSupportType eType ) const
     471             : {
     472        8129 :     if( !mpGraphics )
     473           0 :         if( !ImplGetGraphics() )
     474           0 :             return false;
     475        8129 :     const bool bHasSupport = mpGraphics->supportsOperation( eType );
     476        8129 :     return bHasSupport;
     477             : }
     478             : 
     479       33499 : void OutputDevice::EnableRTL( sal_Bool bEnable )
     480             : {
     481       33499 :     mbEnableRTL = (bEnable != 0);
     482       33499 :     if( meOutDevType == OUTDEV_VIRDEV )
     483             :     {
     484             :         // virdevs default to not mirroring, they will only be set to mirroring
     485             :         // under rare circumstances in the UI, eg the valueset control
     486             :         // because each virdev has its own SalGraphics we can safely switch the SalGraphics here
     487             :         // ...hopefully
     488       14932 :         if( ImplGetGraphics() )
     489       14932 :             mpGraphics->SetLayout( mbEnableRTL ? SAL_LAYOUT_BIDI_RTL : 0 );
     490             :     }
     491             : 
     492             :     // convenience: for controls also switch layout mode
     493       33499 :     if( dynamic_cast<Control*>(this) != 0 )
     494       13991 :         SetLayoutMode( bEnable ? TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT : TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_TEXTORIGIN_LEFT);
     495             : 
     496       33499 :     Window* pWin = dynamic_cast<Window*>(this);
     497       33499 :     if( pWin )
     498       18567 :         pWin->StateChanged( STATE_CHANGE_MIRRORING );
     499             : 
     500       33499 :     if( mpAlphaVDev )
     501        5293 :         mpAlphaVDev->EnableRTL( bEnable );
     502       33499 : }
     503             : 
     504      297238 : sal_Bool OutputDevice::ImplHasMirroredGraphics()
     505             : {
     506             :    // HOTFIX for #i55719#
     507      297238 :    if( meOutDevType == OUTDEV_PRINTER )
     508           0 :        return sal_False;
     509             : 
     510      297238 :    return ( ImplGetGraphics() && (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) );
     511             : }
     512             : 
     513             : // note: the coordiantes to be remirrored are in frame coordiantes !
     514             : 
     515           9 : void    OutputDevice::ImplReMirror( Point &rPoint ) const
     516             : {
     517           9 :     rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
     518           9 : }
     519          14 : void    OutputDevice::ImplReMirror( Rectangle &rRect ) const
     520             : {
     521          14 :     long nWidth = rRect.Right() - rRect.Left();
     522             : 
     523             :     //long lc_x = rRect.nLeft - mnOutOffX;    // normalize
     524             :     //lc_x = mnOutWidth - nWidth - 1 - lc_x;  // mirror
     525             :     //rRect.nLeft = lc_x + mnOutOffX;         // re-normalize
     526             : 
     527          14 :     rRect.Left() = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.Left() + mnOutOffX;
     528          14 :     rRect.Right() = rRect.Left() + nWidth;
     529          14 : }
     530         312 : void    OutputDevice::ImplReMirror( Region &rRegion ) const
     531             : {
     532         312 :     RectangleVector aRectangles;
     533         312 :     rRegion.GetRegionRectangles(aRectangles);
     534         624 :     Region aMirroredRegion;
     535             : 
     536         320 :     for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     537             :     {
     538           8 :         ImplReMirror(*aRectIter);
     539           8 :         aMirroredRegion.Union(*aRectIter);
     540             :     }
     541             : 
     542         624 :     rRegion = aMirroredRegion;
     543             : 
     544             : //  long                nX;
     545             : //  long                nY;
     546             : //  long                nWidth;
     547             : //  long                nHeight;
     548             : //  ImplRegionInfo      aInfo;
     549             : //  sal_Bool                bRegionRect;
     550             : //    Region              aMirroredRegion;
     551             : //
     552             : //  bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
     553             : //  while ( bRegionRect )
     554             : //  {
     555             : //        Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
     556             : //        ImplReMirror( aRect );
     557             : //        aMirroredRegion.Union( aRect );
     558             : //      bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
     559             : //  }
     560             : //    rRegion = aMirroredRegion;
     561         312 : }
     562             : 
     563      681843 : SalGraphics* OutputDevice::ImplGetGraphics() const
     564             : {
     565             :     DBG_TESTSOLARMUTEX();
     566             : 
     567      681843 :     if ( mpGraphics )
     568      535855 :         return mpGraphics;
     569             : 
     570      145988 :     mbInitLineColor     = sal_True;
     571      145988 :     mbInitFillColor     = sal_True;
     572      145988 :     mbInitFont          = sal_True;
     573      145988 :     mbInitTextColor     = sal_True;
     574      145988 :     mbInitClipRegion    = sal_True;
     575             : 
     576      145988 :     ImplSVData* pSVData = ImplGetSVData();
     577      145988 :     if ( meOutDevType == OUTDEV_WINDOW )
     578             :     {
     579       78727 :         Window* pWindow = (Window*)this;
     580             : 
     581       78727 :         mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
     582             :         // try harder if no wingraphics was available directly
     583       78727 :         if ( !mpGraphics )
     584             :         {
     585             :             // find another output device in the same frame
     586           0 :             OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
     587           0 :             while ( pReleaseOutDev )
     588             :             {
     589           0 :                 if ( ((Window*)pReleaseOutDev)->mpWindowImpl->mpFrame == pWindow->mpWindowImpl->mpFrame )
     590           0 :                     break;
     591           0 :                 pReleaseOutDev = pReleaseOutDev->mpPrevGraphics;
     592             :             }
     593             : 
     594           0 :             if ( pReleaseOutDev )
     595             :             {
     596             :                 // steal the wingraphics from the other outdev
     597           0 :                 mpGraphics = pReleaseOutDev->mpGraphics;
     598           0 :                 pReleaseOutDev->ImplReleaseGraphics( sal_False );
     599             :             }
     600             :             else
     601             :             {
     602             :                 // if needed retry after releasing least recently used wingraphics
     603           0 :                 while ( !mpGraphics )
     604             :                 {
     605           0 :                     if ( !pSVData->maGDIData.mpLastWinGraphics )
     606           0 :                         break;
     607           0 :                     pSVData->maGDIData.mpLastWinGraphics->ImplReleaseGraphics();
     608           0 :                     mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
     609             :                 }
     610             :             }
     611             :         }
     612             : 
     613             :         // update global LRU list of wingraphics
     614       78727 :         if ( mpGraphics )
     615             :         {
     616       78727 :             mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics;
     617       78727 :             pSVData->maGDIData.mpFirstWinGraphics = const_cast<OutputDevice*>(this);
     618       78727 :             if ( mpNextGraphics )
     619       78595 :                 mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
     620       78727 :             if ( !pSVData->maGDIData.mpLastWinGraphics )
     621         132 :                 pSVData->maGDIData.mpLastWinGraphics = const_cast<OutputDevice*>(this);
     622             :         }
     623             :     }
     624       67261 :     else if ( meOutDevType == OUTDEV_VIRDEV )
     625             :     {
     626       67109 :         const VirtualDevice* pVirDev = (const VirtualDevice*)this;
     627             : 
     628       67109 :         if ( pVirDev->mpVirDev )
     629             :         {
     630       67109 :             mpGraphics = pVirDev->mpVirDev->GetGraphics();
     631             :             // if needed retry after releasing least recently used virtual device graphics
     632      134218 :             while ( !mpGraphics )
     633             :             {
     634           0 :                 if ( !pSVData->maGDIData.mpLastVirGraphics )
     635           0 :                     break;
     636           0 :                 pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
     637           0 :                 mpGraphics = pVirDev->mpVirDev->GetGraphics();
     638             :             }
     639             :             // update global LRU list of virtual device graphics
     640       67109 :             if ( mpGraphics )
     641             :             {
     642       67109 :                 mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
     643       67109 :                 pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
     644       67109 :                 if ( mpNextGraphics )
     645       66229 :                     mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
     646       67109 :                 if ( !pSVData->maGDIData.mpLastVirGraphics )
     647         880 :                     pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
     648             :             }
     649             :         }
     650             :     }
     651         152 :     else if ( meOutDevType == OUTDEV_PRINTER )
     652             :     {
     653         150 :         const Printer* pPrinter = (const Printer*)this;
     654             : 
     655         150 :         if ( pPrinter->mpJobGraphics )
     656           0 :             mpGraphics = pPrinter->mpJobGraphics;
     657         150 :         else if ( pPrinter->mpDisplayDev )
     658             :         {
     659          70 :             const VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
     660          70 :             mpGraphics = pVirDev->mpVirDev->GetGraphics();
     661             :             // if needed retry after releasing least recently used virtual device graphics
     662         140 :             while ( !mpGraphics )
     663             :             {
     664           0 :                 if ( !pSVData->maGDIData.mpLastVirGraphics )
     665           0 :                     break;
     666           0 :                 pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
     667           0 :                 mpGraphics = pVirDev->mpVirDev->GetGraphics();
     668             :             }
     669             :             // update global LRU list of virtual device graphics
     670          70 :             if ( mpGraphics )
     671             :             {
     672          70 :                 mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
     673          70 :                 pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
     674          70 :                 if ( mpNextGraphics )
     675          70 :                     mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
     676          70 :                 if ( !pSVData->maGDIData.mpLastVirGraphics )
     677           0 :                     pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
     678             :             }
     679             :         }
     680             :         else
     681             :         {
     682          80 :             mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
     683             :             // if needed retry after releasing least recently used printer graphics
     684         160 :             while ( !mpGraphics )
     685             :             {
     686           0 :                 if ( !pSVData->maGDIData.mpLastPrnGraphics )
     687           0 :                     break;
     688           0 :                 pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics();
     689           0 :                 mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
     690             :             }
     691             :             // update global LRU list of printer graphics
     692          80 :             if ( mpGraphics )
     693             :             {
     694          80 :                 mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
     695          80 :                 pSVData->maGDIData.mpFirstPrnGraphics = const_cast<OutputDevice*>(this);
     696          80 :                 if ( mpNextGraphics )
     697          14 :                     mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
     698          80 :                 if ( !pSVData->maGDIData.mpLastPrnGraphics )
     699          66 :                     pSVData->maGDIData.mpLastPrnGraphics = const_cast<OutputDevice*>(this);
     700             :             }
     701             :         }
     702             :     }
     703             : 
     704      145988 :     if ( mpGraphics )
     705             :     {
     706      145986 :         mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
     707      145986 :         mpGraphics->setAntiAliasB2DDraw(mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW);
     708             :     }
     709             : 
     710      145988 :     return mpGraphics;
     711             : }
     712             : 
     713      231102 : void OutputDevice::ImplReleaseGraphics( sal_Bool bRelease )
     714             : {
     715             :     DBG_TESTSOLARMUTEX();
     716             : 
     717      231102 :     if ( !mpGraphics )
     718      316634 :         return;
     719             : 
     720             :     // release the fonts of the physically released graphics device
     721      145570 :     if( bRelease )
     722             :     {
     723             : #ifndef UNX
     724             :         // HACK to fix an urgent P1 printing issue fast
     725             :         // WinSalPrinter does not respect GetGraphics/ReleaseGraphics conventions
     726             :         // so Printer::mpGraphics often points to a dead WinSalGraphics
     727             :         // TODO: fix WinSalPrinter's GetGraphics/ReleaseGraphics handling
     728             :         if( meOutDevType != OUTDEV_PRINTER )
     729             : #endif
     730      145570 :         mpGraphics->ReleaseFonts();
     731             : 
     732      145570 :         mbNewFont = true;
     733      145570 :         mbInitFont = true;
     734             : 
     735      145570 :         if ( mpFontEntry )
     736             :         {
     737       46913 :             mpFontCache->Release( mpFontEntry );
     738       46913 :             mpFontEntry = NULL;
     739             :         }
     740             : 
     741      145570 :         if ( mpGetDevFontList )
     742             :         {
     743        1725 :             delete mpGetDevFontList;
     744        1725 :             mpGetDevFontList = NULL;
     745             :         }
     746             : 
     747      145570 :         if ( mpGetDevSizeList )
     748             :         {
     749         517 :             delete mpGetDevSizeList;
     750         517 :             mpGetDevSizeList = NULL;
     751             :         }
     752             :     }
     753             : 
     754      145570 :     ImplSVData* pSVData = ImplGetSVData();
     755      145570 :     if ( meOutDevType == OUTDEV_WINDOW )
     756             :     {
     757       78402 :         Window* pWindow = (Window*)this;
     758             : 
     759       78402 :         if ( bRelease )
     760       78402 :             pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
     761             :         // remove from global LRU list of window graphics
     762       78402 :         if ( mpPrevGraphics )
     763       66849 :             mpPrevGraphics->mpNextGraphics = mpNextGraphics;
     764             :         else
     765       11553 :             pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics;
     766       78402 :         if ( mpNextGraphics )
     767       78303 :             mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
     768             :         else
     769          99 :             pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics;
     770             :     }
     771       67168 :     else if ( meOutDevType == OUTDEV_VIRDEV )
     772             :     {
     773       67030 :         VirtualDevice* pVirDev = (VirtualDevice*)this;
     774             : 
     775       67030 :         if ( bRelease )
     776       67030 :             pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
     777             :         // remove from global LRU list of virtual device graphics
     778       67030 :         if ( mpPrevGraphics )
     779       25027 :             mpPrevGraphics->mpNextGraphics = mpNextGraphics;
     780             :         else
     781       42003 :             pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
     782       67030 :         if ( mpNextGraphics )
     783       65800 :             mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
     784             :         else
     785        1230 :             pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
     786             :     }
     787         138 :     else if ( meOutDevType == OUTDEV_PRINTER )
     788             :     {
     789         138 :         Printer* pPrinter = (Printer*)this;
     790             : 
     791         138 :         if ( !pPrinter->mpJobGraphics )
     792             :         {
     793         138 :             if ( pPrinter->mpDisplayDev )
     794             :             {
     795          59 :                 VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
     796          59 :                 if ( bRelease )
     797          59 :                     pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
     798             :                 // remove from global LRU list of virtual device graphics
     799          59 :                 if ( mpPrevGraphics )
     800          51 :                     mpPrevGraphics->mpNextGraphics = mpNextGraphics;
     801             :                 else
     802           8 :                     pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
     803          59 :                 if ( mpNextGraphics )
     804          59 :                     mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
     805             :                 else
     806           0 :                     pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
     807             :             }
     808             :             else
     809             :             {
     810          79 :                 if ( bRelease )
     811          79 :                     pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics );
     812             :                 // remove from global LRU list of printer graphics
     813          79 :                 if ( mpPrevGraphics )
     814           0 :                     mpPrevGraphics->mpNextGraphics = mpNextGraphics;
     815             :                 else
     816          79 :                     pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics;
     817          79 :                 if ( mpNextGraphics )
     818          14 :                     mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
     819             :                 else
     820          65 :                     pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics;
     821             :            }
     822             :         }
     823             :     }
     824             : 
     825      145570 :     mpGraphics      = NULL;
     826      145570 :     mpPrevGraphics  = NULL;
     827      145570 :     mpNextGraphics  = NULL;
     828             : }
     829             : 
     830        1274 : void OutputDevice::ImplInitOutDevData()
     831             : {
     832        1274 :     if ( !mpOutDevData )
     833             :     {
     834        1274 :         mpOutDevData = new ImplOutDevData;
     835        1274 :         mpOutDevData->mpRotateDev = NULL;
     836        1274 :         mpOutDevData->mpRecordLayout = NULL;
     837             : 
     838             :         // #i75163#
     839        1274 :         mpOutDevData->mpViewTransform = NULL;
     840        1274 :         mpOutDevData->mpInverseViewTransform = NULL;
     841             :     }
     842        1274 : }
     843             : 
     844             : // #i75163#
     845      158760 : void OutputDevice::ImplInvalidateViewTransform()
     846             : {
     847      158760 :     if(mpOutDevData)
     848             :     {
     849       78563 :         if(mpOutDevData->mpViewTransform)
     850             :         {
     851       24856 :             delete mpOutDevData->mpViewTransform;
     852       24856 :             mpOutDevData->mpViewTransform = NULL;
     853             :         }
     854             : 
     855       78563 :         if(mpOutDevData->mpInverseViewTransform)
     856             :         {
     857       12546 :             delete mpOutDevData->mpInverseViewTransform;
     858       12546 :             mpOutDevData->mpInverseViewTransform = NULL;
     859             :         }
     860             :     }
     861      158760 : }
     862             : 
     863     2214377 : sal_Bool OutputDevice::ImplIsRecordLayout() const
     864             : {
     865     2214377 :     return mpOutDevData && mpOutDevData->mpRecordLayout;
     866             : }
     867             : 
     868        1272 : void OutputDevice::ImplDeInitOutDevData()
     869             : {
     870        1272 :     if ( mpOutDevData )
     871             :     {
     872        1272 :         if ( mpOutDevData->mpRotateDev )
     873           0 :             delete mpOutDevData->mpRotateDev;
     874             : 
     875             :         // #i75163#
     876        1272 :         ImplInvalidateViewTransform();
     877             : 
     878        1272 :         delete mpOutDevData;
     879             :     }
     880        1272 : }
     881             : 
     882      389431 : void OutputDevice::ImplInitLineColor()
     883             : {
     884             :     DBG_TESTSOLARMUTEX();
     885             : 
     886      389431 :     if( mbLineColor )
     887             :     {
     888      195167 :         if( ROP_0 == meRasterOp )
     889           0 :             mpGraphics->SetROPLineColor( SAL_ROP_0 );
     890      195167 :         else if( ROP_1 == meRasterOp )
     891           0 :             mpGraphics->SetROPLineColor( SAL_ROP_1 );
     892      195167 :         else if( ROP_INVERT == meRasterOp )
     893           0 :             mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
     894             :         else
     895      195167 :             mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
     896             :     }
     897             :     else
     898      194264 :         mpGraphics->SetLineColor();
     899             : 
     900      389431 :     mbInitLineColor = sal_False;
     901      389431 : }
     902             : 
     903      339539 : void OutputDevice::ImplInitFillColor()
     904             : {
     905             :     DBG_TESTSOLARMUTEX();
     906             : 
     907      339539 :     if( mbFillColor )
     908             :     {
     909      335347 :         if( ROP_0 == meRasterOp )
     910           0 :             mpGraphics->SetROPFillColor( SAL_ROP_0 );
     911      335347 :         else if( ROP_1 == meRasterOp )
     912           0 :             mpGraphics->SetROPFillColor( SAL_ROP_1 );
     913      335347 :         else if( ROP_INVERT == meRasterOp )
     914           0 :             mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
     915             :         else
     916      335347 :             mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
     917             :     }
     918             :     else
     919        4192 :         mpGraphics->SetFillColor();
     920             : 
     921      339539 :     mbInitFillColor = sal_False;
     922      339539 : }
     923             : 
     924      423789 : void OutputDevice::ImplInitClipRegion()
     925             : {
     926             :     DBG_TESTSOLARMUTEX();
     927             : 
     928      423789 :     if ( GetOutDevType() == OUTDEV_WINDOW )
     929             :     {
     930      320902 :         Window* pWindow = (Window*)this;
     931      320902 :         Region  aRegion;
     932             : 
     933             :         // Hintergrund-Sicherung zuruecksetzen
     934      320902 :         if ( pWindow->mpWindowImpl->mpFrameData->mpFirstBackWin )
     935           0 :             pWindow->ImplInvalidateAllOverlapBackgrounds();
     936      320902 :         if ( pWindow->mpWindowImpl->mbInPaint )
     937      308322 :             aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
     938             :         else
     939             :         {
     940       12580 :             aRegion = *(pWindow->ImplGetWinChildClipRegion());
     941             :             // --- RTL -- only this region is in frame coordinates, so re-mirror it
     942             :             // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) !
     943       12580 :             if( ImplIsAntiparallel() )
     944         304 :                 ImplReMirror ( aRegion );
     945             :         }
     946      320902 :         if ( mbClipRegion )
     947      181019 :             aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
     948      320902 :         if ( aRegion.IsEmpty() )
     949       92305 :             mbOutputClipped = sal_True;
     950             :         else
     951             :         {
     952      228597 :             mbOutputClipped = sal_False;
     953      228597 :             ImplSelectClipRegion( aRegion );
     954             :         }
     955      320902 :         mbClipRegionSet = sal_True;
     956             :     }
     957             :     else
     958             :     {
     959      102887 :         if ( mbClipRegion )
     960             :         {
     961       18759 :             if ( maRegion.IsEmpty() )
     962         107 :                 mbOutputClipped = sal_True;
     963             :             else
     964             :             {
     965       18652 :                 mbOutputClipped = sal_False;
     966             : 
     967             :                 // #102532# Respect output offset also for clip region
     968       18652 :                 Region aRegion( ImplPixelToDevicePixel( maRegion ) );
     969       18652 :                 const bool bClipDeviceBounds( ! GetPDFWriter()
     970       18652 :                                               && GetOutDevType() != OUTDEV_PRINTER );
     971       18652 :                 if( bClipDeviceBounds )
     972             :                 {
     973             :                     // Perform actual rect clip against outdev
     974             :                     // dimensions, to generate empty clips whenever one of the
     975             :                     // values is completely off the device.
     976             :                     Rectangle aDeviceBounds( mnOutOffX, mnOutOffY,
     977       18652 :                                              mnOutOffX+GetOutputWidthPixel()-1,
     978       37304 :                                              mnOutOffY+GetOutputHeightPixel()-1 );
     979       18652 :                     aRegion.Intersect( aDeviceBounds );
     980             :                 }
     981             : 
     982       18652 :                 if ( aRegion.IsEmpty() )
     983             :                 {
     984           2 :                     mbOutputClipped = sal_True;
     985             :                 }
     986             :                 else
     987             :                 {
     988       18650 :                     mbOutputClipped = sal_False;
     989       18650 :                     ImplSelectClipRegion( aRegion );
     990       18652 :                 }
     991             :             }
     992             : 
     993       18759 :             mbClipRegionSet = sal_True;
     994             :         }
     995             :         else
     996             :         {
     997       84128 :             if ( mbClipRegionSet )
     998             :             {
     999        4121 :                 mpGraphics->ResetClipRegion();
    1000        4121 :                 mbClipRegionSet = sal_False;
    1001             :             }
    1002             : 
    1003       84128 :             mbOutputClipped = sal_False;
    1004             :         }
    1005             :     }
    1006             : 
    1007      423789 :     mbInitClipRegion = sal_False;
    1008      423789 : }
    1009             : 
    1010      370162 : void OutputDevice::ImplSetClipRegion( const Region* pRegion )
    1011             : {
    1012             :     DBG_TESTSOLARMUTEX();
    1013             : 
    1014      370162 :     if ( !pRegion )
    1015             :     {
    1016      174065 :         if ( mbClipRegion )
    1017             :         {
    1018      154077 :             maRegion            = Region(true);
    1019      154077 :             mbClipRegion        = sal_False;
    1020      154077 :             mbInitClipRegion    = sal_True;
    1021             :         }
    1022             :     }
    1023             :     else
    1024             :     {
    1025      196097 :         maRegion            = *pRegion;
    1026      196097 :         mbClipRegion        = sal_True;
    1027      196097 :         mbInitClipRegion    = sal_True;
    1028             :     }
    1029      370162 : }
    1030             : 
    1031       25798 : void OutputDevice::SetClipRegion()
    1032             : {
    1033             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1034             : 
    1035       25798 :     if ( mpMetaFile )
    1036          28 :         mpMetaFile->AddAction( new MetaClipRegionAction( Region(), sal_False ) );
    1037             : 
    1038       25798 :     ImplSetClipRegion( NULL );
    1039             : 
    1040       25798 :     if( mpAlphaVDev )
    1041          18 :         mpAlphaVDev->SetClipRegion();
    1042       25798 : }
    1043             : 
    1044       37832 : void OutputDevice::SetClipRegion( const Region& rRegion )
    1045             : {
    1046             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1047             : 
    1048       37832 :     if ( mpMetaFile )
    1049        5360 :         mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, sal_True ) );
    1050             : 
    1051       37832 :     if ( rRegion.IsNull() )
    1052             :     {
    1053        1144 :         ImplSetClipRegion( NULL );
    1054             :     }
    1055             :     else
    1056             :     {
    1057       36688 :         Region aRegion = LogicToPixel( rRegion );
    1058       36688 :         ImplSetClipRegion( &aRegion );
    1059             :     }
    1060             : 
    1061       37832 :     if( mpAlphaVDev )
    1062        5355 :         mpAlphaVDev->SetClipRegion( rRegion );
    1063       37832 : }
    1064             : 
    1065       11036 : Region OutputDevice::GetClipRegion() const
    1066             : {
    1067             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1068             : 
    1069       11036 :     return PixelToLogic( maRegion );
    1070             : }
    1071             : 
    1072       80030 : Region OutputDevice::GetActiveClipRegion() const
    1073             : {
    1074             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1075             : 
    1076       80030 :     if ( GetOutDevType() == OUTDEV_WINDOW )
    1077             :     {
    1078       80030 :         Region aRegion(true);
    1079       80030 :         Window* pWindow = (Window*)this;
    1080       80030 :         if ( pWindow->mpWindowImpl->mbInPaint )
    1081             :         {
    1082       80030 :             aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
    1083       80030 :             aRegion.Move( -mnOutOffX, -mnOutOffY );
    1084             :         }
    1085       80030 :         if ( mbClipRegion )
    1086           0 :             aRegion.Intersect( maRegion );
    1087       80030 :         return PixelToLogic( aRegion );
    1088             :     }
    1089             :     else
    1090           0 :         return GetClipRegion();
    1091             : }
    1092             : 
    1093           0 : void OutputDevice::MoveClipRegion( long nHorzMove, long nVertMove )
    1094             : {
    1095             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1096             : 
    1097           0 :     if ( mbClipRegion )
    1098             :     {
    1099           0 :         if( mpMetaFile )
    1100           0 :             mpMetaFile->AddAction( new MetaMoveClipRegionAction( nHorzMove, nVertMove ) );
    1101             : 
    1102             :         maRegion.Move( ImplLogicWidthToDevicePixel( nHorzMove ),
    1103           0 :                        ImplLogicHeightToDevicePixel( nVertMove ) );
    1104           0 :         mbInitClipRegion = sal_True;
    1105             :     }
    1106             : 
    1107           0 :     if( mpAlphaVDev )
    1108           0 :         mpAlphaVDev->MoveClipRegion( nHorzMove, nVertMove );
    1109           0 : }
    1110             : 
    1111      172633 : void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
    1112             : {
    1113             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1114             : 
    1115      172633 :     if ( mpMetaFile )
    1116        3218 :         mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );
    1117             : 
    1118      172633 :     Rectangle aRect = LogicToPixel( rRect );
    1119      172633 :     maRegion.Intersect( aRect );
    1120      172633 :     mbClipRegion        = sal_True;
    1121      172633 :     mbInitClipRegion    = sal_True;
    1122             : 
    1123      172633 :     if( mpAlphaVDev )
    1124         896 :         mpAlphaVDev->IntersectClipRegion( rRect );
    1125      172633 : }
    1126             : 
    1127      103686 : void OutputDevice::IntersectClipRegion( const Region& rRegion )
    1128             : {
    1129             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1130             : 
    1131      103686 :     if(!rRegion.IsNull())
    1132             :     {
    1133      103686 :         if ( mpMetaFile )
    1134         257 :             mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );
    1135             : 
    1136      103686 :         Region aRegion = LogicToPixel( rRegion );
    1137      103686 :         maRegion.Intersect( aRegion );
    1138      103686 :         mbClipRegion        = sal_True;
    1139      103686 :         mbInitClipRegion    = sal_True;
    1140             :     }
    1141             : 
    1142      103686 :     if( mpAlphaVDev )
    1143         192 :         mpAlphaVDev->IntersectClipRegion( rRegion );
    1144      103686 : }
    1145             : 
    1146       59987 : void OutputDevice::SetDrawMode( sal_uLong nDrawMode )
    1147             : {
    1148             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1149             : 
    1150       59987 :     mnDrawMode = nDrawMode;
    1151             : 
    1152       59987 :     if( mpAlphaVDev )
    1153           0 :         mpAlphaVDev->SetDrawMode( nDrawMode );
    1154       59987 : }
    1155             : 
    1156       58462 : void OutputDevice::SetRasterOp( RasterOp eRasterOp )
    1157             : {
    1158             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1159             : 
    1160       58462 :     if ( mpMetaFile )
    1161        5323 :         mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
    1162             : 
    1163       58462 :     if ( meRasterOp != eRasterOp )
    1164             :     {
    1165        6222 :         meRasterOp = eRasterOp;
    1166        6222 :         mbInitLineColor = mbInitFillColor = sal_True;
    1167             : 
    1168        6222 :         if( mpGraphics || ImplGetGraphics() )
    1169        6222 :             mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
    1170             :     }
    1171             : 
    1172       58462 :     if( mpAlphaVDev )
    1173       10617 :         mpAlphaVDev->SetRasterOp( eRasterOp );
    1174       58462 : }
    1175             : 
    1176      432564 : void OutputDevice::SetLineColor()
    1177             : {
    1178             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1179             : 
    1180      432564 :     if ( mpMetaFile )
    1181        6325 :         mpMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
    1182             : 
    1183      432564 :     if ( mbLineColor )
    1184             :     {
    1185      211239 :         mbInitLineColor = sal_True;
    1186      211239 :         mbLineColor = sal_False;
    1187      211239 :         maLineColor = Color( COL_TRANSPARENT );
    1188             :     }
    1189             : 
    1190      432564 :     if( mpAlphaVDev )
    1191        6947 :         mpAlphaVDev->SetLineColor();
    1192      432564 : }
    1193             : 
    1194     1029008 : Color OutputDevice::ImplDrawModeToColor( const Color& rColor ) const
    1195             : {
    1196     1029008 :     Color aColor( rColor );
    1197     1029008 :     sal_uLong  nDrawMode = GetDrawMode();
    1198             : 
    1199     1029008 :     if( nDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
    1200             :                       DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE |
    1201             :                       DRAWMODE_SETTINGSLINE ) )
    1202             :     {
    1203           0 :         if( !ImplIsColorTransparent( aColor ) )
    1204             :         {
    1205           0 :             if( nDrawMode & DRAWMODE_BLACKLINE )
    1206             :             {
    1207           0 :                 aColor = Color( COL_BLACK );
    1208             :             }
    1209           0 :             else if( nDrawMode & DRAWMODE_WHITELINE )
    1210             :             {
    1211           0 :                 aColor = Color( COL_WHITE );
    1212             :             }
    1213           0 :             else if( nDrawMode & DRAWMODE_GRAYLINE )
    1214             :             {
    1215           0 :                 const sal_uInt8 cLum = aColor.GetLuminance();
    1216           0 :                 aColor = Color( cLum, cLum, cLum );
    1217             :             }
    1218           0 :             else if( nDrawMode & DRAWMODE_SETTINGSLINE )
    1219             :             {
    1220           0 :                 aColor = GetSettings().GetStyleSettings().GetFontColor();
    1221             :             }
    1222             : 
    1223           0 :             if( nDrawMode & DRAWMODE_GHOSTEDLINE )
    1224             :             {
    1225           0 :                 aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
    1226           0 :                                 ( aColor.GetGreen() >> 1 ) | 0x80,
    1227           0 :                                 ( aColor.GetBlue() >> 1 ) | 0x80);
    1228             :             }
    1229             :         }
    1230             :     }
    1231     1029008 :     return aColor;
    1232             : }
    1233             : 
    1234             : 
    1235      849363 : void OutputDevice::SetLineColor( const Color& rColor )
    1236             : {
    1237             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1238             : 
    1239      849363 :     Color aColor = ImplDrawModeToColor( rColor );
    1240             : 
    1241      849363 :     if( mpMetaFile )
    1242       24775 :         mpMetaFile->AddAction( new MetaLineColorAction( aColor, sal_True ) );
    1243             : 
    1244      849363 :     if( ImplIsColorTransparent( aColor ) )
    1245             :     {
    1246       28796 :         if ( mbLineColor )
    1247             :         {
    1248        5414 :             mbInitLineColor = sal_True;
    1249        5414 :             mbLineColor = sal_False;
    1250        5414 :             maLineColor = Color( COL_TRANSPARENT );
    1251             :         }
    1252             :     }
    1253             :     else
    1254             :     {
    1255      820567 :         if( maLineColor != aColor )
    1256             :         {
    1257      487688 :             mbInitLineColor = sal_True;
    1258      487688 :             mbLineColor = sal_True;
    1259      487688 :             maLineColor = aColor;
    1260             :         }
    1261             :     }
    1262             : 
    1263      849363 :     if( mpAlphaVDev )
    1264       31691 :         mpAlphaVDev->SetLineColor( COL_BLACK );
    1265      849363 : }
    1266             : 
    1267      260831 : void OutputDevice::SetFillColor()
    1268             : {
    1269             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1270             : 
    1271      260831 :     if ( mpMetaFile )
    1272        2288 :         mpMetaFile->AddAction( new MetaFillColorAction( Color(), sal_False ) );
    1273             : 
    1274      260831 :     if ( mbFillColor )
    1275             :     {
    1276       37601 :         mbInitFillColor = sal_True;
    1277       37601 :         mbFillColor = sal_False;
    1278       37601 :         maFillColor = Color( COL_TRANSPARENT );
    1279             :     }
    1280             : 
    1281      260831 :     if( mpAlphaVDev )
    1282        1469 :         mpAlphaVDev->SetFillColor();
    1283      260831 : }
    1284             : 
    1285      794655 : void OutputDevice::SetFillColor( const Color& rColor )
    1286             : {
    1287             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1288             : 
    1289      794655 :     Color aColor( rColor );
    1290             : 
    1291      794655 :     if( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL |
    1292             :                        DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
    1293             :                        DRAWMODE_GHOSTEDFILL | DRAWMODE_SETTINGSFILL ) )
    1294             :     {
    1295           0 :         if( !ImplIsColorTransparent( aColor ) )
    1296             :         {
    1297           0 :             if( mnDrawMode & DRAWMODE_BLACKFILL )
    1298             :             {
    1299           0 :                 aColor = Color( COL_BLACK );
    1300             :             }
    1301           0 :             else if( mnDrawMode & DRAWMODE_WHITEFILL )
    1302             :             {
    1303           0 :                 aColor = Color( COL_WHITE );
    1304             :             }
    1305           0 :             else if( mnDrawMode & DRAWMODE_GRAYFILL )
    1306             :             {
    1307           0 :                 const sal_uInt8 cLum = aColor.GetLuminance();
    1308           0 :                 aColor = Color( cLum, cLum, cLum );
    1309             :             }
    1310           0 :             else if( mnDrawMode & DRAWMODE_NOFILL )
    1311             :             {
    1312           0 :                 aColor = Color( COL_TRANSPARENT );
    1313             :             }
    1314           0 :             else if( mnDrawMode & DRAWMODE_SETTINGSFILL )
    1315             :             {
    1316           0 :                 aColor = GetSettings().GetStyleSettings().GetWindowColor();
    1317             :             }
    1318             : 
    1319           0 :             if( mnDrawMode & DRAWMODE_GHOSTEDFILL )
    1320             :             {
    1321           0 :                 aColor = Color( (aColor.GetRed() >> 1) | 0x80,
    1322           0 :                                 (aColor.GetGreen() >> 1) | 0x80,
    1323           0 :                                 (aColor.GetBlue() >> 1) | 0x80);
    1324             :             }
    1325             :         }
    1326             :     }
    1327             : 
    1328      794655 :     if ( mpMetaFile )
    1329       20567 :         mpMetaFile->AddAction( new MetaFillColorAction( aColor, sal_True ) );
    1330             : 
    1331      794655 :     if ( ImplIsColorTransparent( aColor ) )
    1332             :     {
    1333       11887 :         if ( mbFillColor )
    1334             :         {
    1335       10175 :             mbInitFillColor = sal_True;
    1336       10175 :             mbFillColor = sal_False;
    1337       10175 :             maFillColor = Color( COL_TRANSPARENT );
    1338             :         }
    1339             :     }
    1340             :     else
    1341             :     {
    1342      782768 :         if ( maFillColor != aColor )
    1343             :         {
    1344      368793 :             mbInitFillColor = sal_True;
    1345      368793 :             mbFillColor = sal_True;
    1346      368793 :             maFillColor = aColor;
    1347             :         }
    1348             :     }
    1349             : 
    1350      794655 :     if( mpAlphaVDev )
    1351       28998 :         mpAlphaVDev->SetFillColor( COL_BLACK );
    1352      794655 : }
    1353             : 
    1354       30373 : void OutputDevice::SetBackground()
    1355             : {
    1356             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1357             : 
    1358       30373 :     maBackground = Wallpaper();
    1359       30373 :     mbBackground = sal_False;
    1360             : 
    1361       30373 :     if( mpAlphaVDev )
    1362           0 :         mpAlphaVDev->SetBackground();
    1363       30373 : }
    1364             : 
    1365      232323 : void OutputDevice::SetBackground( const Wallpaper& rBackground )
    1366             : {
    1367             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1368             : 
    1369      232323 :     maBackground = rBackground;
    1370             : 
    1371      232323 :     if( rBackground.GetStyle() == WALLPAPER_NULL )
    1372         902 :         mbBackground = sal_False;
    1373             :     else
    1374      231421 :         mbBackground = sal_True;
    1375             : 
    1376      232323 :     if( mpAlphaVDev )
    1377           0 :         mpAlphaVDev->SetBackground( rBackground );
    1378      232323 : }
    1379             : 
    1380       55305 : void OutputDevice::SetRefPoint()
    1381             : {
    1382             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1383             : 
    1384       55305 :     if ( mpMetaFile )
    1385        5293 :         mpMetaFile->AddAction( new MetaRefPointAction( Point(), sal_False ) );
    1386             : 
    1387       55305 :     mbRefPoint = sal_False;
    1388       55305 :     maRefPoint.X() = maRefPoint.Y() = 0L;
    1389             : 
    1390       55305 :     if( mpAlphaVDev )
    1391       10617 :         mpAlphaVDev->SetRefPoint();
    1392       55305 : }
    1393             : 
    1394           0 : void OutputDevice::SetRefPoint( const Point& rRefPoint )
    1395             : {
    1396             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1397             : 
    1398           0 :     if ( mpMetaFile )
    1399           0 :         mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, sal_True ) );
    1400             : 
    1401           0 :     mbRefPoint = sal_True;
    1402           0 :     maRefPoint = rRefPoint;
    1403             : 
    1404           0 :     if( mpAlphaVDev )
    1405           0 :         mpAlphaVDev->SetRefPoint( rRefPoint );
    1406           0 : }
    1407             : 
    1408      547248 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
    1409             : {
    1410             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1411             : 
    1412      547248 :     if ( mpMetaFile )
    1413       23076 :         mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) );
    1414             : 
    1415      547248 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
    1416       35219 :         return;
    1417             : 
    1418      541417 :     if ( !mpGraphics )
    1419             :     {
    1420        1255 :         if ( !ImplGetGraphics() )
    1421           0 :             return;
    1422             :     }
    1423             : 
    1424      541417 :     if ( mbInitClipRegion )
    1425       30676 :         ImplInitClipRegion();
    1426      541417 :     if ( mbOutputClipped )
    1427       23557 :         return;
    1428             : 
    1429      517860 :     if ( mbInitLineColor )
    1430      149383 :         ImplInitLineColor();
    1431             : 
    1432             :     // #i101598# support AA and snap for lines, too
    1433     1035720 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1434           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1435           0 :         && ROP_OVERPAINT == GetRasterOp()
    1436      517860 :         && IsLineColor())
    1437             :     {
    1438             :         // at least transform with double precision to device coordinates; this will
    1439             :         // avoid pixel snap of single, appended lines
    1440           0 :         const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
    1441           0 :         const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1442           0 :         basegfx::B2DPolygon aB2DPolyLine;
    1443             : 
    1444           0 :         aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y()));
    1445           0 :         aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y()));
    1446           0 :         aB2DPolyLine.transform( aTransform );
    1447             : 
    1448           0 :         if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1449             :         {
    1450           0 :             aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
    1451             :         }
    1452             : 
    1453           0 :         if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this))
    1454             :         {
    1455           0 :             return;
    1456           0 :         }
    1457             :     }
    1458             : 
    1459      517860 :     const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
    1460      517860 :     const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
    1461             : 
    1462      517860 :     mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
    1463             : 
    1464      517860 :     if( mpAlphaVDev )
    1465       22656 :         mpAlphaVDev->DrawLine( rStartPt, rEndPt );
    1466             : }
    1467             : 
    1468           0 : void OutputDevice::impPaintLineGeometryWithEvtlExpand(
    1469             :     const LineInfo& rInfo,
    1470             :     basegfx::B2DPolyPolygon aLinePolyPolygon)
    1471             : {
    1472           0 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1473           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1474           0 :         && ROP_OVERPAINT == GetRasterOp()
    1475           0 :         && IsLineColor());
    1476           0 :     basegfx::B2DPolyPolygon aFillPolyPolygon;
    1477           0 :     const bool bDashUsed(LINE_DASH == rInfo.GetStyle());
    1478           0 :     const bool bLineWidthUsed(rInfo.GetWidth() > 1);
    1479             : 
    1480           0 :     if(bDashUsed && aLinePolyPolygon.count())
    1481             :     {
    1482           0 :         ::std::vector< double > fDotDashArray;
    1483           0 :         const double fDashLen(rInfo.GetDashLen());
    1484           0 :         const double fDotLen(rInfo.GetDotLen());
    1485           0 :         const double fDistance(rInfo.GetDistance());
    1486             : 
    1487           0 :         for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++)
    1488             :         {
    1489           0 :             fDotDashArray.push_back(fDashLen);
    1490           0 :             fDotDashArray.push_back(fDistance);
    1491             :         }
    1492             : 
    1493           0 :         for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
    1494             :         {
    1495           0 :             fDotDashArray.push_back(fDotLen);
    1496           0 :             fDotDashArray.push_back(fDistance);
    1497             :         }
    1498             : 
    1499           0 :         const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
    1500             : 
    1501           0 :         if(fAccumulated > 0.0)
    1502             :         {
    1503           0 :             basegfx::B2DPolyPolygon aResult;
    1504             : 
    1505           0 :             for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++)
    1506             :             {
    1507           0 :                 basegfx::B2DPolyPolygon aLineTraget;
    1508             :                 basegfx::tools::applyLineDashing(
    1509             :                     aLinePolyPolygon.getB2DPolygon(c),
    1510             :                     fDotDashArray,
    1511           0 :                     &aLineTraget);
    1512           0 :                 aResult.append(aLineTraget);
    1513           0 :             }
    1514             : 
    1515           0 :             aLinePolyPolygon = aResult;
    1516           0 :         }
    1517             :     }
    1518             : 
    1519           0 :     if(bLineWidthUsed && aLinePolyPolygon.count())
    1520             :     {
    1521           0 :         const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);
    1522             : 
    1523           0 :         if(aLinePolyPolygon.areControlPointsUsed())
    1524             :         {
    1525             :             // #i110768# When area geometry has to be created, do not
    1526             :             // use the fallback bezier decomposition inside createAreaGeometry,
    1527             :             // but one that is at least as good as ImplSubdivideBezier was.
    1528             :             // There, Polygon::AdaptiveSubdivide was used with default parameter
    1529             :             // 1.0 as quality index.
    1530           0 :             aLinePolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0);
    1531             :         }
    1532             : 
    1533           0 :         for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
    1534             :         {
    1535             :             aFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
    1536             :                 aLinePolyPolygon.getB2DPolygon(a),
    1537             :                 fHalfLineWidth,
    1538             :                 rInfo.GetLineJoin(),
    1539           0 :                 rInfo.GetLineCap()));
    1540             :         }
    1541             : 
    1542           0 :         aLinePolyPolygon.clear();
    1543             :     }
    1544             : 
    1545           0 :     GDIMetaFile* pOldMetaFile = mpMetaFile;
    1546           0 :     mpMetaFile = NULL;
    1547             : 
    1548           0 :     if(aLinePolyPolygon.count())
    1549             :     {
    1550           0 :         for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
    1551             :         {
    1552           0 :             const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
    1553           0 :             bool bDone(false);
    1554             : 
    1555           0 :             if(bTryAA)
    1556             :             {
    1557           0 :                 bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this);
    1558             :             }
    1559             : 
    1560           0 :             if(!bDone)
    1561             :             {
    1562           0 :                 const Polygon aPolygon(aCandidate);
    1563           0 :                 mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
    1564             :             }
    1565           0 :         }
    1566             :     }
    1567             : 
    1568           0 :     if(aFillPolyPolygon.count())
    1569             :     {
    1570           0 :         const Color     aOldLineColor( maLineColor );
    1571           0 :         const Color     aOldFillColor( maFillColor );
    1572             : 
    1573           0 :         SetLineColor();
    1574           0 :         ImplInitLineColor();
    1575           0 :         SetFillColor( aOldLineColor );
    1576           0 :         ImplInitFillColor();
    1577             : 
    1578           0 :         bool bDone(false);
    1579             : 
    1580           0 :         if(bTryAA)
    1581             :         {
    1582           0 :             bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this);
    1583             :         }
    1584             : 
    1585           0 :         if(!bDone)
    1586             :         {
    1587           0 :             for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
    1588             :             {
    1589           0 :                 Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
    1590             : 
    1591             :                 // need to subdivide, mpGraphics->DrawPolygon ignores curves
    1592           0 :                 aPolygon.AdaptiveSubdivide(aPolygon);
    1593           0 :                 mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
    1594           0 :             }
    1595             :         }
    1596             : 
    1597           0 :         SetFillColor( aOldFillColor );
    1598           0 :         SetLineColor( aOldLineColor );
    1599             :     }
    1600             : 
    1601           0 :     mpMetaFile = pOldMetaFile;
    1602           0 : }
    1603             : 
    1604           0 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
    1605             :                              const LineInfo& rLineInfo )
    1606             : {
    1607             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1608             : 
    1609           0 :     if ( rLineInfo.IsDefault() )
    1610             :     {
    1611           0 :         DrawLine( rStartPt, rEndPt );
    1612           0 :         return;
    1613             :     }
    1614             : 
    1615           0 :     if ( mpMetaFile )
    1616           0 :         mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );
    1617             : 
    1618           0 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
    1619           0 :         return;
    1620             : 
    1621           0 :     if( !mpGraphics && !ImplGetGraphics() )
    1622           0 :         return;
    1623             : 
    1624           0 :     if ( mbInitClipRegion )
    1625           0 :         ImplInitClipRegion();
    1626             : 
    1627           0 :     if ( mbOutputClipped )
    1628           0 :         return;
    1629             : 
    1630           0 :     const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
    1631           0 :     const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
    1632           0 :     const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
    1633           0 :     const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
    1634           0 :     const bool bLineWidthUsed(aInfo.GetWidth() > 1);
    1635             : 
    1636           0 :     if ( mbInitLineColor )
    1637           0 :         ImplInitLineColor();
    1638             : 
    1639           0 :     if(bDashUsed || bLineWidthUsed)
    1640             :     {
    1641           0 :         basegfx::B2DPolygon aLinePolygon;
    1642           0 :         aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y()));
    1643           0 :         aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y()));
    1644             : 
    1645           0 :         impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon));
    1646             :     }
    1647             :     else
    1648             :     {
    1649           0 :         mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
    1650             :     }
    1651             : 
    1652           0 :     if( mpAlphaVDev )
    1653           0 :         mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo );
    1654             : }
    1655             : 
    1656      334103 : void OutputDevice::DrawRect( const Rectangle& rRect )
    1657             : {
    1658             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1659             : 
    1660      334103 :     if ( mpMetaFile )
    1661        6798 :         mpMetaFile->AddAction( new MetaRectAction( rRect ) );
    1662             : 
    1663      334103 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
    1664       23930 :         return;
    1665             : 
    1666      329080 :     Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
    1667             : 
    1668      329080 :     if ( aRect.IsEmpty() )
    1669        8313 :         return;
    1670      320767 :     aRect.Justify();
    1671             : 
    1672      320767 :     if ( !mpGraphics )
    1673             :     {
    1674       68310 :         if ( !ImplGetGraphics() )
    1675           0 :             return;
    1676             :     }
    1677             : 
    1678      320767 :     if ( mbInitClipRegion )
    1679      125861 :         ImplInitClipRegion();
    1680      320767 :     if ( mbOutputClipped )
    1681        5571 :         return;
    1682             : 
    1683      315196 :     if ( mbInitLineColor )
    1684      188881 :         ImplInitLineColor();
    1685      315196 :     if ( mbInitFillColor )
    1686      182424 :         ImplInitFillColor();
    1687             : 
    1688      315196 :     mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
    1689             : 
    1690      315196 :     if( mpAlphaVDev )
    1691        7556 :         mpAlphaVDev->DrawRect( rRect );
    1692             : }
    1693             : 
    1694       16588 : void OutputDevice::DrawPolyLine( const Polygon& rPoly )
    1695             : {
    1696             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1697             :     DBG_CHKOBJ( &rPoly, Polygon, NULL );
    1698             : 
    1699       16588 :     if( mpMetaFile )
    1700           0 :         mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );
    1701             : 
    1702       16588 :     sal_uInt16 nPoints = rPoly.GetSize();
    1703             : 
    1704       16588 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() )
    1705           0 :         return;
    1706             : 
    1707             :     // we need a graphics
    1708       16588 :     if ( !mpGraphics )
    1709           0 :         if ( !ImplGetGraphics() )
    1710           0 :             return;
    1711             : 
    1712       16588 :     if ( mbInitClipRegion )
    1713         606 :         ImplInitClipRegion();
    1714       16588 :     if ( mbOutputClipped )
    1715           0 :         return;
    1716             : 
    1717       16588 :     if ( mbInitLineColor )
    1718        3351 :         ImplInitLineColor();
    1719             : 
    1720       16588 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1721           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1722           0 :         && ROP_OVERPAINT == GetRasterOp()
    1723       16588 :         && IsLineColor());
    1724             : 
    1725             :     // use b2dpolygon drawing if possible
    1726       16588 :     if(bTryAA && ImpTryDrawPolyLineDirect(rPoly.getB2DPolygon()))
    1727             :     {
    1728           0 :         basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon());
    1729           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    1730           0 :         const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1731             : 
    1732             :         // transform the polygon
    1733           0 :         aB2DPolyLine.transform( aTransform );
    1734             : 
    1735           0 :         if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1736             :         {
    1737           0 :             aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
    1738             :         }
    1739             : 
    1740           0 :         if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this))
    1741             :         {
    1742           0 :             return;
    1743           0 :         }
    1744             :     }
    1745             : 
    1746       16588 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1747       16588 :     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1748             : 
    1749             :     // #100127# Forward beziers to sal, if any
    1750       16588 :     if( aPoly.HasFlags() )
    1751             :     {
    1752           0 :         const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
    1753           0 :         if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, this ) )
    1754             :         {
    1755           0 :             aPoly = ImplSubdivideBezier(aPoly);
    1756           0 :             pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1757           0 :             mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, this );
    1758             :         }
    1759             :     }
    1760             :     else
    1761             :     {
    1762       16588 :         mpGraphics->DrawPolyLine( nPoints, pPtAry, this );
    1763             :     }
    1764             : 
    1765       16588 :     if( mpAlphaVDev )
    1766        2946 :         mpAlphaVDev->DrawPolyLine( rPoly );
    1767             : }
    1768             : 
    1769          30 : void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo )
    1770             : {
    1771             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1772             :     DBG_CHKOBJ( &rPoly, Polygon, NULL );
    1773             : 
    1774          30 :     if ( rLineInfo.IsDefault() )
    1775             :     {
    1776           0 :         DrawPolyLine( rPoly );
    1777           0 :         return;
    1778             :     }
    1779             : 
    1780             :     // #i101491#
    1781             :     // Try direct Fallback to B2D-Version of DrawPolyLine
    1782          60 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1783          30 :         && LINE_SOLID == rLineInfo.GetStyle())
    1784             :     {
    1785           0 :         DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap());
    1786           0 :         return;
    1787             :     }
    1788             : 
    1789          30 :     if ( mpMetaFile )
    1790           2 :         mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
    1791             : 
    1792          30 :     ImpDrawPolyLineWithLineInfo(rPoly, rLineInfo);
    1793             : }
    1794             : 
    1795      132857 : void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
    1796             : {
    1797      132857 :     sal_uInt16 nPoints(rPoly.GetSize());
    1798             : 
    1799      132857 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
    1800           4 :         return;
    1801             : 
    1802      132855 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1803             : 
    1804             :     // #100127# LineInfo is not curve-safe, subdivide always
    1805             :     //
    1806             :     // What shall this mean? It's wrong to subdivide here when the
    1807             :     // polygon is a fat line. In that case, the painted geometry
    1808             :     // WILL be much different.
    1809             :     // I also have no idea how this could be related to the given ID
    1810             :     // which reads 'consolidate boost versions' in the task description.
    1811             :     // Removing.
    1812             :     //
    1813             :     //if( aPoly.HasFlags() )
    1814             :     //{
    1815             :     //    aPoly = ImplSubdivideBezier( aPoly );
    1816             :     //    nPoints = aPoly.GetSize();
    1817             :     //}
    1818             : 
    1819             :     // we need a graphics
    1820      132855 :     if ( !mpGraphics && !ImplGetGraphics() )
    1821           0 :         return;
    1822             : 
    1823      132855 :     if ( mbInitClipRegion )
    1824           2 :         ImplInitClipRegion();
    1825             : 
    1826      132855 :     if ( mbOutputClipped )
    1827           0 :         return;
    1828             : 
    1829      132855 :     if ( mbInitLineColor )
    1830          15 :         ImplInitLineColor();
    1831             : 
    1832      265710 :     const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
    1833      132855 :     const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
    1834      132855 :     const bool bLineWidthUsed(aInfo.GetWidth() > 1);
    1835             : 
    1836      132855 :     if(bDashUsed || bLineWidthUsed)
    1837             :     {
    1838           0 :         impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon()));
    1839             :     }
    1840             :     else
    1841             :     {
    1842             :         // #100127# the subdivision HAS to be done here since only a pointer
    1843             :         // to an array of points is given to the DrawPolyLine method, there is
    1844             :         // NO way to find out there that it's a curve.
    1845      132855 :         if( aPoly.HasFlags() )
    1846             :         {
    1847        1902 :             aPoly = ImplSubdivideBezier( aPoly );
    1848        1902 :             nPoints = aPoly.GetSize();
    1849             :         }
    1850             : 
    1851      132855 :         mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this);
    1852             :     }
    1853             : 
    1854      132855 :     if( mpAlphaVDev )
    1855      132855 :         mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
    1856             : }
    1857             : 
    1858      151389 : void OutputDevice::DrawPolygon( const Polygon& rPoly )
    1859             : {
    1860             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1861             :     DBG_CHKOBJ( &rPoly, Polygon, NULL );
    1862             : 
    1863      151389 :     if( mpMetaFile )
    1864           6 :         mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
    1865             : 
    1866      151389 :     sal_uInt16 nPoints = rPoly.GetSize();
    1867             : 
    1868      151389 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
    1869           0 :         return;
    1870             : 
    1871             :     // we need a graphics
    1872      151389 :     if ( !mpGraphics )
    1873           0 :         if ( !ImplGetGraphics() )
    1874           0 :             return;
    1875             : 
    1876      151389 :     if ( mbInitClipRegion )
    1877         167 :         ImplInitClipRegion();
    1878      151389 :     if ( mbOutputClipped )
    1879           0 :         return;
    1880             : 
    1881      151389 :     if ( mbInitLineColor )
    1882        1719 :         ImplInitLineColor();
    1883      151389 :     if ( mbInitFillColor )
    1884        2388 :         ImplInitFillColor();
    1885             : 
    1886             :     // use b2dpolygon drawing if possible
    1887      302778 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1888          18 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1889           0 :         && ROP_OVERPAINT == GetRasterOp()
    1890      151389 :         && (IsLineColor() || IsFillColor()))
    1891             :     {
    1892           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    1893           0 :         basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
    1894           0 :         bool bSuccess(true);
    1895             : 
    1896             :         // transform the polygon and ensure closed
    1897           0 :         aB2DPolygon.transform(aTransform);
    1898           0 :         aB2DPolygon.setClosed(true);
    1899             : 
    1900           0 :         if(IsFillColor())
    1901             :         {
    1902           0 :             bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
    1903             :         }
    1904             : 
    1905           0 :         if(bSuccess && IsLineColor())
    1906             :         {
    1907           0 :             const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1908             : 
    1909           0 :             if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1910             :             {
    1911           0 :                 aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
    1912             :             }
    1913             : 
    1914             :             bSuccess = mpGraphics->DrawPolyLine(
    1915             :                 aB2DPolygon,
    1916             :                 0.0,
    1917             :                 aB2DLineWidth,
    1918             :                 basegfx::B2DLINEJOIN_NONE,
    1919             :                 com::sun::star::drawing::LineCap_BUTT,
    1920           0 :                 this);
    1921             :         }
    1922             : 
    1923           0 :         if(bSuccess)
    1924             :         {
    1925           0 :             return;
    1926           0 :         }
    1927             :     }
    1928             : 
    1929      151389 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1930      151389 :     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1931             : 
    1932             :     // #100127# Forward beziers to sal, if any
    1933      151389 :     if( aPoly.HasFlags() )
    1934             :     {
    1935        4077 :         const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
    1936        4077 :         if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
    1937             :         {
    1938        4077 :             aPoly = ImplSubdivideBezier(aPoly);
    1939        4077 :             pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1940        4077 :             mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
    1941             :         }
    1942             :     }
    1943             :     else
    1944             :     {
    1945      147312 :         mpGraphics->DrawPolygon( nPoints, pPtAry, this );
    1946             :     }
    1947      151389 :     if( mpAlphaVDev )
    1948        3851 :         mpAlphaVDev->DrawPolygon( rPoly );
    1949             : }
    1950             : 
    1951      146426 : void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
    1952             : {
    1953             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1954             :     DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
    1955             : 
    1956      146426 :     if( mpMetaFile )
    1957           0 :         mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
    1958             : 
    1959      146426 :     sal_uInt16 nPoly = rPolyPoly.Count();
    1960             : 
    1961      146426 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
    1962           0 :         return;
    1963             : 
    1964             :     // we need a graphics
    1965      146426 :     if ( !mpGraphics )
    1966           0 :         if ( !ImplGetGraphics() )
    1967           0 :             return;
    1968             : 
    1969      146426 :     if ( mbInitClipRegion )
    1970         126 :         ImplInitClipRegion();
    1971      146426 :     if ( mbOutputClipped )
    1972           0 :         return;
    1973             : 
    1974      146426 :     if ( mbInitLineColor )
    1975        7624 :         ImplInitLineColor();
    1976      146426 :     if ( mbInitFillColor )
    1977        8520 :         ImplInitFillColor();
    1978             : 
    1979             :     // use b2dpolygon drawing if possible
    1980      292852 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1981          18 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1982           0 :         && ROP_OVERPAINT == GetRasterOp()
    1983      146426 :         && (IsLineColor() || IsFillColor()))
    1984             :     {
    1985           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    1986           0 :         basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
    1987           0 :         bool bSuccess(true);
    1988             : 
    1989             :         // transform the polygon and ensure closed
    1990           0 :         aB2DPolyPolygon.transform(aTransform);
    1991           0 :         aB2DPolyPolygon.setClosed(true);
    1992             : 
    1993           0 :         if(IsFillColor())
    1994             :         {
    1995           0 :             bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
    1996             :         }
    1997             : 
    1998           0 :         if(bSuccess && IsLineColor())
    1999             :         {
    2000           0 :             const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    2001             : 
    2002           0 :             if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    2003             :             {
    2004           0 :                 aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
    2005             :             }
    2006             : 
    2007           0 :             for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
    2008             :             {
    2009             :                 bSuccess = mpGraphics->DrawPolyLine(
    2010             :                     aB2DPolyPolygon.getB2DPolygon(a),
    2011             :                     0.0,
    2012             :                     aB2DLineWidth,
    2013             :                     basegfx::B2DLINEJOIN_NONE,
    2014             :                     com::sun::star::drawing::LineCap_BUTT,
    2015           0 :                     this);
    2016           0 :             }
    2017             :         }
    2018             : 
    2019           0 :         if(bSuccess)
    2020             :         {
    2021           0 :             return;
    2022           0 :         }
    2023             :     }
    2024             : 
    2025      146426 :     if ( nPoly == 1 )
    2026             :     {
    2027             :         // #100127# Map to DrawPolygon
    2028      144740 :         Polygon aPoly = rPolyPoly.GetObject( 0 );
    2029      144740 :         if( aPoly.GetSize() >= 2 )
    2030             :         {
    2031      144740 :             GDIMetaFile* pOldMF = mpMetaFile;
    2032      144740 :             mpMetaFile = NULL;
    2033             : 
    2034      144740 :             DrawPolygon( aPoly );
    2035             : 
    2036      144740 :             mpMetaFile = pOldMF;
    2037      144740 :         }
    2038             :     }
    2039             :     else
    2040             :     {
    2041             :         // #100127# moved real PolyPolygon draw to separate method,
    2042             :         // have to call recursively, avoiding duplicate
    2043             :         // ImplLogicToDevicePixel calls
    2044        1686 :         ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
    2045             :     }
    2046      146426 :     if( mpAlphaVDev )
    2047        3851 :         mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
    2048             : }
    2049             : 
    2050          62 : void OutputDevice::DrawPolygon( const ::basegfx::B2DPolygon& rB2DPolygon)
    2051             : {
    2052             :     // AW: Do NOT paint empty polygons
    2053          62 :     if(rB2DPolygon.count())
    2054             :     {
    2055          62 :         ::basegfx::B2DPolyPolygon aPP( rB2DPolygon );
    2056          62 :         DrawPolyPolygon( aPP );
    2057             :     }
    2058          62 : }
    2059             : 
    2060             : // -----------------------------------------------------------------------
    2061             : // Caution: This method is nearly the same as
    2062             : // OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
    2063             : // so when changes are made here do not forget to make change sthere, too
    2064             : 
    2065       47829 : void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
    2066             : {
    2067             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    2068             : 
    2069       47829 :     if( mpMetaFile )
    2070          90 :         mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
    2071             : 
    2072             :     // call helper
    2073       47829 :     ImpDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
    2074       47829 : }
    2075             : 
    2076       47829 : void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
    2077             : {
    2078             :     // Do not paint empty PolyPolygons
    2079       47829 :     if(!rB2DPolyPoly.count() || !IsDeviceOutputNecessary())
    2080         180 :         return;
    2081             : 
    2082             :     // we need a graphics
    2083       47739 :     if( !mpGraphics )
    2084           0 :         if( !ImplGetGraphics() )
    2085           0 :             return;
    2086             : 
    2087       47739 :     if( mbInitClipRegion )
    2088           0 :         ImplInitClipRegion();
    2089       47739 :     if( mbOutputClipped )
    2090           0 :         return;
    2091             : 
    2092       47739 :     if( mbInitLineColor )
    2093         146 :         ImplInitLineColor();
    2094       47739 :     if( mbInitFillColor )
    2095       44341 :         ImplInitFillColor();
    2096             : 
    2097       95478 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    2098           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    2099           0 :         && ROP_OVERPAINT == GetRasterOp()
    2100       47739 :         && (IsLineColor() || IsFillColor()))
    2101             :     {
    2102           0 :         const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
    2103           0 :         basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
    2104           0 :         bool bSuccess(true);
    2105             : 
    2106             :         // transform the polygon and ensure closed
    2107           0 :         aB2DPolyPolygon.transform(aTransform);
    2108           0 :         aB2DPolyPolygon.setClosed(true);
    2109             : 
    2110           0 :         if(IsFillColor())
    2111             :         {
    2112           0 :             bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
    2113             :         }
    2114             : 
    2115           0 :         if(bSuccess && IsLineColor())
    2116             :         {
    2117           0 :             const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    2118             : 
    2119           0 :             if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    2120             :             {
    2121           0 :                 aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
    2122             :             }
    2123             : 
    2124           0 :             for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
    2125             :             {
    2126             :                 bSuccess = mpGraphics->DrawPolyLine(
    2127             :                     aB2DPolyPolygon.getB2DPolygon(a),
    2128             :                     0.0,
    2129             :                     aB2DLineWidth,
    2130             :                     basegfx::B2DLINEJOIN_NONE,
    2131             :                     com::sun::star::drawing::LineCap_BUTT,
    2132           0 :                     this);
    2133           0 :             }
    2134             :         }
    2135             : 
    2136           0 :         if(bSuccess)
    2137             :         {
    2138           0 :             return;
    2139           0 :         }
    2140             :     }
    2141             : 
    2142             :     // fallback to old polygon drawing if needed
    2143       47739 :     const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
    2144       95478 :     const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
    2145       95478 :     ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon );
    2146             : }
    2147             : 
    2148           0 : bool OutputDevice::ImpTryDrawPolyLineDirect(
    2149             :     const basegfx::B2DPolygon& rB2DPolygon,
    2150             :     double fLineWidth,
    2151             :     double fTransparency,
    2152             :     basegfx::B2DLineJoin eLineJoin,
    2153             :     com::sun::star::drawing::LineCap eLineCap)
    2154             : {
    2155           0 :     const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    2156           0 :     basegfx::B2DVector aB2DLineWidth(1.0, 1.0);
    2157             : 
    2158             :     // transform the line width if used
    2159           0 :     if( fLineWidth != 0.0 )
    2160             :     {
    2161           0 :         aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
    2162             :     }
    2163             : 
    2164             :     // transform the polygon
    2165           0 :     basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
    2166           0 :     aB2DPolygon.transform(aTransform);
    2167             : 
    2168           0 :     if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    2169           0 :         && aB2DPolygon.count() < 1000)
    2170             :     {
    2171             :         // #i98289#, #i101491#
    2172             :         // better to remove doubles on device coordinates. Also assume from a given amount
    2173             :         // of points that the single edges are not long enough to smooth
    2174           0 :         aB2DPolygon.removeDoublePoints();
    2175           0 :         aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
    2176             :     }
    2177             : 
    2178             :     // draw the polyline
    2179             :     return mpGraphics->DrawPolyLine(
    2180             :         aB2DPolygon,
    2181             :         fTransparency,
    2182             :         aB2DLineWidth,
    2183             :         eLineJoin,
    2184             :         eLineCap,
    2185           0 :         this);
    2186             : }
    2187             : 
    2188      130778 : bool OutputDevice::TryDrawPolyLineDirect(
    2189             :     const basegfx::B2DPolygon& rB2DPolygon,
    2190             :     double fLineWidth,
    2191             :     double fTransparency,
    2192             :     basegfx::B2DLineJoin eLineJoin,
    2193             :     com::sun::star::drawing::LineCap eLineCap)
    2194             : {
    2195             :     // AW: Do NOT paint empty PolyPolygons
    2196      130778 :     if(!rB2DPolygon.count())
    2197           0 :         return true;
    2198             : 
    2199             :     // we need a graphics
    2200      130778 :     if( !mpGraphics )
    2201           0 :         if( !ImplGetGraphics() )
    2202           0 :             return false;
    2203             : 
    2204      130778 :     if( mbInitClipRegion )
    2205        6184 :         ImplInitClipRegion();
    2206             : 
    2207      130778 :     if( mbOutputClipped )
    2208           0 :         return true;
    2209             : 
    2210      130778 :     if( mbInitLineColor )
    2211       12268 :         ImplInitLineColor();
    2212             : 
    2213      130778 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    2214           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    2215           0 :         && ROP_OVERPAINT == GetRasterOp()
    2216      130778 :         && IsLineColor());
    2217             : 
    2218      130778 :     if(bTryAA)
    2219             :     {
    2220           0 :         if(ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, fTransparency, eLineJoin, eLineCap))
    2221             :         {
    2222             :             // worked, add metafile action (if recorded) and return true
    2223           0 :             if( mpMetaFile )
    2224             :             {
    2225           0 :                 LineInfo aLineInfo;
    2226           0 :                 if( fLineWidth != 0.0 )
    2227           0 :                     aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    2228           0 :                 const Polygon aToolsPolygon( rB2DPolygon );
    2229           0 :                 mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
    2230             :             }
    2231             : 
    2232           0 :             return true;
    2233             :         }
    2234             :     }
    2235             : 
    2236      130778 :     return false;
    2237             : }
    2238             : 
    2239      134078 : void OutputDevice::DrawPolyLine(
    2240             :     const basegfx::B2DPolygon& rB2DPolygon,
    2241             :     double fLineWidth,
    2242             :     basegfx::B2DLineJoin eLineJoin,
    2243             :     com::sun::star::drawing::LineCap eLineCap)
    2244             : {
    2245             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    2246             : 
    2247      134078 :     if( mpMetaFile )
    2248             :     {
    2249        1251 :         LineInfo aLineInfo;
    2250        1251 :         if( fLineWidth != 0.0 )
    2251          20 :             aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    2252        2502 :         const Polygon aToolsPolygon( rB2DPolygon );
    2253        2502 :         mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
    2254             :     }
    2255             : 
    2256             :     // Do not paint empty PolyPolygons
    2257      134078 :     if(!rB2DPolygon.count() || !IsDeviceOutputNecessary())
    2258        1251 :         return;
    2259             : 
    2260             :     // we need a graphics
    2261      132827 :     if( !mpGraphics )
    2262           0 :         if( !ImplGetGraphics() )
    2263           0 :             return;
    2264             : 
    2265      132827 :     if( mbInitClipRegion )
    2266           0 :         ImplInitClipRegion();
    2267      132827 :     if( mbOutputClipped )
    2268           0 :         return;
    2269             : 
    2270      132827 :     if( mbInitLineColor )
    2271           0 :         ImplInitLineColor();
    2272             : 
    2273      132827 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    2274           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    2275           0 :         && ROP_OVERPAINT == GetRasterOp()
    2276      132827 :         && IsLineColor());
    2277             : 
    2278             :     // use b2dpolygon drawing if possible
    2279      132827 :     if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap))
    2280             :     {
    2281           0 :         return;
    2282             :     }
    2283             : 
    2284             :     // #i101491#
    2285             :     // no output yet; fallback to geometry decomposition and use filled polygon paint
    2286             :     // when line is fat and not too complex. ImpDrawPolyPolygonWithB2DPolyPolygon
    2287             :     // will do internal needed AA checks etc.
    2288      132827 :     if(fLineWidth >= 2.5
    2289           0 :         && rB2DPolygon.count()
    2290      132827 :         && rB2DPolygon.count() <= 1000)
    2291             :     {
    2292           0 :         const double fHalfLineWidth((fLineWidth * 0.5) + 0.5);
    2293             :         const basegfx::B2DPolyPolygon aAreaPolyPolygon(
    2294             :             basegfx::tools::createAreaGeometry(
    2295             :                 rB2DPolygon,
    2296             :                 fHalfLineWidth,
    2297             :                 eLineJoin,
    2298           0 :                 eLineCap));
    2299           0 :         const Color aOldLineColor(maLineColor);
    2300           0 :         const Color aOldFillColor(maFillColor);
    2301             : 
    2302           0 :         SetLineColor();
    2303           0 :         ImplInitLineColor();
    2304           0 :         SetFillColor(aOldLineColor);
    2305           0 :         ImplInitFillColor();
    2306             : 
    2307             :         // draw usig a loop; else the topology will paint a PolyPolygon
    2308           0 :         for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
    2309             :         {
    2310             :             ImpDrawPolyPolygonWithB2DPolyPolygon(
    2311           0 :                 basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a)));
    2312             :         }
    2313             : 
    2314           0 :         SetLineColor(aOldLineColor);
    2315           0 :         ImplInitLineColor();
    2316           0 :         SetFillColor(aOldFillColor);
    2317           0 :         ImplInitFillColor();
    2318             : 
    2319           0 :         if(bTryAA)
    2320             :         {
    2321             :             // when AA it is necessary to also paint the filled polygon's outline
    2322             :             // to avoid optical gaps
    2323           0 :             for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
    2324             :             {
    2325           0 :                 ImpTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a));
    2326             :             }
    2327           0 :         }
    2328             :     }
    2329             :     else
    2330             :     {
    2331             :         // fallback to old polygon drawing if needed
    2332      132827 :         const Polygon aToolsPolygon( rB2DPolygon );
    2333      265654 :         LineInfo aLineInfo;
    2334      132827 :         if( fLineWidth != 0.0 )
    2335           0 :             aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    2336      265654 :         ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
    2337             :     }
    2338             : }
    2339             : 
    2340           0 : sal_uInt32 OutputDevice::GetGCStackDepth() const
    2341             : {
    2342           0 :     const ImplObjStack* pData = mpObjStack;
    2343           0 :     sal_uInt32 nDepth = 0;
    2344           0 :     while( pData )
    2345             :     {
    2346           0 :         nDepth++;
    2347           0 :         pData = pData->mpPrev;
    2348             :     }
    2349           0 :     return nDepth;
    2350             : }
    2351             : 
    2352      618993 : void OutputDevice::Push( sal_uInt16 nFlags )
    2353             : {
    2354             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    2355             : 
    2356      618993 :     if ( mpMetaFile )
    2357       34841 :         mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
    2358             : 
    2359      618993 :     ImplObjStack* pData = new ImplObjStack;
    2360      618993 :     pData->mpPrev = mpObjStack;
    2361      618993 :     mpObjStack = pData;
    2362             : 
    2363      618993 :     pData->mnFlags = nFlags;
    2364             : 
    2365      618993 :     if ( nFlags & PUSH_LINECOLOR )
    2366             :     {
    2367      108238 :         if ( mbLineColor )
    2368       78332 :             pData->mpLineColor = new Color( maLineColor );
    2369             :         else
    2370       29906 :             pData->mpLineColor = NULL;
    2371             :     }
    2372      618993 :     if ( nFlags & PUSH_FILLCOLOR )
    2373             :     {
    2374       85767 :         if ( mbFillColor )
    2375       82397 :             pData->mpFillColor = new Color( maFillColor );
    2376             :         else
    2377        3370 :             pData->mpFillColor = NULL;
    2378             :     }
    2379      618993 :     if ( nFlags & PUSH_FONT )
    2380       74785 :         pData->mpFont = new Font( maFont );
    2381      618993 :     if ( nFlags & PUSH_TEXTCOLOR )
    2382       68223 :         pData->mpTextColor = new Color( GetTextColor() );
    2383      618993 :     if ( nFlags & PUSH_TEXTFILLCOLOR )
    2384             :     {
    2385       34102 :         if ( IsTextFillColor() )
    2386         396 :             pData->mpTextFillColor = new Color( GetTextFillColor() );
    2387             :         else
    2388       33706 :             pData->mpTextFillColor = NULL;
    2389             :     }
    2390      618993 :     if ( nFlags & PUSH_TEXTLINECOLOR )
    2391             :     {
    2392       34102 :         if ( IsTextLineColor() )
    2393         512 :             pData->mpTextLineColor = new Color( GetTextLineColor() );
    2394             :         else
    2395       33590 :             pData->mpTextLineColor = NULL;
    2396             :     }
    2397      618993 :     if ( nFlags & PUSH_OVERLINECOLOR )
    2398             :     {
    2399       34102 :         if ( IsOverlineColor() )
    2400         510 :             pData->mpOverlineColor = new Color( GetOverlineColor() );
    2401             :         else
    2402       33592 :             pData->mpOverlineColor = NULL;
    2403             :     }
    2404      618993 :     if ( nFlags & PUSH_TEXTALIGN )
    2405       34102 :         pData->meTextAlign = GetTextAlign();
    2406      618993 :     if( nFlags & PUSH_TEXTLAYOUTMODE )
    2407      240863 :         pData->mnTextLayoutMode = GetLayoutMode();
    2408      618993 :     if( nFlags & PUSH_TEXTLANGUAGE )
    2409      240299 :         pData->meTextLanguage = GetDigitLanguage();
    2410      618993 :     if ( nFlags & PUSH_RASTEROP )
    2411       34102 :         pData->meRasterOp = GetRasterOp();
    2412      618993 :     if ( nFlags & PUSH_MAPMODE )
    2413             :     {
    2414       98390 :         pData->mpMapMode = new MapMode( maMapMode );
    2415       98390 :         pData->mbMapActive = mbMap;
    2416             :     }
    2417      618993 :     if ( nFlags & PUSH_CLIPREGION )
    2418             :     {
    2419      306532 :         if ( mbClipRegion )
    2420      159409 :             pData->mpClipRegion = new Region( maRegion );
    2421             :         else
    2422      147123 :             pData->mpClipRegion = NULL;
    2423             :     }
    2424      618993 :     if ( nFlags & PUSH_REFPOINT )
    2425             :     {
    2426       34102 :         if ( mbRefPoint )
    2427           0 :             pData->mpRefPoint = new Point( maRefPoint );
    2428             :         else
    2429       34102 :             pData->mpRefPoint = NULL;
    2430             :     }
    2431             : 
    2432      618993 :     if( mpAlphaVDev )
    2433       11885 :         mpAlphaVDev->Push();
    2434      618993 : }
    2435             : 
    2436      618993 : void OutputDevice::Pop()
    2437             : {
    2438             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    2439             : 
    2440      618993 :     if( mpMetaFile )
    2441       34841 :         mpMetaFile->AddAction( new MetaPopAction() );
    2442             : 
    2443      618993 :     GDIMetaFile*    pOldMetaFile = mpMetaFile;
    2444      618993 :     ImplObjStack*   pData = mpObjStack;
    2445      618993 :     mpMetaFile = NULL;
    2446             : 
    2447      618993 :     if ( !pData )
    2448             :     {
    2449             :         SAL_WARN( "vcl.gdi", "OutputDevice::Pop() without OutputDevice::Push()" );
    2450      618993 :         return;
    2451             :     }
    2452             : 
    2453      618993 :     if( mpAlphaVDev )
    2454       11885 :         mpAlphaVDev->Pop();
    2455             : 
    2456      618993 :     mpObjStack = pData->mpPrev;
    2457             : 
    2458      618993 :     if ( pData->mnFlags & PUSH_LINECOLOR )
    2459             :     {
    2460      108238 :         if ( pData->mpLineColor )
    2461       78332 :             SetLineColor( *pData->mpLineColor );
    2462             :         else
    2463       29906 :             SetLineColor();
    2464             :     }
    2465      618993 :     if ( pData->mnFlags & PUSH_FILLCOLOR )
    2466             :     {
    2467       85767 :         if ( pData->mpFillColor )
    2468       82397 :             SetFillColor( *pData->mpFillColor );
    2469             :         else
    2470        3370 :             SetFillColor();
    2471             :     }
    2472      618993 :     if ( pData->mnFlags & PUSH_FONT )
    2473       74785 :         SetFont( *pData->mpFont );
    2474      618993 :     if ( pData->mnFlags & PUSH_TEXTCOLOR )
    2475       68223 :         SetTextColor( *pData->mpTextColor );
    2476      618993 :     if ( pData->mnFlags & PUSH_TEXTFILLCOLOR )
    2477             :     {
    2478       34102 :         if ( pData->mpTextFillColor )
    2479         396 :             SetTextFillColor( *pData->mpTextFillColor );
    2480             :         else
    2481       33706 :             SetTextFillColor();
    2482             :     }
    2483      618993 :     if ( pData->mnFlags & PUSH_TEXTLINECOLOR )
    2484             :     {
    2485       34102 :         if ( pData->mpTextLineColor )
    2486         512 :             SetTextLineColor( *pData->mpTextLineColor );
    2487             :         else
    2488       33590 :             SetTextLineColor();
    2489             :     }
    2490      618993 :     if ( pData->mnFlags & PUSH_OVERLINECOLOR )
    2491             :     {
    2492       34102 :         if ( pData->mpOverlineColor )
    2493         510 :             SetOverlineColor( *pData->mpOverlineColor );
    2494             :         else
    2495       33592 :             SetOverlineColor();
    2496             :     }
    2497      618993 :     if ( pData->mnFlags & PUSH_TEXTALIGN )
    2498       34102 :         SetTextAlign( pData->meTextAlign );
    2499      618993 :     if( pData->mnFlags & PUSH_TEXTLAYOUTMODE )
    2500      240863 :         SetLayoutMode( pData->mnTextLayoutMode );
    2501      618993 :     if( pData->mnFlags & PUSH_TEXTLANGUAGE )
    2502      240299 :         SetDigitLanguage( pData->meTextLanguage );
    2503      618993 :     if ( pData->mnFlags & PUSH_RASTEROP )
    2504       34102 :         SetRasterOp( pData->meRasterOp );
    2505      618993 :     if ( pData->mnFlags & PUSH_MAPMODE )
    2506             :     {
    2507       98390 :         if ( pData->mpMapMode )
    2508       98390 :             SetMapMode( *pData->mpMapMode );
    2509             :         else
    2510           0 :             SetMapMode();
    2511       98390 :         mbMap = pData->mbMapActive;
    2512             :     }
    2513      618993 :     if ( pData->mnFlags & PUSH_CLIPREGION )
    2514      306532 :         ImplSetClipRegion( pData->mpClipRegion );
    2515      618993 :     if ( pData->mnFlags & PUSH_REFPOINT )
    2516             :     {
    2517       34102 :         if ( pData->mpRefPoint )
    2518           0 :             SetRefPoint( *pData->mpRefPoint );
    2519             :         else
    2520       34102 :             SetRefPoint();
    2521             :     }
    2522             : 
    2523      618993 :     ImplDeleteObjStack( pData );
    2524             : 
    2525      618993 :     mpMetaFile = pOldMetaFile;
    2526             : }
    2527             : 
    2528       21410 : void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
    2529             : {
    2530       21410 :     mpMetaFile = pMtf;
    2531       21410 : }
    2532             : 
    2533       19927 : void OutputDevice::EnableOutput( sal_Bool bEnable )
    2534             : {
    2535       19927 :     mbOutput = (bEnable != 0);
    2536             : 
    2537       19927 :     if( mpAlphaVDev )
    2538           0 :         mpAlphaVDev->EnableOutput( bEnable );
    2539       19927 : }
    2540             : 
    2541      112900 : void OutputDevice::SetSettings( const AllSettings& rSettings )
    2542             : {
    2543      112900 :     maSettings = rSettings;
    2544             : 
    2545      112900 :     if( mpAlphaVDev )
    2546           0 :         mpAlphaVDev->SetSettings( rSettings );
    2547      112900 : }
    2548             : 
    2549      209410 : sal_uInt16 OutputDevice::GetBitCount() const
    2550             : {
    2551             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    2552             : 
    2553      209410 :     if ( meOutDevType == OUTDEV_VIRDEV )
    2554       80032 :         return ((VirtualDevice*)this)->mnBitCount;
    2555             : 
    2556             :     // we need a graphics
    2557      129378 :     if ( !mpGraphics )
    2558             :     {
    2559           0 :         if ( !((OutputDevice*)this)->ImplGetGraphics() )
    2560           0 :             return 0;
    2561             :     }
    2562             : 
    2563      129378 :     return (sal_uInt16)mpGraphics->GetBitCount();
    2564             : }
    2565             : 
    2566           0 : sal_uInt16 OutputDevice::GetAlphaBitCount() const
    2567             : {
    2568             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    2569             : 
    2570           0 :     if ( meOutDevType == OUTDEV_VIRDEV &&
    2571           0 :         mpAlphaVDev != NULL )
    2572             :     {
    2573           0 :         return mpAlphaVDev->GetBitCount();
    2574             :     }
    2575             : 
    2576           0 :     return 0;
    2577             : }
    2578             : 
    2579         206 : sal_uLong OutputDevice::GetColorCount() const
    2580             : {
    2581             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    2582             : 
    2583         206 :     const sal_uInt16 nBitCount = GetBitCount();
    2584         206 :     return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) );
    2585             : }
    2586             : 
    2587           0 : sal_Bool OutputDevice::HasAlpha()
    2588             : {
    2589           0 :     return mpAlphaVDev != NULL;
    2590             : }
    2591             : 
    2592       11209 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > OutputDevice::CreateUnoGraphics()
    2593             : {
    2594       11209 :     UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
    2595       11209 :     return pWrapper ? pWrapper->CreateGraphics( this ) : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >();
    2596             : }
    2597             : 
    2598           2 : SystemGraphicsData OutputDevice::GetSystemGfxData() const
    2599             : {
    2600           2 :     if ( !mpGraphics )
    2601             :     {
    2602           1 :         if ( !ImplGetGraphics() )
    2603           0 :             return SystemGraphicsData();
    2604             :     }
    2605             : 
    2606           2 :     return mpGraphics->GetGraphicsData();
    2607             : }
    2608             : 
    2609           1 : ::com::sun::star::uno::Any OutputDevice::GetSystemGfxDataAny() const
    2610             : {
    2611           1 :     ::com::sun::star::uno::Any aRet;
    2612           1 :     const SystemGraphicsData aSysData = GetSystemGfxData();
    2613             :     ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)&aSysData,
    2614           2 :                                                       aSysData.nSize );
    2615             : 
    2616           2 :     return uno::makeAny(aSeq);
    2617             : }
    2618             : 
    2619           0 : ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > OutputDevice::GetCanvas() const
    2620             : {
    2621           0 :     uno::Sequence< uno::Any > aArg(6);
    2622             : 
    2623           0 :     aArg[ 0 ] = uno::makeAny( reinterpret_cast<sal_Int64>(this) );
    2624           0 :     aArg[ 2 ] = uno::makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
    2625           0 :     aArg[ 3 ] = uno::makeAny( sal_False );
    2626           0 :     aArg[ 5 ] = GetSystemGfxDataAny();
    2627             : 
    2628           0 :     uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
    2629             : 
    2630             :     // Create canvas instance with window handle
    2631             :     // =========================================
    2632           0 :     static uno::Reference<lang::XMultiComponentFactory> xCanvasFactory( rendering::CanvasFactory::create( xContext ) );
    2633             : 
    2634           0 :     uno::Reference<rendering::XCanvas> xCanvas;
    2635             :     xCanvas.set(
    2636           0 :         xCanvasFactory->createInstanceWithArgumentsAndContext(
    2637           0 :             "com.sun.star.rendering.Canvas", aArg, xContext ),
    2638           0 :         uno::UNO_QUERY );
    2639             : 
    2640           0 :     return xCanvas;
    2641         465 : }
    2642             : 
    2643             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10