LCOV - code coverage report
Current view: top level - vcl/source/gdi - outdev.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 889 1180 75.3 %
Date: 2014-04-11 Functions: 67 75 89.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <tools/debug.hxx>
      21             : #include <tools/poly.hxx>
      22             : 
      23             : #include <vcl/svapp.hxx>
      24             : #include <vcl/ctrl.hxx>
      25             : #include <vcl/region.hxx>
      26             : #include <vcl/virdev.hxx>
      27             : #include <vcl/window.hxx>
      28             : #include <vcl/metaact.hxx>
      29             : #include <vcl/gdimtf.hxx>
      30             : #include <vcl/print.hxx>
      31             : #include <vcl/outdev.hxx>
      32             : #include <vcl/unowrap.hxx>
      33             : #include <vcl/settings.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 <outdata.hxx>
      46             : #include "PhysicalFontCollection.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/rendering/CanvasFactory.hpp>
      61             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      62             : #include <comphelper/processfactory.hxx>
      63             : 
      64             : #include <numeric>
      65             : 
      66             : #ifdef DISABLE_DYNLOADING
      67             : // Linking all needed LO code into one .so/executable, these already
      68             : // exist in the tools library, so put them in the anonymous namespace
      69             : // here to avoid clash...
      70             : namespace {
      71             : #endif
      72             : #ifdef DISABLE_DYNLOADING
      73             : }
      74             : #endif
      75             : 
      76             : #ifdef DBG_UTIL
      77             : const char* ImplDbgCheckOutputDevice( const void* pObj )
      78             : {
      79             :     DBG_TESTSOLARMUTEX();
      80             : 
      81             :     const OutputDevice* pOutDev = (OutputDevice*)pObj;
      82             : 
      83             :     if ( (pOutDev->GetOutDevType() != OUTDEV_DONTKNOW) &&
      84             :          (pOutDev->GetOutDevType() != OUTDEV_WINDOW) &&
      85             :          (pOutDev->GetOutDevType() != OUTDEV_PRINTER) &&
      86             :          (pOutDev->GetOutDevType() != OUTDEV_VIRDEV) )
      87             :         return "OutputDevice data overwrite";
      88             : 
      89             :     return NULL;
      90             : }
      91             : #endif
      92             : 
      93             : #define OUTDEV_POLYPOLY_STACKBUF        32
      94             : 
      95             : struct ImplObjStack
      96             : {
      97             :     ImplObjStack*   mpPrev;
      98             :     MapMode*        mpMapMode;
      99             :     bool            mbMapActive;
     100             :     Region*         mpClipRegion;
     101             :     Color*          mpLineColor;
     102             :     Color*          mpFillColor;
     103             :     Font*           mpFont;
     104             :     Color*          mpTextColor;
     105             :     Color*          mpTextFillColor;
     106             :     Color*          mpTextLineColor;
     107             :     Color*          mpOverlineColor;
     108             :     Point*          mpRefPoint;
     109             :     TextAlign       meTextAlign;
     110             :     RasterOp        meRasterOp;
     111             :     sal_uLong           mnTextLayoutMode;
     112             :     LanguageType    meTextLanguage;
     113             :     sal_uInt16          mnFlags;
     114             : };
     115             : 
     116      704781 : static void ImplDeleteObjStack( ImplObjStack* pObjStack )
     117             : {
     118      704781 :     if ( pObjStack->mnFlags & PUSH_LINECOLOR )
     119             :     {
     120      146297 :         if ( pObjStack->mpLineColor )
     121      112823 :             delete pObjStack->mpLineColor;
     122             :     }
     123      704781 :     if ( pObjStack->mnFlags & PUSH_FILLCOLOR )
     124             :     {
     125      122600 :         if ( pObjStack->mpFillColor )
     126      118534 :             delete pObjStack->mpFillColor;
     127             :     }
     128      704781 :     if ( pObjStack->mnFlags & PUSH_FONT )
     129      110789 :         delete pObjStack->mpFont;
     130      704781 :     if ( pObjStack->mnFlags & PUSH_TEXTCOLOR )
     131      101048 :         delete pObjStack->mpTextColor;
     132      704781 :     if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR )
     133             :     {
     134       49175 :         if ( pObjStack->mpTextFillColor )
     135         682 :             delete pObjStack->mpTextFillColor;
     136             :     }
     137      704781 :     if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR )
     138             :     {
     139       49175 :         if ( pObjStack->mpTextLineColor )
     140         682 :             delete pObjStack->mpTextLineColor;
     141             :     }
     142      704781 :     if ( pObjStack->mnFlags & PUSH_OVERLINECOLOR )
     143             :     {
     144       49175 :         if ( pObjStack->mpOverlineColor )
     145         688 :             delete pObjStack->mpOverlineColor;
     146             :     }
     147      704781 :     if ( pObjStack->mnFlags & PUSH_MAPMODE )
     148             :     {
     149      139450 :         if ( pObjStack->mpMapMode )
     150      139450 :             delete pObjStack->mpMapMode;
     151             :     }
     152      704781 :     if ( pObjStack->mnFlags & PUSH_CLIPREGION )
     153             :     {
     154      322912 :         if ( pObjStack->mpClipRegion )
     155      152297 :             delete pObjStack->mpClipRegion;
     156             :     }
     157      704781 :     if ( pObjStack->mnFlags & PUSH_REFPOINT )
     158             :     {
     159       49175 :         if ( pObjStack->mpRefPoint )
     160           0 :             delete pObjStack->mpRefPoint;
     161             :     }
     162             : 
     163      704781 :     delete pObjStack;
     164      704781 : }
     165             : 
     166      404893 : bool OutputDevice::ImplIsAntiparallel() const
     167             : {
     168      404893 :     bool bRet = false;
     169      404893 :     if( ImplGetGraphics() )
     170             :     {
     171      811216 :         if( ( (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && ! IsRTLEnabled() ) ||
     172      797559 :             ( ! (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && IsRTLEnabled() ) )
     173             :         {
     174        1430 :             bRet = true;
     175             :         }
     176             :     }
     177      404893 :     return bRet;
     178             : }
     179             : 
     180      435063 : bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGraphics )
     181             : {
     182             :     DBG_TESTSOLARMUTEX();
     183             : 
     184      435063 :     if( !pGraphics )
     185             :     {
     186      434793 :         if( !mpGraphics )
     187           0 :             if( !ImplInitGraphics() )
     188           0 :                 return false;
     189      434793 :         pGraphics = mpGraphics;
     190             :     }
     191             : 
     192      435063 :     bool bClipRegion = pGraphics->SetClipRegion( rRegion, this );
     193             :     OSL_ENSURE( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" );
     194      435063 :     return bClipRegion;
     195             : }
     196             : 
     197       16237 : Polygon ImplSubdivideBezier( const Polygon& rPoly )
     198             : {
     199       16237 :     Polygon aPoly;
     200             : 
     201             :     // #100127# Use adaptive subdivide instead of fixed 25 segments
     202       16237 :     rPoly.AdaptiveSubdivide( aPoly );
     203             : 
     204       16237 :     return aPoly;
     205             : }
     206             : 
     207        1774 : PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
     208             : {
     209        1774 :     sal_uInt16 i, nPolys = rPolyPoly.Count();
     210        1774 :     PolyPolygon aPolyPoly( nPolys );
     211        7409 :     for( i=0; i<nPolys; ++i )
     212        5635 :         aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );
     213             : 
     214        1774 :     return aPolyPoly;
     215             : }
     216             : 
     217             : // #100127# Extracted from OutputDevice::DrawPolyPolygon()
     218       52349 : void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
     219             : {
     220             :     // AW: This crashes on empty PolyPolygons, avoid that
     221       52349 :     if(!nPoly)
     222       52349 :         return;
     223             : 
     224             :     sal_uInt32          aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
     225             :     PCONSTSALPOINT      aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
     226             :     sal_uInt8*              aStackAry3[OUTDEV_POLYPOLY_STACKBUF];
     227             :     sal_uInt32*         pPointAry;
     228             :     PCONSTSALPOINT*     pPointAryAry;
     229             :     const sal_uInt8**       pFlagAryAry;
     230       52349 :     sal_uInt16              i = 0, j = 0, last = 0;
     231       52349 :     bool                bHaveBezier = false;
     232       52349 :     if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
     233             :     {
     234         102 :         pPointAry       = new sal_uInt32[nPoly];
     235         102 :         pPointAryAry    = new PCONSTSALPOINT[nPoly];
     236         102 :         pFlagAryAry     = new const sal_uInt8*[nPoly];
     237             :     }
     238             :     else
     239             :     {
     240       52247 :         pPointAry       = aStackAry1;
     241       52247 :         pPointAryAry    = aStackAry2;
     242       52247 :         pFlagAryAry     = (const sal_uInt8**)aStackAry3;
     243             :     }
     244       67188 :     do
     245             :     {
     246       67188 :         const Polygon&  rPoly = rPolyPoly.GetObject( i );
     247       67188 :         sal_uInt16          nSize = rPoly.GetSize();
     248       67188 :         if ( nSize )
     249             :         {
     250       67188 :             pPointAry[j]    = nSize;
     251       67188 :             pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
     252       67188 :             pFlagAryAry[j]  = rPoly.GetConstFlagAry();
     253       67188 :             last            = i;
     254             : 
     255       67188 :             if( pFlagAryAry[j] )
     256        9599 :                 bHaveBezier = true;
     257             : 
     258       67188 :             ++j;
     259             :         }
     260             : 
     261       67188 :         ++i;
     262             :     }
     263             :     while ( i < nPoly );
     264             : 
     265       52349 :     if ( j == 1 )
     266             :     {
     267             :         // #100127# Forward beziers to sal, if any
     268       48371 :         if( bHaveBezier )
     269             :         {
     270        5203 :             if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
     271             :             {
     272        5203 :                 Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
     273        5203 :                 mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
     274             :             }
     275             :         }
     276             :         else
     277             :         {
     278       43168 :             mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
     279             :         }
     280             :     }
     281             :     else
     282             :     {
     283             :         // #100127# Forward beziers to sal, if any
     284        3978 :         if( bHaveBezier )
     285             :         {
     286        1774 :             if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
     287             :             {
     288        1774 :                 PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
     289        1774 :                 ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
     290             :             }
     291             :         }
     292             :         else
     293             :         {
     294        2204 :             mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
     295             :         }
     296             :     }
     297             : 
     298       52349 :     if ( pPointAry != aStackAry1 )
     299             :     {
     300         102 :         delete[] pPointAry;
     301         102 :         delete[] pPointAryAry;
     302         102 :         delete[] pFlagAryAry;
     303             :     }
     304             : }
     305             : 
     306      222809 : OutputDevice::OutputDevice() :
     307             :     maRegion(true),
     308             :     maFillColor( COL_WHITE ),
     309             :     maTextLineColor( COL_TRANSPARENT ),
     310      222809 :     mxSettings( new AllSettings(Application::GetSettings()) )
     311             : {
     312             : 
     313      222809 :     mpGraphics          = NULL;
     314      222809 :     mpUnoGraphicsList   = NULL;
     315      222809 :     mpPrevGraphics      = NULL;
     316      222809 :     mpNextGraphics      = NULL;
     317      222809 :     mpMetaFile          = NULL;
     318      222809 :     mpFontEntry         = NULL;
     319      222809 :     mpFontCache         = NULL;
     320      222809 :     mpFontCollection   = NULL;
     321      222809 :     mpGetDevFontList    = NULL;
     322      222809 :     mpGetDevSizeList    = NULL;
     323      222809 :     mpObjStack          = NULL;
     324      222809 :     mpOutDevData        = NULL;
     325      222809 :     mpPDFWriter         = NULL;
     326      222809 :     mpAlphaVDev         = NULL;
     327      222809 :     mpExtOutDevData     = NULL;
     328      222809 :     mnOutOffX           = 0;
     329      222809 :     mnOutOffY           = 0;
     330      222809 :     mnOutWidth          = 0;
     331      222809 :     mnOutHeight         = 0;
     332      222809 :     mnDPIX              = 0;
     333      222809 :     mnDPIY              = 0;
     334      222809 :     mnDPIScaleFactor    = 1;
     335      222809 :     mnTextOffX          = 0;
     336      222809 :     mnTextOffY          = 0;
     337      222809 :     mnOutOffOrigX       = 0;
     338      222809 :     mnOutOffLogicX      = 0;
     339      222809 :     mnOutOffOrigY       = 0;
     340      222809 :     mnOutOffLogicY      = 0;
     341      222809 :     mnEmphasisAscent    = 0;
     342      222809 :     mnEmphasisDescent   = 0;
     343      222809 :     mnDrawMode          = 0;
     344      222809 :     mnTextLayoutMode        = TEXT_LAYOUT_DEFAULT;
     345      222809 :     if( Application::GetSettings().GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
     346           0 :         mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
     347      222809 :     meOutDevType        = OUTDEV_DONTKNOW;
     348      222809 :     meOutDevViewType    = OUTDEV_VIEWTYPE_DONTKNOW;
     349      222809 :     mbMap               = false;
     350      222809 :     mbMapIsDefault      = true;
     351      222809 :     mbClipRegion        = false;
     352      222809 :     mbBackground        = false;
     353      222809 :     mbOutput            = true;
     354      222809 :     mbDevOutput         = false;
     355      222809 :     mbOutputClipped     = false;
     356      222809 :     maTextColor         = Color( COL_BLACK );
     357      222809 :     maOverlineColor     = Color( COL_TRANSPARENT );
     358      222809 :     meTextAlign         = maFont.GetAlign();
     359      222809 :     meRasterOp          = ROP_OVERPAINT;
     360      222809 :     mnAntialiasing      = 0;
     361      222809 :     meTextLanguage      = 0;  // TODO: get default from configuration?
     362      222809 :     mbLineColor         = true;
     363      222809 :     mbFillColor         = true;
     364      222809 :     mbInitLineColor     = true;
     365      222809 :     mbInitFillColor     = true;
     366      222809 :     mbInitFont          = true;
     367      222809 :     mbInitTextColor     = true;
     368      222809 :     mbInitClipRegion    = true;
     369      222809 :     mbClipRegionSet     = false;
     370      222809 :     mbKerning           = false;
     371      222809 :     mbNewFont           = true;
     372      222809 :     mbTextLines         = false;
     373      222809 :     mbTextSpecial       = false;
     374      222809 :     mbRefPoint          = false;
     375      222809 :     mbEnableRTL         = false;    // mirroring must be explicitly allowed (typically for windows only)
     376             : 
     377             :     // struct ImplMapRes
     378      222809 :     maMapRes.mnMapOfsX          = 0;
     379      222809 :     maMapRes.mnMapOfsY          = 0;
     380      222809 :     maMapRes.mnMapScNumX        = 1;
     381      222809 :     maMapRes.mnMapScNumY        = 1;
     382      222809 :     maMapRes.mnMapScDenomX      = 1;
     383      222809 :     maMapRes.mnMapScDenomY      = 1;
     384             :     // struct ImplThresholdRes
     385      222809 :     maThresRes.mnThresLogToPixX = 0;
     386      222809 :     maThresRes.mnThresLogToPixY = 0;
     387      222809 :     maThresRes.mnThresPixToLogX = 0;
     388      222809 :     maThresRes.mnThresPixToLogY = 0;
     389      222809 : }
     390             : 
     391      440942 : OutputDevice::~OutputDevice()
     392             : {
     393             : 
     394      220471 :     if ( GetUnoGraphicsList() )
     395             :     {
     396        1193 :         UnoWrapperBase* pWrapper = Application::GetUnoWrapper( false );
     397        1193 :         if ( pWrapper )
     398        1193 :             pWrapper->ReleaseAllGraphics( this );
     399        1193 :         delete mpUnoGraphicsList;
     400        1193 :         mpUnoGraphicsList = NULL;
     401             :     }
     402             : 
     403      220471 :     if ( mpOutDevData )
     404        2943 :         ImplDeInitOutDevData();
     405             : 
     406      220471 :     ImplObjStack* pData = mpObjStack;
     407      220471 :     if ( pData )
     408             :     {
     409             :         SAL_WARN( "vcl.gdi", "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
     410           0 :         while ( pData )
     411             :         {
     412           0 :             ImplObjStack* pTemp = pData;
     413           0 :             pData = pData->mpPrev;
     414           0 :             ImplDeleteObjStack( pTemp );
     415             :         }
     416             :     }
     417             : 
     418             :     // release the active font instance
     419      220471 :     if( mpFontEntry )
     420           0 :         mpFontCache->Release( mpFontEntry );
     421             :     // remove cached results of GetDevFontList/GetDevSizeList
     422             :     // TODO: use smart pointers for them
     423      220471 :     if( mpGetDevFontList )
     424           0 :         delete mpGetDevFontList;
     425      220471 :     if( mpGetDevSizeList )
     426           0 :         delete mpGetDevSizeList;
     427             : 
     428             :     // release ImplFontCache specific to this OutputDevice
     429             :     // TODO: refcount ImplFontCache
     430      220471 :     if( mpFontCache
     431      220202 :     && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
     432      222715 :     && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
     433             :     {
     434        2244 :         delete mpFontCache;
     435        2244 :         mpFontCache = NULL;
     436             :     }
     437             : 
     438             :     // release ImplFontList specific to this OutputDevice
     439             :     // TODO: refcount ImplFontList
     440      220471 :     if( mpFontCollection
     441      220471 :     && (mpFontCollection != ImplGetSVData()->maGDIData.mpScreenFontList)
     442      222984 :     && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
     443             :     {
     444        2513 :         mpFontCollection->Clear();
     445        2513 :         delete mpFontCollection;
     446        2513 :         mpFontCollection = NULL;
     447             :     }
     448             : 
     449      220471 :     delete mpAlphaVDev;
     450      220471 : }
     451             : 
     452        8775 : bool OutputDevice::supportsOperation( OutDevSupportType eType ) const
     453             : {
     454        8775 :     if( !mpGraphics )
     455           0 :         if( !ImplGetGraphics() )
     456           0 :             return false;
     457        8775 :     const bool bHasSupport = mpGraphics->supportsOperation( eType );
     458        8775 :     return bHasSupport;
     459             : }
     460             : 
     461       44493 : void OutputDevice::EnableRTL( bool bEnable )
     462             : {
     463       44493 :     mbEnableRTL = bEnable;
     464             : 
     465       44493 :     if( mpAlphaVDev )
     466        7635 :         mpAlphaVDev->EnableRTL( bEnable );
     467       44493 : }
     468             : 
     469      477839 : bool OutputDevice::HasMirroredGraphics() const
     470             : {
     471      477839 :    return ( ImplGetGraphics() && (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) );
     472             : }
     473             : 
     474             : // note: the coordiantes to be remirrored are in frame coordiantes !
     475             : 
     476          16 : void    OutputDevice::ReMirror( Point &rPoint ) const
     477             : {
     478          16 :     rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
     479          16 : }
     480          44 : void    OutputDevice::ReMirror( Rectangle &rRect ) const
     481             : {
     482          44 :     long nWidth = rRect.Right() - rRect.Left();
     483             : 
     484             :     //long lc_x = rRect.nLeft - mnOutOffX;    // normalize
     485             :     //lc_x = mnOutWidth - nWidth - 1 - lc_x;  // mirror
     486             :     //rRect.nLeft = lc_x + mnOutOffX;         // re-normalize
     487             : 
     488          44 :     rRect.Left() = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.Left() + mnOutOffX;
     489          44 :     rRect.Right() = rRect.Left() + nWidth;
     490          44 : }
     491         498 : void    OutputDevice::ReMirror( Region &rRegion ) const
     492             : {
     493         498 :     RectangleVector aRectangles;
     494         498 :     rRegion.GetRegionRectangles(aRectangles);
     495         996 :     Region aMirroredRegion;
     496             : 
     497         520 :     for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     498             :     {
     499          22 :         ReMirror(*aRectIter);
     500          22 :         aMirroredRegion.Union(*aRectIter);
     501             :     }
     502             : 
     503         996 :     rRegion = aMirroredRegion;
     504             : 
     505         498 : }
     506             : 
     507      151173 : SalGraphics* OutputDevice::ImplGetGraphics()
     508             : {
     509             :     DBG_TESTSOLARMUTEX();
     510             : 
     511      151173 :     if ( !mpGraphics )
     512             :     {
     513      128469 :         if ( !ImplInitGraphics() )
     514             :         {
     515             :             SAL_WARN("vcl", "No mpGraphics set");
     516             :         }
     517             :     }
     518             : 
     519      151173 :     return mpGraphics;
     520             : }
     521             : 
     522      936329 : SalGraphics const *OutputDevice::ImplGetGraphics() const
     523             : {
     524             :     DBG_TESTSOLARMUTEX();
     525             : 
     526      936329 :     if ( !mpGraphics )
     527             :     {
     528      102886 :         if ( !ImplInitGraphics() )
     529             :         {
     530             :             SAL_WARN("vcl", "No mpGraphics set");
     531             :         }
     532             :     }
     533             : 
     534      936329 :     return mpGraphics;
     535             : }
     536             : 
     537        2953 : void OutputDevice::ImplInitOutDevData()
     538             : {
     539        2953 :     if ( !mpOutDevData )
     540             :     {
     541        2953 :         mpOutDevData = new ImplOutDevData;
     542        2953 :         mpOutDevData->mpRotateDev = NULL;
     543        2953 :         mpOutDevData->mpRecordLayout = NULL;
     544             : 
     545             :         // #i75163#
     546        2953 :         mpOutDevData->mpViewTransform = NULL;
     547        2953 :         mpOutDevData->mpInverseViewTransform = NULL;
     548             :     }
     549        2953 : }
     550             : 
     551      228761 : void OutputDevice::ImplReleaseFonts()
     552             : {
     553      228761 :     mpGraphics->ReleaseFonts();
     554      228761 :     mbNewFont = true;
     555      228761 :     mbInitFont = true;
     556             : 
     557      228761 :     if ( mpFontEntry )
     558             :     {
     559       63226 :         mpFontCache->Release( mpFontEntry );
     560       63226 :         mpFontEntry = NULL;
     561             :     }
     562             : 
     563      228761 :     if ( mpGetDevFontList )
     564             :     {
     565        2771 :         delete mpGetDevFontList;
     566        2771 :         mpGetDevFontList = NULL;
     567             :     }
     568             : 
     569      228761 :     if ( mpGetDevSizeList )
     570             :     {
     571         520 :         delete mpGetDevSizeList;
     572         520 :         mpGetDevSizeList = NULL;
     573             :     }
     574      228761 : }
     575             : 
     576             : // #i75163#
     577      209543 : void OutputDevice::ImplInvalidateViewTransform()
     578             : {
     579      209543 :     if(mpOutDevData)
     580             :     {
     581       83991 :         if(mpOutDevData->mpViewTransform)
     582             :         {
     583       30454 :             delete mpOutDevData->mpViewTransform;
     584       30454 :             mpOutDevData->mpViewTransform = NULL;
     585             :         }
     586             : 
     587       83991 :         if(mpOutDevData->mpInverseViewTransform)
     588             :         {
     589       15191 :             delete mpOutDevData->mpInverseViewTransform;
     590       15191 :             mpOutDevData->mpInverseViewTransform = NULL;
     591             :         }
     592             :     }
     593      209543 : }
     594             : 
     595     3182823 : bool OutputDevice::ImplIsRecordLayout() const
     596             : {
     597     3182823 :     return mpOutDevData && mpOutDevData->mpRecordLayout;
     598             : }
     599             : 
     600        2943 : void OutputDevice::ImplDeInitOutDevData()
     601             : {
     602        2943 :     if ( mpOutDevData )
     603             :     {
     604        2943 :         if ( mpOutDevData->mpRotateDev )
     605           0 :             delete mpOutDevData->mpRotateDev;
     606             : 
     607             :         // #i75163#
     608        2943 :         ImplInvalidateViewTransform();
     609             : 
     610        2943 :         delete mpOutDevData;
     611             :     }
     612        2943 : }
     613             : 
     614      582124 : void OutputDevice::ImplInitLineColor()
     615             : {
     616             :     DBG_TESTSOLARMUTEX();
     617             : 
     618      582124 :     if( mbLineColor )
     619             :     {
     620      288345 :         if( ROP_0 == meRasterOp )
     621           0 :             mpGraphics->SetROPLineColor( SAL_ROP_0 );
     622      288345 :         else if( ROP_1 == meRasterOp )
     623           0 :             mpGraphics->SetROPLineColor( SAL_ROP_1 );
     624      288345 :         else if( ROP_INVERT == meRasterOp )
     625           0 :             mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
     626             :         else
     627      288345 :             mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
     628             :     }
     629             :     else
     630      293779 :         mpGraphics->SetLineColor();
     631             : 
     632      582124 :     mbInitLineColor = false;
     633      582124 : }
     634             : 
     635      469354 : void OutputDevice::ImplInitFillColor()
     636             : {
     637             :     DBG_TESTSOLARMUTEX();
     638             : 
     639      469354 :     if( mbFillColor )
     640             :     {
     641      462944 :         if( ROP_0 == meRasterOp )
     642           0 :             mpGraphics->SetROPFillColor( SAL_ROP_0 );
     643      462944 :         else if( ROP_1 == meRasterOp )
     644           0 :             mpGraphics->SetROPFillColor( SAL_ROP_1 );
     645      462944 :         else if( ROP_INVERT == meRasterOp )
     646           0 :             mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
     647             :         else
     648      462944 :             mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
     649             :     }
     650             :     else
     651        6410 :         mpGraphics->SetFillColor();
     652             : 
     653      469354 :     mbInitFillColor = false;
     654      469354 : }
     655             : 
     656             : // TODO: fdo#74424 - this needs to be moved out of OutputDevice and into the
     657             : // Window, VirtualDevice and Printer classes
     658      658661 : void OutputDevice::ImplInitClipRegion()
     659             : {
     660             :     DBG_TESTSOLARMUTEX();
     661             : 
     662      658661 :     if ( GetOutDevType() == OUTDEV_WINDOW )
     663             :     {
     664      500629 :         Window* pWindow = (Window*)this;
     665      500629 :         Region  aRegion;
     666             : 
     667             :         // Put back backed up background
     668      500629 :         if ( pWindow->mpWindowImpl->mpFrameData->mpFirstBackWin )
     669           0 :             pWindow->ImplInvalidateAllOverlapBackgrounds();
     670      500629 :         if ( pWindow->mpWindowImpl->mbInPaint )
     671      481098 :             aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
     672             :         else
     673             :         {
     674       19531 :             aRegion = *(pWindow->ImplGetWinChildClipRegion());
     675             :             // --- RTL -- only this region is in frame coordinates, so re-mirror it
     676             :             // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) !
     677       19531 :             if( ImplIsAntiparallel() )
     678         476 :                 ReMirror ( aRegion );
     679             :         }
     680      500629 :         if ( mbClipRegion )
     681      331341 :             aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
     682      500629 :         if ( aRegion.IsEmpty() )
     683       91049 :             mbOutputClipped = true;
     684             :         else
     685             :         {
     686      409580 :             mbOutputClipped = false;
     687      409580 :             ImplSelectClipRegion( aRegion );
     688             :         }
     689      500629 :         mbClipRegionSet = true;
     690             :     }
     691             :     else
     692             :     {
     693      158032 :         if ( mbClipRegion )
     694             :         {
     695       25472 :             if ( maRegion.IsEmpty() )
     696         257 :                 mbOutputClipped = true;
     697             :             else
     698             :             {
     699       25215 :                 mbOutputClipped = false;
     700             : 
     701             :                 // #102532# Respect output offset also for clip region
     702       25215 :                 Region aRegion( ImplPixelToDevicePixel( maRegion ) );
     703       25215 :                 const bool bClipDeviceBounds( ! GetPDFWriter()
     704       25215 :                                               && GetOutDevType() != OUTDEV_PRINTER );
     705       25215 :                 if( bClipDeviceBounds )
     706             :                 {
     707             :                     // Perform actual rect clip against outdev
     708             :                     // dimensions, to generate empty clips whenever one of the
     709             :                     // values is completely off the device.
     710             :                     Rectangle aDeviceBounds( mnOutOffX, mnOutOffY,
     711       25215 :                                              mnOutOffX+GetOutputWidthPixel()-1,
     712       50430 :                                              mnOutOffY+GetOutputHeightPixel()-1 );
     713       25215 :                     aRegion.Intersect( aDeviceBounds );
     714             :                 }
     715             : 
     716       25215 :                 if ( aRegion.IsEmpty() )
     717             :                 {
     718           2 :                     mbOutputClipped = true;
     719             :                 }
     720             :                 else
     721             :                 {
     722       25213 :                     mbOutputClipped = false;
     723       25213 :                     ImplSelectClipRegion( aRegion );
     724       25215 :                 }
     725             :             }
     726             : 
     727       25472 :             mbClipRegionSet = true;
     728             :         }
     729             :         else
     730             :         {
     731      132560 :             if ( mbClipRegionSet )
     732             :             {
     733        4857 :                 mpGraphics->ResetClipRegion();
     734        4857 :                 mbClipRegionSet = false;
     735             :             }
     736             : 
     737      132560 :             mbOutputClipped = false;
     738             :         }
     739             :     }
     740             : 
     741      658661 :     mbInitClipRegion = false;
     742      658661 : }
     743             : 
     744      400694 : void OutputDevice::ImplSetClipRegion( const Region* pRegion )
     745             : {
     746             :     DBG_TESTSOLARMUTEX();
     747             : 
     748      400694 :     if ( !pRegion )
     749             :     {
     750      202307 :         if ( mbClipRegion )
     751             :         {
     752      174652 :             maRegion            = Region(true);
     753      174652 :             mbClipRegion        = false;
     754      174652 :             mbInitClipRegion    = true;
     755             :         }
     756             :     }
     757             :     else
     758             :     {
     759      198387 :         maRegion            = *pRegion;
     760      198387 :         mbClipRegion        = true;
     761      198387 :         mbInitClipRegion    = true;
     762             :     }
     763      400694 : }
     764             : 
     765       30508 : void OutputDevice::SetClipRegion()
     766             : {
     767             : 
     768       30508 :     if ( mpMetaFile )
     769          29 :         mpMetaFile->AddAction( new MetaClipRegionAction( Region(), false ) );
     770             : 
     771       30508 :     ImplSetClipRegion( NULL );
     772             : 
     773       30508 :     if( mpAlphaVDev )
     774          13 :         mpAlphaVDev->SetClipRegion();
     775       30508 : }
     776             : 
     777       47274 : void OutputDevice::SetClipRegion( const Region& rRegion )
     778             : {
     779             : 
     780       47274 :     if ( mpMetaFile )
     781        7942 :         mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, true ) );
     782             : 
     783       47274 :     if ( rRegion.IsNull() )
     784             :     {
     785        1184 :         ImplSetClipRegion( NULL );
     786             :     }
     787             :     else
     788             :     {
     789       46090 :         Region aRegion = LogicToPixel( rRegion );
     790       46090 :         ImplSetClipRegion( &aRegion );
     791             :     }
     792             : 
     793       47274 :     if( mpAlphaVDev )
     794        7785 :         mpAlphaVDev->SetClipRegion( rRegion );
     795       47274 : }
     796             : 
     797       20028 : Region OutputDevice::GetClipRegion() const
     798             : {
     799             : 
     800       20028 :     return PixelToLogic( maRegion );
     801             : }
     802             : 
     803       85352 : Region OutputDevice::GetActiveClipRegion() const
     804             : {
     805             : 
     806       85352 :     if ( GetOutDevType() == OUTDEV_WINDOW )
     807             :     {
     808       85352 :         Region aRegion(true);
     809       85352 :         Window* pWindow = (Window*)this;
     810       85352 :         if ( pWindow->mpWindowImpl->mbInPaint )
     811             :         {
     812       85352 :             aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
     813       85352 :             aRegion.Move( -mnOutOffX, -mnOutOffY );
     814             :         }
     815       85352 :         if ( mbClipRegion )
     816           0 :             aRegion.Intersect( maRegion );
     817       85352 :         return PixelToLogic( aRegion );
     818             :     }
     819             :     else
     820           0 :         return GetClipRegion();
     821             : }
     822             : 
     823           0 : void OutputDevice::MoveClipRegion( long nHorzMove, long nVertMove )
     824             : {
     825             : 
     826           0 :     if ( mbClipRegion )
     827             :     {
     828           0 :         if( mpMetaFile )
     829           0 :             mpMetaFile->AddAction( new MetaMoveClipRegionAction( nHorzMove, nVertMove ) );
     830             : 
     831             :         maRegion.Move( ImplLogicWidthToDevicePixel( nHorzMove ),
     832           0 :                        ImplLogicHeightToDevicePixel( nVertMove ) );
     833           0 :         mbInitClipRegion = true;
     834             :     }
     835             : 
     836           0 :     if( mpAlphaVDev )
     837           0 :         mpAlphaVDev->MoveClipRegion( nHorzMove, nVertMove );
     838           0 : }
     839             : 
     840      166096 : void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
     841             : {
     842             : 
     843      166096 :     if ( mpMetaFile )
     844        5698 :         mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );
     845             : 
     846      166096 :     Rectangle aRect = LogicToPixel( rRect );
     847      166096 :     maRegion.Intersect( aRect );
     848      166096 :     mbClipRegion        = true;
     849      166096 :     mbInitClipRegion    = true;
     850             : 
     851      166096 :     if( mpAlphaVDev )
     852        1189 :         mpAlphaVDev->IntersectClipRegion( rRect );
     853      166096 : }
     854             : 
     855      114279 : void OutputDevice::IntersectClipRegion( const Region& rRegion )
     856             : {
     857             : 
     858      114279 :     if(!rRegion.IsNull())
     859             :     {
     860      114279 :         if ( mpMetaFile )
     861         867 :             mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );
     862             : 
     863      114279 :         Region aRegion = LogicToPixel( rRegion );
     864      114279 :         maRegion.Intersect( aRegion );
     865      114279 :         mbClipRegion        = true;
     866      114279 :         mbInitClipRegion    = true;
     867             :     }
     868             : 
     869      114279 :     if( mpAlphaVDev )
     870         343 :         mpAlphaVDev->IntersectClipRegion( rRegion );
     871      114279 : }
     872             : 
     873       72439 : void OutputDevice::SetDrawMode( sal_uLong nDrawMode )
     874             : {
     875             : 
     876       72439 :     mnDrawMode = nDrawMode;
     877             : 
     878       72439 :     if( mpAlphaVDev )
     879           0 :         mpAlphaVDev->SetDrawMode( nDrawMode );
     880       72439 : }
     881             : 
     882       85209 : void OutputDevice::SetRasterOp( RasterOp eRasterOp )
     883             : {
     884             : 
     885       85209 :     if ( mpMetaFile )
     886        8892 :         mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
     887             : 
     888       85209 :     if ( meRasterOp != eRasterOp )
     889             :     {
     890        6450 :         meRasterOp = eRasterOp;
     891        6450 :         mbInitLineColor = mbInitFillColor = true;
     892             : 
     893        6450 :         if( mpGraphics || ImplGetGraphics() )
     894        6450 :             mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
     895             :     }
     896             : 
     897       85209 :     if( mpAlphaVDev )
     898       15345 :         mpAlphaVDev->SetRasterOp( eRasterOp );
     899       85209 : }
     900             : 
     901      604525 : void OutputDevice::SetLineColor()
     902             : {
     903             : 
     904      604525 :     if ( mpMetaFile )
     905       10349 :         mpMetaFile->AddAction( new MetaLineColorAction( Color(), false ) );
     906             : 
     907      604525 :     if ( mbLineColor )
     908             :     {
     909      319967 :         mbInitLineColor = true;
     910      319967 :         mbLineColor = false;
     911      319967 :         maLineColor = Color( COL_TRANSPARENT );
     912             :     }
     913             : 
     914      604525 :     if( mpAlphaVDev )
     915       11108 :         mpAlphaVDev->SetLineColor();
     916      604525 : }
     917             : 
     918     1456790 : Color OutputDevice::ImplDrawModeToColor( const Color& rColor ) const
     919             : {
     920     1456790 :     Color aColor( rColor );
     921     1456790 :     sal_uLong  nDrawMode = GetDrawMode();
     922             : 
     923     1456790 :     if( nDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
     924             :                       DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE |
     925             :                       DRAWMODE_SETTINGSLINE ) )
     926             :     {
     927           0 :         if( !ImplIsColorTransparent( aColor ) )
     928             :         {
     929           0 :             if( nDrawMode & DRAWMODE_BLACKLINE )
     930             :             {
     931           0 :                 aColor = Color( COL_BLACK );
     932             :             }
     933           0 :             else if( nDrawMode & DRAWMODE_WHITELINE )
     934             :             {
     935           0 :                 aColor = Color( COL_WHITE );
     936             :             }
     937           0 :             else if( nDrawMode & DRAWMODE_GRAYLINE )
     938             :             {
     939           0 :                 const sal_uInt8 cLum = aColor.GetLuminance();
     940           0 :                 aColor = Color( cLum, cLum, cLum );
     941             :             }
     942           0 :             else if( nDrawMode & DRAWMODE_SETTINGSLINE )
     943             :             {
     944           0 :                 aColor = GetSettings().GetStyleSettings().GetFontColor();
     945             :             }
     946             : 
     947           0 :             if( nDrawMode & DRAWMODE_GHOSTEDLINE )
     948             :             {
     949           0 :                 aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
     950           0 :                                 ( aColor.GetGreen() >> 1 ) | 0x80,
     951           0 :                                 ( aColor.GetBlue() >> 1 ) | 0x80);
     952             :             }
     953             :         }
     954             :     }
     955     1456790 :     return aColor;
     956             : }
     957             : 
     958     1153450 : void OutputDevice::SetLineColor( const Color& rColor )
     959             : {
     960             : 
     961     1153450 :     Color aColor = ImplDrawModeToColor( rColor );
     962             : 
     963     1153450 :     if( mpMetaFile )
     964       37428 :         mpMetaFile->AddAction( new MetaLineColorAction( aColor, true ) );
     965             : 
     966     1153450 :     if( ImplIsColorTransparent( aColor ) )
     967             :     {
     968       66933 :         if ( mbLineColor )
     969             :         {
     970       14061 :             mbInitLineColor = true;
     971       14061 :             mbLineColor = false;
     972       14061 :             maLineColor = Color( COL_TRANSPARENT );
     973             :         }
     974             :     }
     975             :     else
     976             :     {
     977     1086517 :         if( maLineColor != aColor )
     978             :         {
     979      666497 :             mbInitLineColor = true;
     980      666497 :             mbLineColor = true;
     981      666497 :             maLineColor = aColor;
     982             :         }
     983             :     }
     984             : 
     985     1153450 :     if( mpAlphaVDev )
     986       47169 :         mpAlphaVDev->SetLineColor( COL_BLACK );
     987     1153450 : }
     988             : 
     989      285594 : void OutputDevice::SetFillColor()
     990             : {
     991             : 
     992      285594 :     if ( mpMetaFile )
     993        3184 :         mpMetaFile->AddAction( new MetaFillColorAction( Color(), false ) );
     994             : 
     995      285594 :     if ( mbFillColor )
     996             :     {
     997       44886 :         mbInitFillColor = true;
     998       44886 :         mbFillColor = false;
     999       44886 :         maFillColor = Color( COL_TRANSPARENT );
    1000             :     }
    1001             : 
    1002      285594 :     if( mpAlphaVDev )
    1003        2434 :         mpAlphaVDev->SetFillColor();
    1004      285594 : }
    1005             : 
    1006     1150604 : void OutputDevice::SetFillColor( const Color& rColor )
    1007             : {
    1008             : 
    1009     1150604 :     Color aColor( rColor );
    1010             : 
    1011     1150604 :     if( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL |
    1012             :                        DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
    1013             :                        DRAWMODE_GHOSTEDFILL | DRAWMODE_SETTINGSFILL ) )
    1014             :     {
    1015           0 :         if( !ImplIsColorTransparent( aColor ) )
    1016             :         {
    1017           0 :             if( mnDrawMode & DRAWMODE_BLACKFILL )
    1018             :             {
    1019           0 :                 aColor = Color( COL_BLACK );
    1020             :             }
    1021           0 :             else if( mnDrawMode & DRAWMODE_WHITEFILL )
    1022             :             {
    1023           0 :                 aColor = Color( COL_WHITE );
    1024             :             }
    1025           0 :             else if( mnDrawMode & DRAWMODE_GRAYFILL )
    1026             :             {
    1027           0 :                 const sal_uInt8 cLum = aColor.GetLuminance();
    1028           0 :                 aColor = Color( cLum, cLum, cLum );
    1029             :             }
    1030           0 :             else if( mnDrawMode & DRAWMODE_NOFILL )
    1031             :             {
    1032           0 :                 aColor = Color( COL_TRANSPARENT );
    1033             :             }
    1034           0 :             else if( mnDrawMode & DRAWMODE_SETTINGSFILL )
    1035             :             {
    1036           0 :                 aColor = GetSettings().GetStyleSettings().GetWindowColor();
    1037             :             }
    1038             : 
    1039           0 :             if( mnDrawMode & DRAWMODE_GHOSTEDFILL )
    1040             :             {
    1041           0 :                 aColor = Color( (aColor.GetRed() >> 1) | 0x80,
    1042           0 :                                 (aColor.GetGreen() >> 1) | 0x80,
    1043           0 :                                 (aColor.GetBlue() >> 1) | 0x80);
    1044             :             }
    1045             :         }
    1046             :     }
    1047             : 
    1048     1150604 :     if ( mpMetaFile )
    1049       31600 :         mpMetaFile->AddAction( new MetaFillColorAction( aColor, true ) );
    1050             : 
    1051     1150604 :     if ( ImplIsColorTransparent( aColor ) )
    1052             :     {
    1053       16304 :         if ( mbFillColor )
    1054             :         {
    1055       13834 :             mbInitFillColor = true;
    1056       13834 :             mbFillColor = false;
    1057       13834 :             maFillColor = Color( COL_TRANSPARENT );
    1058             :         }
    1059             :     }
    1060             :     else
    1061             :     {
    1062     1134300 :         if ( maFillColor != aColor )
    1063             :         {
    1064      533577 :             mbInitFillColor = true;
    1065      533577 :             mbFillColor = true;
    1066      533577 :             maFillColor = aColor;
    1067             :         }
    1068             :     }
    1069             : 
    1070     1150604 :     if( mpAlphaVDev )
    1071       44027 :         mpAlphaVDev->SetFillColor( COL_BLACK );
    1072     1150604 : }
    1073             : 
    1074       38931 : void OutputDevice::SetBackground()
    1075             : {
    1076             : 
    1077       38931 :     maBackground = Wallpaper();
    1078       38931 :     mbBackground = false;
    1079             : 
    1080       38931 :     if( mpAlphaVDev )
    1081           0 :         mpAlphaVDev->SetBackground();
    1082       38931 : }
    1083             : 
    1084      383520 : void OutputDevice::SetBackground( const Wallpaper& rBackground )
    1085             : {
    1086             : 
    1087      383520 :     maBackground = rBackground;
    1088             : 
    1089      383520 :     if( rBackground.GetStyle() == WALLPAPER_NULL )
    1090         778 :         mbBackground = false;
    1091             :     else
    1092      382742 :         mbBackground = true;
    1093             : 
    1094      383520 :     if( mpAlphaVDev )
    1095           0 :         mpAlphaVDev->SetBackground( rBackground );
    1096      383520 : }
    1097             : 
    1098       79790 : void OutputDevice::SetRefPoint()
    1099             : {
    1100             : 
    1101       79790 :     if ( mpMetaFile )
    1102        7635 :         mpMetaFile->AddAction( new MetaRefPointAction( Point(), false ) );
    1103             : 
    1104       79790 :     mbRefPoint = false;
    1105       79790 :     maRefPoint.X() = maRefPoint.Y() = 0L;
    1106             : 
    1107       79790 :     if( mpAlphaVDev )
    1108       15345 :         mpAlphaVDev->SetRefPoint();
    1109       79790 : }
    1110             : 
    1111           0 : void OutputDevice::SetRefPoint( const Point& rRefPoint )
    1112             : {
    1113             : 
    1114           0 :     if ( mpMetaFile )
    1115           0 :         mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, true ) );
    1116             : 
    1117           0 :     mbRefPoint = true;
    1118           0 :     maRefPoint = rRefPoint;
    1119             : 
    1120           0 :     if( mpAlphaVDev )
    1121           0 :         mpAlphaVDev->SetRefPoint( rRefPoint );
    1122           0 : }
    1123             : 
    1124      981800 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
    1125             : {
    1126             : 
    1127      981800 :     if ( mpMetaFile )
    1128       33336 :         mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) );
    1129             : 
    1130      981800 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
    1131       44677 :         return;
    1132             : 
    1133      976675 :     if ( !mpGraphics )
    1134             :     {
    1135        1858 :         if ( !ImplGetGraphics() )
    1136           0 :             return;
    1137             :     }
    1138             : 
    1139      976675 :     if ( mbInitClipRegion )
    1140       35808 :         ImplInitClipRegion();
    1141      976675 :     if ( mbOutputClipped )
    1142       34427 :         return;
    1143             : 
    1144      942248 :     if ( mbInitLineColor )
    1145      221268 :         ImplInitLineColor();
    1146             : 
    1147             :     // #i101598# support AA and snap for lines, too
    1148     1884496 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1149           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1150           0 :         && ROP_OVERPAINT == GetRasterOp()
    1151      942248 :         && IsLineColor())
    1152             :     {
    1153             :         // at least transform with double precision to device coordinates; this will
    1154             :         // avoid pixel snap of single, appended lines
    1155           0 :         const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
    1156           0 :         const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1157           0 :         basegfx::B2DPolygon aB2DPolyLine;
    1158             : 
    1159           0 :         aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y()));
    1160           0 :         aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y()));
    1161           0 :         aB2DPolyLine.transform( aTransform );
    1162             : 
    1163           0 :         if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1164             :         {
    1165           0 :             aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
    1166             :         }
    1167             : 
    1168           0 :         if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, css::drawing::LineCap_BUTT, this))
    1169             :         {
    1170           0 :             return;
    1171           0 :         }
    1172             :     }
    1173             : 
    1174      942248 :     const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
    1175      942248 :     const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
    1176             : 
    1177      942248 :     mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
    1178             : 
    1179      942248 :     if( mpAlphaVDev )
    1180       32356 :         mpAlphaVDev->DrawLine( rStartPt, rEndPt );
    1181             : }
    1182             : 
    1183          13 : void OutputDevice::ImplPaintLineGeometryWithEvtlExpand(
    1184             :     const LineInfo& rInfo,
    1185             :     basegfx::B2DPolyPolygon aLinePolyPolygon)
    1186             : {
    1187          13 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1188           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1189           0 :         && ROP_OVERPAINT == GetRasterOp()
    1190          13 :         && IsLineColor());
    1191          13 :     basegfx::B2DPolyPolygon aFillPolyPolygon;
    1192          13 :     const bool bDashUsed(LINE_DASH == rInfo.GetStyle());
    1193          13 :     const bool bLineWidthUsed(rInfo.GetWidth() > 1);
    1194             : 
    1195          13 :     if(bDashUsed && aLinePolyPolygon.count())
    1196             :     {
    1197           5 :         ::std::vector< double > fDotDashArray;
    1198           5 :         const double fDashLen(rInfo.GetDashLen());
    1199           5 :         const double fDotLen(rInfo.GetDotLen());
    1200           5 :         const double fDistance(rInfo.GetDistance());
    1201             : 
    1202           5 :         for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++)
    1203             :         {
    1204           0 :             fDotDashArray.push_back(fDashLen);
    1205           0 :             fDotDashArray.push_back(fDistance);
    1206             :         }
    1207             : 
    1208          10 :         for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
    1209             :         {
    1210           5 :             fDotDashArray.push_back(fDotLen);
    1211           5 :             fDotDashArray.push_back(fDistance);
    1212             :         }
    1213             : 
    1214           5 :         const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
    1215             : 
    1216           5 :         if(fAccumulated > 0.0)
    1217             :         {
    1218           5 :             basegfx::B2DPolyPolygon aResult;
    1219             : 
    1220          10 :             for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++)
    1221             :             {
    1222           5 :                 basegfx::B2DPolyPolygon aLineTraget;
    1223             :                 basegfx::tools::applyLineDashing(
    1224             :                     aLinePolyPolygon.getB2DPolygon(c),
    1225             :                     fDotDashArray,
    1226           5 :                     &aLineTraget);
    1227           5 :                 aResult.append(aLineTraget);
    1228           5 :             }
    1229             : 
    1230           5 :             aLinePolyPolygon = aResult;
    1231           5 :         }
    1232             :     }
    1233             : 
    1234          13 :     if(bLineWidthUsed && aLinePolyPolygon.count())
    1235             :     {
    1236           8 :         const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);
    1237             : 
    1238           8 :         if(aLinePolyPolygon.areControlPointsUsed())
    1239             :         {
    1240             :             // #i110768# When area geometry has to be created, do not
    1241             :             // use the fallback bezier decomposition inside createAreaGeometry,
    1242             :             // but one that is at least as good as ImplSubdivideBezier was.
    1243             :             // There, Polygon::AdaptiveSubdivide was used with default parameter
    1244             :             // 1.0 as quality index.
    1245           0 :             aLinePolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0);
    1246             :         }
    1247             : 
    1248          16 :         for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
    1249             :         {
    1250             :             aFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
    1251             :                 aLinePolyPolygon.getB2DPolygon(a),
    1252             :                 fHalfLineWidth,
    1253             :                 rInfo.GetLineJoin(),
    1254           8 :                 rInfo.GetLineCap()));
    1255             :         }
    1256             : 
    1257           8 :         aLinePolyPolygon.clear();
    1258             :     }
    1259             : 
    1260          13 :     GDIMetaFile* pOldMetaFile = mpMetaFile;
    1261          13 :     mpMetaFile = NULL;
    1262             : 
    1263          13 :     if(aLinePolyPolygon.count())
    1264             :     {
    1265         710 :         for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
    1266             :         {
    1267         705 :             const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
    1268         705 :             bool bDone(false);
    1269             : 
    1270         705 :             if(bTryAA)
    1271             :             {
    1272           0 :                 bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, css::drawing::LineCap_BUTT, this);
    1273             :             }
    1274             : 
    1275         705 :             if(!bDone)
    1276             :             {
    1277         705 :                 const Polygon aPolygon(aCandidate);
    1278         705 :                 mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
    1279             :             }
    1280         705 :         }
    1281             :     }
    1282             : 
    1283          13 :     if(aFillPolyPolygon.count())
    1284             :     {
    1285           8 :         const Color     aOldLineColor( maLineColor );
    1286           8 :         const Color     aOldFillColor( maFillColor );
    1287             : 
    1288           8 :         SetLineColor();
    1289           8 :         ImplInitLineColor();
    1290           8 :         SetFillColor( aOldLineColor );
    1291           8 :         ImplInitFillColor();
    1292             : 
    1293           8 :         bool bDone(false);
    1294             : 
    1295           8 :         if(bTryAA)
    1296             :         {
    1297           0 :             bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this);
    1298             :         }
    1299             : 
    1300           8 :         if(!bDone)
    1301             :         {
    1302         148 :             for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
    1303             :             {
    1304         140 :                 Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
    1305             : 
    1306             :                 // need to subdivide, mpGraphics->DrawPolygon ignores curves
    1307         140 :                 aPolygon.AdaptiveSubdivide(aPolygon);
    1308         140 :                 mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
    1309         140 :             }
    1310             :         }
    1311             : 
    1312           8 :         SetFillColor( aOldFillColor );
    1313           8 :         SetLineColor( aOldLineColor );
    1314             :     }
    1315             : 
    1316          13 :     mpMetaFile = pOldMetaFile;
    1317          13 : }
    1318             : 
    1319          94 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
    1320             :                              const LineInfo& rLineInfo )
    1321             : {
    1322             : 
    1323          94 :     if ( rLineInfo.IsDefault() )
    1324             :     {
    1325           0 :         DrawLine( rStartPt, rEndPt );
    1326          94 :         return;
    1327             :     }
    1328             : 
    1329          94 :     if ( mpMetaFile )
    1330          94 :         mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );
    1331             : 
    1332          94 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
    1333          94 :         return;
    1334             : 
    1335           0 :     if( !mpGraphics && !ImplGetGraphics() )
    1336           0 :         return;
    1337             : 
    1338           0 :     if ( mbInitClipRegion )
    1339           0 :         ImplInitClipRegion();
    1340             : 
    1341           0 :     if ( mbOutputClipped )
    1342           0 :         return;
    1343             : 
    1344           0 :     const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
    1345           0 :     const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
    1346           0 :     const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
    1347           0 :     const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
    1348           0 :     const bool bLineWidthUsed(aInfo.GetWidth() > 1);
    1349             : 
    1350           0 :     if ( mbInitLineColor )
    1351           0 :         ImplInitLineColor();
    1352             : 
    1353           0 :     if(bDashUsed || bLineWidthUsed)
    1354             :     {
    1355           0 :         basegfx::B2DPolygon aLinePolygon;
    1356           0 :         aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y()));
    1357           0 :         aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y()));
    1358             : 
    1359           0 :         ImplPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon));
    1360             :     }
    1361             :     else
    1362             :     {
    1363           0 :         mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
    1364             :     }
    1365             : 
    1366           0 :     if( mpAlphaVDev )
    1367           0 :         mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo );
    1368             : }
    1369             : 
    1370      530057 : void OutputDevice::DrawRect( const Rectangle& rRect )
    1371             : {
    1372             : 
    1373      530057 :     if ( mpMetaFile )
    1374       10204 :         mpMetaFile->AddAction( new MetaRectAction( rRect ) );
    1375             : 
    1376      530057 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
    1377       31821 :         return;
    1378             : 
    1379      524223 :     Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
    1380             : 
    1381      524223 :     if ( aRect.IsEmpty() )
    1382        8553 :         return;
    1383      515670 :     aRect.Justify();
    1384             : 
    1385      515670 :     if ( !mpGraphics )
    1386             :     {
    1387      109541 :         if ( !ImplGetGraphics() )
    1388           0 :             return;
    1389             :     }
    1390             : 
    1391      515670 :     if ( mbInitClipRegion )
    1392      186248 :         ImplInitClipRegion();
    1393      515670 :     if ( mbOutputClipped )
    1394       11600 :         return;
    1395             : 
    1396      504070 :     if ( mbInitLineColor )
    1397      282398 :         ImplInitLineColor();
    1398      504070 :     if ( mbInitFillColor )
    1399      291737 :         ImplInitFillColor();
    1400             : 
    1401      504070 :     mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
    1402             : 
    1403      504070 :     if( mpAlphaVDev )
    1404       10978 :         mpAlphaVDev->DrawRect( rRect );
    1405             : }
    1406             : 
    1407       20601 : void OutputDevice::DrawPolyLine( const Polygon& rPoly )
    1408             : {
    1409             : 
    1410       20601 :     if( mpMetaFile )
    1411           0 :         mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );
    1412             : 
    1413       20601 :     sal_uInt16 nPoints = rPoly.GetSize();
    1414             : 
    1415       20601 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() )
    1416           0 :         return;
    1417             : 
    1418             :     // we need a graphics
    1419       20601 :     if ( !mpGraphics )
    1420           0 :         if ( !ImplGetGraphics() )
    1421           0 :             return;
    1422             : 
    1423       20601 :     if ( mbInitClipRegion )
    1424         672 :         ImplInitClipRegion();
    1425       20601 :     if ( mbOutputClipped )
    1426           0 :         return;
    1427             : 
    1428       20601 :     if ( mbInitLineColor )
    1429        4345 :         ImplInitLineColor();
    1430             : 
    1431       20601 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1432           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1433           0 :         && ROP_OVERPAINT == GetRasterOp()
    1434       20601 :         && IsLineColor());
    1435             : 
    1436             :     // use b2dpolygon drawing if possible
    1437       20601 :     if(bTryAA && ImplTryDrawPolyLineDirect(rPoly.getB2DPolygon()))
    1438             :     {
    1439           0 :         basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon());
    1440           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    1441           0 :         const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1442             : 
    1443             :         // transform the polygon
    1444           0 :         aB2DPolyLine.transform( aTransform );
    1445             : 
    1446           0 :         if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1447             :         {
    1448           0 :             aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
    1449             :         }
    1450             : 
    1451           0 :         if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, css::drawing::LineCap_BUTT, this))
    1452             :         {
    1453           0 :             return;
    1454           0 :         }
    1455             :     }
    1456             : 
    1457       20601 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1458       20601 :     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1459             : 
    1460             :     // #100127# Forward beziers to sal, if any
    1461       20601 :     if( aPoly.HasFlags() )
    1462             :     {
    1463           0 :         const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
    1464           0 :         if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, this ) )
    1465             :         {
    1466           0 :             aPoly = ImplSubdivideBezier(aPoly);
    1467           0 :             pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1468           0 :             mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, this );
    1469             :         }
    1470             :     }
    1471             :     else
    1472             :     {
    1473       20601 :         mpGraphics->DrawPolyLine( nPoints, pPtAry, this );
    1474             :     }
    1475             : 
    1476       20601 :     if( mpAlphaVDev )
    1477        3940 :         mpAlphaVDev->DrawPolyLine( rPoly );
    1478             : }
    1479             : 
    1480         105 : void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo )
    1481             : {
    1482             : 
    1483         105 :     if ( rLineInfo.IsDefault() )
    1484             :     {
    1485           0 :         DrawPolyLine( rPoly );
    1486           0 :         return;
    1487             :     }
    1488             : 
    1489             :     // #i101491#
    1490             :     // Try direct Fallback to B2D-Version of DrawPolyLine
    1491         210 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1492         105 :         && LINE_SOLID == rLineInfo.GetStyle())
    1493             :     {
    1494           0 :         DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap());
    1495           0 :         return;
    1496             :     }
    1497             : 
    1498         105 :     if ( mpMetaFile )
    1499          49 :         mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
    1500             : 
    1501         105 :     ImplDrawPolyLineWithLineInfo(rPoly, rLineInfo);
    1502             : }
    1503             : 
    1504      136830 : void OutputDevice::ImplDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
    1505             : {
    1506      136830 :     sal_uInt16 nPoints(rPoly.GetSize());
    1507             : 
    1508      136830 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
    1509         406 :         return;
    1510             : 
    1511      136627 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1512             : 
    1513             :     // #100127# LineInfo is not curve-safe, subdivide always
    1514             : 
    1515             :     // What shall this mean? It's wrong to subdivide here when the
    1516             :     // polygon is a fat line. In that case, the painted geometry
    1517             :     // WILL be much different.
    1518             :     // I also have no idea how this could be related to the given ID
    1519             :     // which reads 'consolidate boost versions' in the task description.
    1520             :     // Removing.
    1521             : 
    1522             :     //if( aPoly.HasFlags() )
    1523             :     //{
    1524             :     //    aPoly = ImplSubdivideBezier( aPoly );
    1525             :     //    nPoints = aPoly.GetSize();
    1526             :     //}
    1527             : 
    1528             :     // we need a graphics
    1529      136627 :     if ( !mpGraphics && !ImplGetGraphics() )
    1530           0 :         return;
    1531             : 
    1532      136627 :     if ( mbInitClipRegion )
    1533           9 :         ImplInitClipRegion();
    1534             : 
    1535      136627 :     if ( mbOutputClipped )
    1536           0 :         return;
    1537             : 
    1538      136627 :     if ( mbInitLineColor )
    1539          37 :         ImplInitLineColor();
    1540             : 
    1541      273254 :     const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
    1542      136627 :     const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
    1543      136627 :     const bool bLineWidthUsed(aInfo.GetWidth() > 1);
    1544             : 
    1545      136627 :     if(bDashUsed || bLineWidthUsed)
    1546             :     {
    1547          13 :         ImplPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon()));
    1548             :     }
    1549             :     else
    1550             :     {
    1551             :         // #100127# the subdivision HAS to be done here since only a pointer
    1552             :         // to an array of points is given to the DrawPolyLine method, there is
    1553             :         // NO way to find out there that it's a curve.
    1554      136614 :         if( aPoly.HasFlags() )
    1555             :         {
    1556        1961 :             aPoly = ImplSubdivideBezier( aPoly );
    1557        1961 :             nPoints = aPoly.GetSize();
    1558             :         }
    1559             : 
    1560      136614 :         mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this);
    1561             :     }
    1562             : 
    1563      136627 :     if( mpAlphaVDev )
    1564      136627 :         mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
    1565             : }
    1566             : 
    1567      194733 : void OutputDevice::DrawPolygon( const Polygon& rPoly )
    1568             : {
    1569             : 
    1570      194733 :     if( mpMetaFile )
    1571           6 :         mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
    1572             : 
    1573      194733 :     sal_uInt16 nPoints = rPoly.GetSize();
    1574             : 
    1575      194733 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
    1576           0 :         return;
    1577             : 
    1578             :     // we need a graphics
    1579      194733 :     if ( !mpGraphics )
    1580           0 :         if ( !ImplGetGraphics() )
    1581           0 :             return;
    1582             : 
    1583      194733 :     if ( mbInitClipRegion )
    1584         314 :         ImplInitClipRegion();
    1585      194733 :     if ( mbOutputClipped )
    1586           0 :         return;
    1587             : 
    1588      194733 :     if ( mbInitLineColor )
    1589        2265 :         ImplInitLineColor();
    1590      194733 :     if ( mbInitFillColor )
    1591        2674 :         ImplInitFillColor();
    1592             : 
    1593             :     // use b2dpolygon drawing if possible
    1594      389466 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1595          18 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1596           0 :         && ROP_OVERPAINT == GetRasterOp()
    1597      194733 :         && (IsLineColor() || IsFillColor()))
    1598             :     {
    1599           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    1600           0 :         basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
    1601           0 :         bool bSuccess(true);
    1602             : 
    1603             :         // transform the polygon and ensure closed
    1604           0 :         aB2DPolygon.transform(aTransform);
    1605           0 :         aB2DPolygon.setClosed(true);
    1606             : 
    1607           0 :         if(IsFillColor())
    1608             :         {
    1609           0 :             bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
    1610             :         }
    1611             : 
    1612           0 :         if(bSuccess && IsLineColor())
    1613             :         {
    1614           0 :             const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1615             : 
    1616           0 :             if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1617             :             {
    1618           0 :                 aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
    1619             :             }
    1620             : 
    1621             :             bSuccess = mpGraphics->DrawPolyLine(
    1622             :                 aB2DPolygon,
    1623             :                 0.0,
    1624             :                 aB2DLineWidth,
    1625             :                 basegfx::B2DLINEJOIN_NONE,
    1626             :                 css::drawing::LineCap_BUTT,
    1627           0 :                 this);
    1628             :         }
    1629             : 
    1630           0 :         if(bSuccess)
    1631             :         {
    1632           0 :             return;
    1633           0 :         }
    1634             :     }
    1635             : 
    1636      194733 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1637      194733 :     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1638             : 
    1639             :     // #100127# Forward beziers to sal, if any
    1640      194733 :     if( aPoly.HasFlags() )
    1641             :     {
    1642        3438 :         const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
    1643        3438 :         if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
    1644             :         {
    1645        3438 :             aPoly = ImplSubdivideBezier(aPoly);
    1646        3438 :             pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1647        3438 :             mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
    1648             :         }
    1649             :     }
    1650             :     else
    1651             :     {
    1652      191295 :         mpGraphics->DrawPolygon( nPoints, pPtAry, this );
    1653             :     }
    1654      194733 :     if( mpAlphaVDev )
    1655        6842 :         mpAlphaVDev->DrawPolygon( rPoly );
    1656             : }
    1657             : 
    1658      186848 : void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
    1659             : {
    1660             : 
    1661      186848 :     if( mpMetaFile )
    1662           2 :         mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
    1663             : 
    1664      186848 :     sal_uInt16 nPoly = rPolyPoly.Count();
    1665             : 
    1666      186848 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
    1667           2 :         return;
    1668             : 
    1669             :     // we need a graphics
    1670      186846 :     if ( !mpGraphics )
    1671           0 :         if ( !ImplGetGraphics() )
    1672           0 :             return;
    1673             : 
    1674      186846 :     if ( mbInitClipRegion )
    1675         360 :         ImplInitClipRegion();
    1676      186846 :     if ( mbOutputClipped )
    1677           0 :         return;
    1678             : 
    1679      186846 :     if ( mbInitLineColor )
    1680       12724 :         ImplInitLineColor();
    1681      186846 :     if ( mbInitFillColor )
    1682       14080 :         ImplInitFillColor();
    1683             : 
    1684             :     // use b2dpolygon drawing if possible
    1685      373692 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1686          18 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1687           0 :         && ROP_OVERPAINT == GetRasterOp()
    1688      186846 :         && (IsLineColor() || IsFillColor()))
    1689             :     {
    1690           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    1691           0 :         basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
    1692           0 :         bool bSuccess(true);
    1693             : 
    1694             :         // transform the polygon and ensure closed
    1695           0 :         aB2DPolyPolygon.transform(aTransform);
    1696           0 :         aB2DPolyPolygon.setClosed(true);
    1697             : 
    1698           0 :         if(IsFillColor())
    1699             :         {
    1700           0 :             bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
    1701             :         }
    1702             : 
    1703           0 :         if(bSuccess && IsLineColor())
    1704             :         {
    1705           0 :             const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1706             : 
    1707           0 :             if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1708             :             {
    1709           0 :                 aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
    1710             :             }
    1711             : 
    1712           0 :             for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
    1713             :             {
    1714             :                 bSuccess = mpGraphics->DrawPolyLine(
    1715             :                     aB2DPolyPolygon.getB2DPolygon(a),
    1716             :                     0.0,
    1717             :                     aB2DLineWidth,
    1718             :                     basegfx::B2DLINEJOIN_NONE,
    1719             :                     css::drawing::LineCap_BUTT,
    1720           0 :                     this);
    1721           0 :             }
    1722             :         }
    1723             : 
    1724           0 :         if(bSuccess)
    1725             :         {
    1726           0 :             return;
    1727           0 :         }
    1728             :     }
    1729             : 
    1730      186846 :     if ( nPoly == 1 )
    1731             :     {
    1732             :         // #100127# Map to DrawPolygon
    1733      184847 :         Polygon aPoly = rPolyPoly.GetObject( 0 );
    1734      184847 :         if( aPoly.GetSize() >= 2 )
    1735             :         {
    1736      184847 :             GDIMetaFile* pOldMF = mpMetaFile;
    1737      184847 :             mpMetaFile = NULL;
    1738             : 
    1739      184847 :             DrawPolygon( aPoly );
    1740             : 
    1741      184847 :             mpMetaFile = pOldMF;
    1742      184847 :         }
    1743             :     }
    1744             :     else
    1745             :     {
    1746             :         // #100127# moved real PolyPolygon draw to separate method,
    1747             :         // have to call recursively, avoiding duplicate
    1748             :         // ImplLogicToDevicePixel calls
    1749        1999 :         ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
    1750             :     }
    1751      186846 :     if( mpAlphaVDev )
    1752        6842 :         mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
    1753             : }
    1754             : 
    1755        1031 : void OutputDevice::DrawPolygon( const basegfx::B2DPolygon& rB2DPolygon)
    1756             : {
    1757             :     // AW: Do NOT paint empty polygons
    1758        1031 :     if(rB2DPolygon.count())
    1759             :     {
    1760        1031 :         basegfx::B2DPolyPolygon aPP( rB2DPolygon );
    1761        1031 :         DrawPolyPolygon( aPP );
    1762             :     }
    1763        1031 : }
    1764             : 
    1765             : // Caution: This method is nearly the same as
    1766             : // OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
    1767             : // so when changes are made here do not forget to make change sthere, too
    1768             : 
    1769       49783 : void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
    1770             : {
    1771             : 
    1772       49783 :     if( mpMetaFile )
    1773        1207 :         mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
    1774             : 
    1775             :     // call helper
    1776       49783 :     ImplDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
    1777       49783 : }
    1778             : 
    1779       49783 : void OutputDevice::ImplDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
    1780             : {
    1781             :     // Do not paint empty PolyPolygons
    1782       49783 :     if(!rB2DPolyPoly.count() || !IsDeviceOutputNecessary())
    1783        2414 :         return;
    1784             : 
    1785             :     // we need a graphics
    1786       48576 :     if( !mpGraphics )
    1787           0 :         if( !ImplGetGraphics() )
    1788           0 :             return;
    1789             : 
    1790       48576 :     if( mbInitClipRegion )
    1791          61 :         ImplInitClipRegion();
    1792       48576 :     if( mbOutputClipped )
    1793           0 :         return;
    1794             : 
    1795       48576 :     if( mbInitLineColor )
    1796        2637 :         ImplInitLineColor();
    1797       48576 :     if( mbInitFillColor )
    1798       45375 :         ImplInitFillColor();
    1799             : 
    1800       97152 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1801           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1802           0 :         && ROP_OVERPAINT == GetRasterOp()
    1803       48576 :         && (IsLineColor() || IsFillColor()))
    1804             :     {
    1805           0 :         const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
    1806           0 :         basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
    1807           0 :         bool bSuccess(true);
    1808             : 
    1809             :         // transform the polygon and ensure closed
    1810           0 :         aB2DPolyPolygon.transform(aTransform);
    1811           0 :         aB2DPolyPolygon.setClosed(true);
    1812             : 
    1813           0 :         if(IsFillColor())
    1814             :         {
    1815           0 :             bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
    1816             :         }
    1817             : 
    1818           0 :         if(bSuccess && IsLineColor())
    1819             :         {
    1820           0 :             const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
    1821             : 
    1822           0 :             if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1823             :             {
    1824           0 :                 aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
    1825             :             }
    1826             : 
    1827           0 :             for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
    1828             :             {
    1829             :                 bSuccess = mpGraphics->DrawPolyLine(
    1830             :                     aB2DPolyPolygon.getB2DPolygon(a),
    1831             :                     0.0,
    1832             :                     aB2DLineWidth,
    1833             :                     basegfx::B2DLINEJOIN_NONE,
    1834             :                     css::drawing::LineCap_BUTT,
    1835           0 :                     this);
    1836           0 :             }
    1837             :         }
    1838             : 
    1839           0 :         if(bSuccess)
    1840             :         {
    1841           0 :             return;
    1842           0 :         }
    1843             :     }
    1844             : 
    1845             :     // fallback to old polygon drawing if needed
    1846       48576 :     const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
    1847       97152 :     const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
    1848       97152 :     ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon );
    1849             : }
    1850             : 
    1851           0 : bool OutputDevice::ImplTryDrawPolyLineDirect(
    1852             :     const basegfx::B2DPolygon& rB2DPolygon,
    1853             :     double fLineWidth,
    1854             :     double fTransparency,
    1855             :     basegfx::B2DLineJoin eLineJoin,
    1856             :     css::drawing::LineCap eLineCap)
    1857             : {
    1858           0 :     const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    1859           0 :     basegfx::B2DVector aB2DLineWidth(1.0, 1.0);
    1860             : 
    1861             :     // transform the line width if used
    1862           0 :     if( fLineWidth != 0.0 )
    1863             :     {
    1864           0 :         aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
    1865             :     }
    1866             : 
    1867             :     // transform the polygon
    1868           0 :     basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
    1869           0 :     aB2DPolygon.transform(aTransform);
    1870             : 
    1871           0 :     if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
    1872           0 :         && aB2DPolygon.count() < 1000)
    1873             :     {
    1874             :         // #i98289#, #i101491#
    1875             :         // better to remove doubles on device coordinates. Also assume from a given amount
    1876             :         // of points that the single edges are not long enough to smooth
    1877           0 :         aB2DPolygon.removeDoublePoints();
    1878           0 :         aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
    1879             :     }
    1880             : 
    1881             :     // draw the polyline
    1882             :     return mpGraphics->DrawPolyLine(
    1883             :         aB2DPolygon,
    1884             :         fTransparency,
    1885             :         aB2DLineWidth,
    1886             :         eLineJoin,
    1887             :         eLineCap,
    1888           0 :         this);
    1889             : }
    1890             : 
    1891      130814 : bool OutputDevice::TryDrawPolyLineDirect(
    1892             :     const basegfx::B2DPolygon& rB2DPolygon,
    1893             :     double fLineWidth,
    1894             :     double fTransparency,
    1895             :     basegfx::B2DLineJoin eLineJoin,
    1896             :     css::drawing::LineCap eLineCap)
    1897             : {
    1898             :     // AW: Do NOT paint empty PolyPolygons
    1899      130814 :     if(!rB2DPolygon.count())
    1900           0 :         return true;
    1901             : 
    1902             :     // we need a graphics
    1903      130814 :     if( !mpGraphics )
    1904           0 :         if( !ImplGetGraphics() )
    1905           0 :             return false;
    1906             : 
    1907      130814 :     if( mbInitClipRegion )
    1908        6895 :         ImplInitClipRegion();
    1909             : 
    1910      130814 :     if( mbOutputClipped )
    1911           0 :         return true;
    1912             : 
    1913      130814 :     if( mbInitLineColor )
    1914       13986 :         ImplInitLineColor();
    1915             : 
    1916      130814 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1917           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1918           0 :         && ROP_OVERPAINT == GetRasterOp()
    1919      130814 :         && IsLineColor());
    1920             : 
    1921      130814 :     if(bTryAA)
    1922             :     {
    1923           0 :         if(ImplTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, fTransparency, eLineJoin, eLineCap))
    1924             :         {
    1925             :             // worked, add metafile action (if recorded) and return true
    1926           0 :             if( mpMetaFile )
    1927             :             {
    1928           0 :                 LineInfo aLineInfo;
    1929           0 :                 if( fLineWidth != 0.0 )
    1930           0 :                     aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    1931           0 :                 const Polygon aToolsPolygon( rB2DPolygon );
    1932           0 :                 mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
    1933             :             }
    1934             : 
    1935           0 :             return true;
    1936             :         }
    1937             :     }
    1938             : 
    1939      130814 :     return false;
    1940             : }
    1941             : 
    1942      137892 : void OutputDevice::DrawPolyLine(
    1943             :     const basegfx::B2DPolygon& rB2DPolygon,
    1944             :     double fLineWidth,
    1945             :     basegfx::B2DLineJoin eLineJoin,
    1946             :     css::drawing::LineCap eLineCap)
    1947             : {
    1948             : 
    1949      137892 :     if( mpMetaFile )
    1950             :     {
    1951        1167 :         LineInfo aLineInfo;
    1952        1167 :         if( fLineWidth != 0.0 )
    1953          36 :             aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    1954        2334 :         const Polygon aToolsPolygon( rB2DPolygon );
    1955        2334 :         mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
    1956             :     }
    1957             : 
    1958             :     // Do not paint empty PolyPolygons
    1959      137892 :     if(!rB2DPolygon.count() || !IsDeviceOutputNecessary())
    1960        1167 :         return;
    1961             : 
    1962             :     // we need a graphics
    1963      136725 :     if( !mpGraphics )
    1964           0 :         if( !ImplGetGraphics() )
    1965           0 :             return;
    1966             : 
    1967      136725 :     if( mbInitClipRegion )
    1968          53 :         ImplInitClipRegion();
    1969      136725 :     if( mbOutputClipped )
    1970           0 :         return;
    1971             : 
    1972      136725 :     if( mbInitLineColor )
    1973         583 :         ImplInitLineColor();
    1974             : 
    1975      136725 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1976           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1977           0 :         && ROP_OVERPAINT == GetRasterOp()
    1978      136725 :         && IsLineColor());
    1979             : 
    1980             :     // use b2dpolygon drawing if possible
    1981      136725 :     if(bTryAA && ImplTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap))
    1982             :     {
    1983           0 :         return;
    1984             :     }
    1985             : 
    1986             :     // #i101491#
    1987             :     // no output yet; fallback to geometry decomposition and use filled polygon paint
    1988             :     // when line is fat and not too complex. ImplDrawPolyPolygonWithB2DPolyPolygon
    1989             :     // will do internal needed AA checks etc.
    1990      136725 :     if(fLineWidth >= 2.5
    1991           0 :         && rB2DPolygon.count()
    1992      136725 :         && rB2DPolygon.count() <= 1000)
    1993             :     {
    1994           0 :         const double fHalfLineWidth((fLineWidth * 0.5) + 0.5);
    1995             :         const basegfx::B2DPolyPolygon aAreaPolyPolygon(
    1996             :             basegfx::tools::createAreaGeometry(
    1997             :                 rB2DPolygon,
    1998             :                 fHalfLineWidth,
    1999             :                 eLineJoin,
    2000           0 :                 eLineCap));
    2001           0 :         const Color aOldLineColor(maLineColor);
    2002           0 :         const Color aOldFillColor(maFillColor);
    2003             : 
    2004           0 :         SetLineColor();
    2005           0 :         ImplInitLineColor();
    2006           0 :         SetFillColor(aOldLineColor);
    2007           0 :         ImplInitFillColor();
    2008             : 
    2009             :         // draw usig a loop; else the topology will paint a PolyPolygon
    2010           0 :         for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
    2011             :         {
    2012             :             ImplDrawPolyPolygonWithB2DPolyPolygon(
    2013           0 :                 basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a)));
    2014             :         }
    2015             : 
    2016           0 :         SetLineColor(aOldLineColor);
    2017           0 :         ImplInitLineColor();
    2018           0 :         SetFillColor(aOldFillColor);
    2019           0 :         ImplInitFillColor();
    2020             : 
    2021           0 :         if(bTryAA)
    2022             :         {
    2023             :             // when AA it is necessary to also paint the filled polygon's outline
    2024             :             // to avoid optical gaps
    2025           0 :             for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
    2026             :             {
    2027           0 :                 ImplTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a));
    2028             :             }
    2029           0 :         }
    2030             :     }
    2031             :     else
    2032             :     {
    2033             :         // fallback to old polygon drawing if needed
    2034      136725 :         const Polygon aToolsPolygon( rB2DPolygon );
    2035      273450 :         LineInfo aLineInfo;
    2036      136725 :         if( fLineWidth != 0.0 )
    2037           0 :             aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    2038      273450 :         ImplDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
    2039             :     }
    2040             : }
    2041             : 
    2042           0 : sal_uInt32 OutputDevice::GetGCStackDepth() const
    2043             : {
    2044           0 :     const ImplObjStack* pData = mpObjStack;
    2045           0 :     sal_uInt32 nDepth = 0;
    2046           0 :     while( pData )
    2047             :     {
    2048           0 :         nDepth++;
    2049           0 :         pData = pData->mpPrev;
    2050             :     }
    2051           0 :     return nDepth;
    2052             : }
    2053             : 
    2054      704781 : void OutputDevice::Push( sal_uInt16 nFlags )
    2055             : {
    2056             : 
    2057      704781 :     if ( mpMetaFile )
    2058       54313 :         mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
    2059             : 
    2060      704781 :     ImplObjStack* pData = new ImplObjStack;
    2061      704781 :     pData->mpPrev = mpObjStack;
    2062      704781 :     mpObjStack = pData;
    2063             : 
    2064      704781 :     pData->mnFlags = nFlags;
    2065             : 
    2066      704781 :     if ( nFlags & PUSH_LINECOLOR )
    2067             :     {
    2068      146297 :         if ( mbLineColor )
    2069      112823 :             pData->mpLineColor = new Color( maLineColor );
    2070             :         else
    2071       33474 :             pData->mpLineColor = NULL;
    2072             :     }
    2073      704781 :     if ( nFlags & PUSH_FILLCOLOR )
    2074             :     {
    2075      122600 :         if ( mbFillColor )
    2076      118534 :             pData->mpFillColor = new Color( maFillColor );
    2077             :         else
    2078        4066 :             pData->mpFillColor = NULL;
    2079             :     }
    2080      704781 :     if ( nFlags & PUSH_FONT )
    2081      110789 :         pData->mpFont = new Font( maFont );
    2082      704781 :     if ( nFlags & PUSH_TEXTCOLOR )
    2083      101048 :         pData->mpTextColor = new Color( GetTextColor() );
    2084      704781 :     if ( nFlags & PUSH_TEXTFILLCOLOR )
    2085             :     {
    2086       49175 :         if ( IsTextFillColor() )
    2087         682 :             pData->mpTextFillColor = new Color( GetTextFillColor() );
    2088             :         else
    2089       48493 :             pData->mpTextFillColor = NULL;
    2090             :     }
    2091      704781 :     if ( nFlags & PUSH_TEXTLINECOLOR )
    2092             :     {
    2093       49175 :         if ( IsTextLineColor() )
    2094         682 :             pData->mpTextLineColor = new Color( GetTextLineColor() );
    2095             :         else
    2096       48493 :             pData->mpTextLineColor = NULL;
    2097             :     }
    2098      704781 :     if ( nFlags & PUSH_OVERLINECOLOR )
    2099             :     {
    2100       49175 :         if ( IsOverlineColor() )
    2101         688 :             pData->mpOverlineColor = new Color( GetOverlineColor() );
    2102             :         else
    2103       48487 :             pData->mpOverlineColor = NULL;
    2104             :     }
    2105      704781 :     if ( nFlags & PUSH_TEXTALIGN )
    2106       49175 :         pData->meTextAlign = GetTextAlign();
    2107      704781 :     if( nFlags & PUSH_TEXTLAYOUTMODE )
    2108      292456 :         pData->mnTextLayoutMode = GetLayoutMode();
    2109      704781 :     if( nFlags & PUSH_TEXTLANGUAGE )
    2110      291706 :         pData->meTextLanguage = GetDigitLanguage();
    2111      704781 :     if ( nFlags & PUSH_RASTEROP )
    2112       49179 :         pData->meRasterOp = GetRasterOp();
    2113      704781 :     if ( nFlags & PUSH_MAPMODE )
    2114             :     {
    2115      139450 :         pData->mpMapMode = new MapMode( maMapMode );
    2116      139450 :         pData->mbMapActive = mbMap;
    2117             :     }
    2118      704781 :     if ( nFlags & PUSH_CLIPREGION )
    2119             :     {
    2120      322912 :         if ( mbClipRegion )
    2121      152297 :             pData->mpClipRegion = new Region( maRegion );
    2122             :         else
    2123      170615 :             pData->mpClipRegion = NULL;
    2124             :     }
    2125      704781 :     if ( nFlags & PUSH_REFPOINT )
    2126             :     {
    2127       49175 :         if ( mbRefPoint )
    2128           0 :             pData->mpRefPoint = new Point( maRefPoint );
    2129             :         else
    2130       49175 :             pData->mpRefPoint = NULL;
    2131             :     }
    2132             : 
    2133      704781 :     if( mpAlphaVDev )
    2134       17121 :         mpAlphaVDev->Push();
    2135      704781 : }
    2136             : 
    2137      704781 : void OutputDevice::Pop()
    2138             : {
    2139             : 
    2140      704781 :     if( mpMetaFile )
    2141       54313 :         mpMetaFile->AddAction( new MetaPopAction() );
    2142             : 
    2143      704781 :     GDIMetaFile*    pOldMetaFile = mpMetaFile;
    2144      704781 :     ImplObjStack*   pData = mpObjStack;
    2145      704781 :     mpMetaFile = NULL;
    2146             : 
    2147      704781 :     if ( !pData )
    2148             :     {
    2149             :         SAL_WARN( "vcl.gdi", "OutputDevice::Pop() without OutputDevice::Push()" );
    2150      704781 :         return;
    2151             :     }
    2152             : 
    2153      704781 :     if( mpAlphaVDev )
    2154       17121 :         mpAlphaVDev->Pop();
    2155             : 
    2156      704781 :     mpObjStack = pData->mpPrev;
    2157             : 
    2158      704781 :     if ( pData->mnFlags & PUSH_LINECOLOR )
    2159             :     {
    2160      146297 :         if ( pData->mpLineColor )
    2161      112823 :             SetLineColor( *pData->mpLineColor );
    2162             :         else
    2163       33474 :             SetLineColor();
    2164             :     }
    2165      704781 :     if ( pData->mnFlags & PUSH_FILLCOLOR )
    2166             :     {
    2167      122600 :         if ( pData->mpFillColor )
    2168      118534 :             SetFillColor( *pData->mpFillColor );
    2169             :         else
    2170        4066 :             SetFillColor();
    2171             :     }
    2172      704781 :     if ( pData->mnFlags & PUSH_FONT )
    2173      110789 :         SetFont( *pData->mpFont );
    2174      704781 :     if ( pData->mnFlags & PUSH_TEXTCOLOR )
    2175      101048 :         SetTextColor( *pData->mpTextColor );
    2176      704781 :     if ( pData->mnFlags & PUSH_TEXTFILLCOLOR )
    2177             :     {
    2178       49175 :         if ( pData->mpTextFillColor )
    2179         682 :             SetTextFillColor( *pData->mpTextFillColor );
    2180             :         else
    2181       48493 :             SetTextFillColor();
    2182             :     }
    2183      704781 :     if ( pData->mnFlags & PUSH_TEXTLINECOLOR )
    2184             :     {
    2185       49175 :         if ( pData->mpTextLineColor )
    2186         682 :             SetTextLineColor( *pData->mpTextLineColor );
    2187             :         else
    2188       48493 :             SetTextLineColor();
    2189             :     }
    2190      704781 :     if ( pData->mnFlags & PUSH_OVERLINECOLOR )
    2191             :     {
    2192       49175 :         if ( pData->mpOverlineColor )
    2193         688 :             SetOverlineColor( *pData->mpOverlineColor );
    2194             :         else
    2195       48487 :             SetOverlineColor();
    2196             :     }
    2197      704781 :     if ( pData->mnFlags & PUSH_TEXTALIGN )
    2198       49175 :         SetTextAlign( pData->meTextAlign );
    2199      704781 :     if( pData->mnFlags & PUSH_TEXTLAYOUTMODE )
    2200      292456 :         SetLayoutMode( pData->mnTextLayoutMode );
    2201      704781 :     if( pData->mnFlags & PUSH_TEXTLANGUAGE )
    2202      291706 :         SetDigitLanguage( pData->meTextLanguage );
    2203      704781 :     if ( pData->mnFlags & PUSH_RASTEROP )
    2204       49179 :         SetRasterOp( pData->meRasterOp );
    2205      704781 :     if ( pData->mnFlags & PUSH_MAPMODE )
    2206             :     {
    2207      139450 :         if ( pData->mpMapMode )
    2208      139450 :             SetMapMode( *pData->mpMapMode );
    2209             :         else
    2210           0 :             SetMapMode();
    2211      139450 :         mbMap = pData->mbMapActive;
    2212             :     }
    2213      704781 :     if ( pData->mnFlags & PUSH_CLIPREGION )
    2214      322912 :         ImplSetClipRegion( pData->mpClipRegion );
    2215      704781 :     if ( pData->mnFlags & PUSH_REFPOINT )
    2216             :     {
    2217       49175 :         if ( pData->mpRefPoint )
    2218           0 :             SetRefPoint( *pData->mpRefPoint );
    2219             :         else
    2220       49175 :             SetRefPoint();
    2221             :     }
    2222             : 
    2223      704781 :     ImplDeleteObjStack( pData );
    2224             : 
    2225      704781 :     mpMetaFile = pOldMetaFile;
    2226             : }
    2227             : 
    2228       36020 : void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
    2229             : {
    2230       36020 :     mpMetaFile = pMtf;
    2231       36020 : }
    2232             : 
    2233       30872 : void OutputDevice::EnableOutput( bool bEnable )
    2234             : {
    2235       30872 :     mbOutput = bEnable;
    2236             : 
    2237       30872 :     if( mpAlphaVDev )
    2238           0 :         mpAlphaVDev->EnableOutput( bEnable );
    2239       30872 : }
    2240             : 
    2241      166231 : void OutputDevice::SetSettings( const AllSettings& rSettings )
    2242             : {
    2243      166231 :     *mxSettings = rSettings;
    2244             : 
    2245      166231 :     if( mpAlphaVDev )
    2246           0 :         mpAlphaVDev->SetSettings( rSettings );
    2247      166231 : }
    2248             : 
    2249      173852 : sal_uInt16 OutputDevice::GetBitCount() const
    2250             : {
    2251             :     // we need a graphics instance
    2252      173852 :     if ( !mpGraphics )
    2253             :     {
    2254           0 :         if ( !((OutputDevice*)this)->ImplGetGraphics() )
    2255           0 :             return 0;
    2256             :     }
    2257             : 
    2258      173852 :     return (sal_uInt16)mpGraphics->GetBitCount();
    2259             : }
    2260             : 
    2261           0 : sal_uInt16 OutputDevice::GetAlphaBitCount() const
    2262             : {
    2263           0 :     return 0;
    2264             : }
    2265             : 
    2266         232 : sal_uLong OutputDevice::GetColorCount() const
    2267             : {
    2268             : 
    2269         232 :     const sal_uInt16 nBitCount = GetBitCount();
    2270         232 :     return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) );
    2271             : }
    2272             : 
    2273           0 : bool OutputDevice::HasAlpha()
    2274             : {
    2275           0 :     return mpAlphaVDev != NULL;
    2276             : }
    2277             : 
    2278       12524 : css::uno::Reference< css::awt::XGraphics > OutputDevice::CreateUnoGraphics()
    2279             : {
    2280       12524 :     UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
    2281       12524 :     return pWrapper ? pWrapper->CreateGraphics( this ) : css::uno::Reference< css::awt::XGraphics >();
    2282             : }
    2283             : 
    2284          22 : SystemGraphicsData OutputDevice::GetSystemGfxData() const
    2285             : {
    2286          22 :     if ( !mpGraphics )
    2287             :     {
    2288           1 :         if ( !ImplGetGraphics() )
    2289           0 :             return SystemGraphicsData();
    2290             :     }
    2291             : 
    2292          22 :     return mpGraphics->GetGraphicsData();
    2293             : }
    2294             : 
    2295          21 : css::uno::Any OutputDevice::GetSystemGfxDataAny() const
    2296             : {
    2297          21 :     const SystemGraphicsData aSysData = GetSystemGfxData();
    2298             :     css::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)&aSysData,
    2299          21 :                                                       aSysData.nSize );
    2300             : 
    2301          21 :     return css::uno::makeAny(aSeq);
    2302             : }
    2303             : 
    2304           0 : css::uno::Reference< css::rendering::XCanvas > OutputDevice::GetCanvas() const
    2305             : {
    2306           0 :     css::uno::Sequence< css::uno::Any > aArg(6);
    2307             : 
    2308           0 :     aArg[ 0 ] = css::uno::makeAny( reinterpret_cast<sal_Int64>(this) );
    2309           0 :     aArg[ 2 ] = css::uno::makeAny( css::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
    2310           0 :     aArg[ 3 ] = css::uno::makeAny( sal_False );
    2311           0 :     aArg[ 5 ] = GetSystemGfxDataAny();
    2312             : 
    2313           0 :     css::uno::Reference<css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
    2314             : 
    2315             :     // Create canvas instance with window handle
    2316           0 :     static css::uno::Reference<css::lang::XMultiComponentFactory > xCanvasFactory( css::rendering::CanvasFactory::create( xContext ) );
    2317             : 
    2318           0 :     css::uno::Reference<css::rendering::XCanvas> xCanvas;
    2319             :     xCanvas.set(
    2320           0 :         xCanvasFactory->createInstanceWithArgumentsAndContext(
    2321           0 :             "com.sun.star.rendering.Canvas", aArg, xContext ),
    2322           0 :         css::uno::UNO_QUERY );
    2323             : 
    2324           0 :     return xCanvas;
    2325         516 : }
    2326             : 
    2327             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10