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

Generated by: LCOV version 1.10