LCOV - code coverage report
Current view: top level - vcl/source/gdi - outdev.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 1 1180 0.1 %
Date: 2014-04-14 Functions: 2 75 2.7 %
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           0 : static void ImplDeleteObjStack( ImplObjStack* pObjStack )
     117             : {
     118           0 :     if ( pObjStack->mnFlags & PUSH_LINECOLOR )
     119             :     {
     120           0 :         if ( pObjStack->mpLineColor )
     121           0 :             delete pObjStack->mpLineColor;
     122             :     }
     123           0 :     if ( pObjStack->mnFlags & PUSH_FILLCOLOR )
     124             :     {
     125           0 :         if ( pObjStack->mpFillColor )
     126           0 :             delete pObjStack->mpFillColor;
     127             :     }
     128           0 :     if ( pObjStack->mnFlags & PUSH_FONT )
     129           0 :         delete pObjStack->mpFont;
     130           0 :     if ( pObjStack->mnFlags & PUSH_TEXTCOLOR )
     131           0 :         delete pObjStack->mpTextColor;
     132           0 :     if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR )
     133             :     {
     134           0 :         if ( pObjStack->mpTextFillColor )
     135           0 :             delete pObjStack->mpTextFillColor;
     136             :     }
     137           0 :     if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR )
     138             :     {
     139           0 :         if ( pObjStack->mpTextLineColor )
     140           0 :             delete pObjStack->mpTextLineColor;
     141             :     }
     142           0 :     if ( pObjStack->mnFlags & PUSH_OVERLINECOLOR )
     143             :     {
     144           0 :         if ( pObjStack->mpOverlineColor )
     145           0 :             delete pObjStack->mpOverlineColor;
     146             :     }
     147           0 :     if ( pObjStack->mnFlags & PUSH_MAPMODE )
     148             :     {
     149           0 :         if ( pObjStack->mpMapMode )
     150           0 :             delete pObjStack->mpMapMode;
     151             :     }
     152           0 :     if ( pObjStack->mnFlags & PUSH_CLIPREGION )
     153             :     {
     154           0 :         if ( pObjStack->mpClipRegion )
     155           0 :             delete pObjStack->mpClipRegion;
     156             :     }
     157           0 :     if ( pObjStack->mnFlags & PUSH_REFPOINT )
     158             :     {
     159           0 :         if ( pObjStack->mpRefPoint )
     160           0 :             delete pObjStack->mpRefPoint;
     161             :     }
     162             : 
     163           0 :     delete pObjStack;
     164           0 : }
     165             : 
     166           0 : bool OutputDevice::ImplIsAntiparallel() const
     167             : {
     168           0 :     bool bRet = false;
     169           0 :     if( ImplGetGraphics() )
     170             :     {
     171           0 :         if( ( (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && ! IsRTLEnabled() ) ||
     172           0 :             ( ! (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && IsRTLEnabled() ) )
     173             :         {
     174           0 :             bRet = true;
     175             :         }
     176             :     }
     177           0 :     return bRet;
     178             : }
     179             : 
     180           0 : bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGraphics )
     181             : {
     182             :     DBG_TESTSOLARMUTEX();
     183             : 
     184           0 :     if( !pGraphics )
     185             :     {
     186           0 :         if( !mpGraphics )
     187           0 :             if( !ImplInitGraphics() )
     188           0 :                 return false;
     189           0 :         pGraphics = mpGraphics;
     190             :     }
     191             : 
     192           0 :     bool bClipRegion = pGraphics->SetClipRegion( rRegion, this );
     193             :     OSL_ENSURE( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" );
     194           0 :     return bClipRegion;
     195             : }
     196             : 
     197           0 : Polygon ImplSubdivideBezier( const Polygon& rPoly )
     198             : {
     199           0 :     Polygon aPoly;
     200             : 
     201             :     // #100127# Use adaptive subdivide instead of fixed 25 segments
     202           0 :     rPoly.AdaptiveSubdivide( aPoly );
     203             : 
     204           0 :     return aPoly;
     205             : }
     206             : 
     207           0 : PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
     208             : {
     209           0 :     sal_uInt16 i, nPolys = rPolyPoly.Count();
     210           0 :     PolyPolygon aPolyPoly( nPolys );
     211           0 :     for( i=0; i<nPolys; ++i )
     212           0 :         aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );
     213             : 
     214           0 :     return aPolyPoly;
     215             : }
     216             : 
     217             : // #100127# Extracted from OutputDevice::DrawPolyPolygon()
     218           0 : void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
     219             : {
     220             :     // AW: This crashes on empty PolyPolygons, avoid that
     221           0 :     if(!nPoly)
     222           0 :         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           0 :     sal_uInt16              i = 0, j = 0, last = 0;
     231           0 :     bool                bHaveBezier = false;
     232           0 :     if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
     233             :     {
     234           0 :         pPointAry       = new sal_uInt32[nPoly];
     235           0 :         pPointAryAry    = new PCONSTSALPOINT[nPoly];
     236           0 :         pFlagAryAry     = new const sal_uInt8*[nPoly];
     237             :     }
     238             :     else
     239             :     {
     240           0 :         pPointAry       = aStackAry1;
     241           0 :         pPointAryAry    = aStackAry2;
     242           0 :         pFlagAryAry     = (const sal_uInt8**)aStackAry3;
     243             :     }
     244           0 :     do
     245             :     {
     246           0 :         const Polygon&  rPoly = rPolyPoly.GetObject( i );
     247           0 :         sal_uInt16          nSize = rPoly.GetSize();
     248           0 :         if ( nSize )
     249             :         {
     250           0 :             pPointAry[j]    = nSize;
     251           0 :             pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
     252           0 :             pFlagAryAry[j]  = rPoly.GetConstFlagAry();
     253           0 :             last            = i;
     254             : 
     255           0 :             if( pFlagAryAry[j] )
     256           0 :                 bHaveBezier = true;
     257             : 
     258           0 :             ++j;
     259             :         }
     260             : 
     261           0 :         ++i;
     262             :     }
     263             :     while ( i < nPoly );
     264             : 
     265           0 :     if ( j == 1 )
     266             :     {
     267             :         // #100127# Forward beziers to sal, if any
     268           0 :         if( bHaveBezier )
     269             :         {
     270           0 :             if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
     271             :             {
     272           0 :                 Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
     273           0 :                 mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
     274             :             }
     275             :         }
     276             :         else
     277             :         {
     278           0 :             mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
     279             :         }
     280             :     }
     281             :     else
     282             :     {
     283             :         // #100127# Forward beziers to sal, if any
     284           0 :         if( bHaveBezier )
     285             :         {
     286           0 :             if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
     287             :             {
     288           0 :                 PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
     289           0 :                 ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
     290             :             }
     291             :         }
     292             :         else
     293             :         {
     294           0 :             mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
     295             :         }
     296             :     }
     297             : 
     298           0 :     if ( pPointAry != aStackAry1 )
     299             :     {
     300           0 :         delete[] pPointAry;
     301           0 :         delete[] pPointAryAry;
     302           0 :         delete[] pFlagAryAry;
     303             :     }
     304             : }
     305             : 
     306           0 : OutputDevice::OutputDevice() :
     307             :     maRegion(true),
     308             :     maFillColor( COL_WHITE ),
     309             :     maTextLineColor( COL_TRANSPARENT ),
     310           0 :     mxSettings( new AllSettings(Application::GetSettings()) )
     311             : {
     312             : 
     313           0 :     mpGraphics          = NULL;
     314           0 :     mpUnoGraphicsList   = NULL;
     315           0 :     mpPrevGraphics      = NULL;
     316           0 :     mpNextGraphics      = NULL;
     317           0 :     mpMetaFile          = NULL;
     318           0 :     mpFontEntry         = NULL;
     319           0 :     mpFontCache         = NULL;
     320           0 :     mpFontCollection   = NULL;
     321           0 :     mpGetDevFontList    = NULL;
     322           0 :     mpGetDevSizeList    = NULL;
     323           0 :     mpObjStack          = NULL;
     324           0 :     mpOutDevData        = NULL;
     325           0 :     mpPDFWriter         = NULL;
     326           0 :     mpAlphaVDev         = NULL;
     327           0 :     mpExtOutDevData     = NULL;
     328           0 :     mnOutOffX           = 0;
     329           0 :     mnOutOffY           = 0;
     330           0 :     mnOutWidth          = 0;
     331           0 :     mnOutHeight         = 0;
     332           0 :     mnDPIX              = 0;
     333           0 :     mnDPIY              = 0;
     334           0 :     mnDPIScaleFactor    = 1;
     335           0 :     mnTextOffX          = 0;
     336           0 :     mnTextOffY          = 0;
     337           0 :     mnOutOffOrigX       = 0;
     338           0 :     mnOutOffLogicX      = 0;
     339           0 :     mnOutOffOrigY       = 0;
     340           0 :     mnOutOffLogicY      = 0;
     341           0 :     mnEmphasisAscent    = 0;
     342           0 :     mnEmphasisDescent   = 0;
     343           0 :     mnDrawMode          = 0;
     344           0 :     mnTextLayoutMode        = TEXT_LAYOUT_DEFAULT;
     345           0 :     if( Application::GetSettings().GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
     346           0 :         mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
     347           0 :     meOutDevType        = OUTDEV_DONTKNOW;
     348           0 :     meOutDevViewType    = OUTDEV_VIEWTYPE_DONTKNOW;
     349           0 :     mbMap               = false;
     350           0 :     mbMapIsDefault      = true;
     351           0 :     mbClipRegion        = false;
     352           0 :     mbBackground        = false;
     353           0 :     mbOutput            = true;
     354           0 :     mbDevOutput         = false;
     355           0 :     mbOutputClipped     = false;
     356           0 :     maTextColor         = Color( COL_BLACK );
     357           0 :     maOverlineColor     = Color( COL_TRANSPARENT );
     358           0 :     meTextAlign         = maFont.GetAlign();
     359           0 :     meRasterOp          = ROP_OVERPAINT;
     360           0 :     mnAntialiasing      = 0;
     361           0 :     meTextLanguage      = 0;  // TODO: get default from configuration?
     362           0 :     mbLineColor         = true;
     363           0 :     mbFillColor         = true;
     364           0 :     mbInitLineColor     = true;
     365           0 :     mbInitFillColor     = true;
     366           0 :     mbInitFont          = true;
     367           0 :     mbInitTextColor     = true;
     368           0 :     mbInitClipRegion    = true;
     369           0 :     mbClipRegionSet     = false;
     370           0 :     mbKerning           = false;
     371           0 :     mbNewFont           = true;
     372           0 :     mbTextLines         = false;
     373           0 :     mbTextSpecial       = false;
     374           0 :     mbRefPoint          = false;
     375           0 :     mbEnableRTL         = false;    // mirroring must be explicitly allowed (typically for windows only)
     376             : 
     377             :     // struct ImplMapRes
     378           0 :     maMapRes.mnMapOfsX          = 0;
     379           0 :     maMapRes.mnMapOfsY          = 0;
     380           0 :     maMapRes.mnMapScNumX        = 1;
     381           0 :     maMapRes.mnMapScNumY        = 1;
     382           0 :     maMapRes.mnMapScDenomX      = 1;
     383           0 :     maMapRes.mnMapScDenomY      = 1;
     384             :     // struct ImplThresholdRes
     385           0 :     maThresRes.mnThresLogToPixX = 0;
     386           0 :     maThresRes.mnThresLogToPixY = 0;
     387           0 :     maThresRes.mnThresPixToLogX = 0;
     388           0 :     maThresRes.mnThresPixToLogY = 0;
     389           0 : }
     390             : 
     391           0 : OutputDevice::~OutputDevice()
     392             : {
     393             : 
     394           0 :     if ( GetUnoGraphicsList() )
     395             :     {
     396           0 :         UnoWrapperBase* pWrapper = Application::GetUnoWrapper( false );
     397           0 :         if ( pWrapper )
     398           0 :             pWrapper->ReleaseAllGraphics( this );
     399           0 :         delete mpUnoGraphicsList;
     400           0 :         mpUnoGraphicsList = NULL;
     401             :     }
     402             : 
     403           0 :     if ( mpOutDevData )
     404           0 :         ImplDeInitOutDevData();
     405             : 
     406           0 :     ImplObjStack* pData = mpObjStack;
     407           0 :     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           0 :     if( mpFontEntry )
     420           0 :         mpFontCache->Release( mpFontEntry );
     421             :     // remove cached results of GetDevFontList/GetDevSizeList
     422             :     // TODO: use smart pointers for them
     423           0 :     if( mpGetDevFontList )
     424           0 :         delete mpGetDevFontList;
     425           0 :     if( mpGetDevSizeList )
     426           0 :         delete mpGetDevSizeList;
     427             : 
     428             :     // release ImplFontCache specific to this OutputDevice
     429             :     // TODO: refcount ImplFontCache
     430           0 :     if( mpFontCache
     431           0 :     && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
     432           0 :     && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
     433             :     {
     434           0 :         delete mpFontCache;
     435           0 :         mpFontCache = NULL;
     436             :     }
     437             : 
     438             :     // release ImplFontList specific to this OutputDevice
     439             :     // TODO: refcount ImplFontList
     440           0 :     if( mpFontCollection
     441           0 :     && (mpFontCollection != ImplGetSVData()->maGDIData.mpScreenFontList)
     442           0 :     && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
     443             :     {
     444           0 :         mpFontCollection->Clear();
     445           0 :         delete mpFontCollection;
     446           0 :         mpFontCollection = NULL;
     447             :     }
     448             : 
     449           0 :     delete mpAlphaVDev;
     450           0 : }
     451             : 
     452           0 : bool OutputDevice::supportsOperation( OutDevSupportType eType ) const
     453             : {
     454           0 :     if( !mpGraphics )
     455           0 :         if( !ImplGetGraphics() )
     456           0 :             return false;
     457           0 :     const bool bHasSupport = mpGraphics->supportsOperation( eType );
     458           0 :     return bHasSupport;
     459             : }
     460             : 
     461           0 : void OutputDevice::EnableRTL( bool bEnable )
     462             : {
     463           0 :     mbEnableRTL = bEnable;
     464             : 
     465           0 :     if( mpAlphaVDev )
     466           0 :         mpAlphaVDev->EnableRTL( bEnable );
     467           0 : }
     468             : 
     469           0 : bool OutputDevice::HasMirroredGraphics() const
     470             : {
     471           0 :    return ( ImplGetGraphics() && (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) );
     472             : }
     473             : 
     474             : // note: the coordiantes to be remirrored are in frame coordiantes !
     475             : 
     476           0 : void    OutputDevice::ReMirror( Point &rPoint ) const
     477             : {
     478           0 :     rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
     479           0 : }
     480           0 : void    OutputDevice::ReMirror( Rectangle &rRect ) const
     481             : {
     482           0 :     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           0 :     rRect.Left() = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.Left() + mnOutOffX;
     489           0 :     rRect.Right() = rRect.Left() + nWidth;
     490           0 : }
     491           0 : void    OutputDevice::ReMirror( Region &rRegion ) const
     492             : {
     493           0 :     RectangleVector aRectangles;
     494           0 :     rRegion.GetRegionRectangles(aRectangles);
     495           0 :     Region aMirroredRegion;
     496             : 
     497           0 :     for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     498             :     {
     499           0 :         ReMirror(*aRectIter);
     500           0 :         aMirroredRegion.Union(*aRectIter);
     501             :     }
     502             : 
     503           0 :     rRegion = aMirroredRegion;
     504             : 
     505           0 : }
     506             : 
     507           0 : SalGraphics* OutputDevice::ImplGetGraphics()
     508             : {
     509             :     DBG_TESTSOLARMUTEX();
     510             : 
     511           0 :     if ( !mpGraphics )
     512             :     {
     513           0 :         if ( !ImplInitGraphics() )
     514             :         {
     515             :             SAL_WARN("vcl", "No mpGraphics set");
     516             :         }
     517             :     }
     518             : 
     519           0 :     return mpGraphics;
     520             : }
     521             : 
     522           0 : SalGraphics const *OutputDevice::ImplGetGraphics() const
     523             : {
     524             :     DBG_TESTSOLARMUTEX();
     525             : 
     526           0 :     if ( !mpGraphics )
     527             :     {
     528           0 :         if ( !ImplInitGraphics() )
     529             :         {
     530             :             SAL_WARN("vcl", "No mpGraphics set");
     531             :         }
     532             :     }
     533             : 
     534           0 :     return mpGraphics;
     535             : }
     536             : 
     537           0 : void OutputDevice::ImplInitOutDevData()
     538             : {
     539           0 :     if ( !mpOutDevData )
     540             :     {
     541           0 :         mpOutDevData = new ImplOutDevData;
     542           0 :         mpOutDevData->mpRotateDev = NULL;
     543           0 :         mpOutDevData->mpRecordLayout = NULL;
     544             : 
     545             :         // #i75163#
     546           0 :         mpOutDevData->mpViewTransform = NULL;
     547           0 :         mpOutDevData->mpInverseViewTransform = NULL;
     548             :     }
     549           0 : }
     550             : 
     551           0 : void OutputDevice::ImplReleaseFonts()
     552             : {
     553           0 :     mpGraphics->ReleaseFonts();
     554           0 :     mbNewFont = true;
     555           0 :     mbInitFont = true;
     556             : 
     557           0 :     if ( mpFontEntry )
     558             :     {
     559           0 :         mpFontCache->Release( mpFontEntry );
     560           0 :         mpFontEntry = NULL;
     561             :     }
     562             : 
     563           0 :     if ( mpGetDevFontList )
     564             :     {
     565           0 :         delete mpGetDevFontList;
     566           0 :         mpGetDevFontList = NULL;
     567             :     }
     568             : 
     569           0 :     if ( mpGetDevSizeList )
     570             :     {
     571           0 :         delete mpGetDevSizeList;
     572           0 :         mpGetDevSizeList = NULL;
     573             :     }
     574           0 : }
     575             : 
     576             : // #i75163#
     577           0 : void OutputDevice::ImplInvalidateViewTransform()
     578             : {
     579           0 :     if(mpOutDevData)
     580             :     {
     581           0 :         if(mpOutDevData->mpViewTransform)
     582             :         {
     583           0 :             delete mpOutDevData->mpViewTransform;
     584           0 :             mpOutDevData->mpViewTransform = NULL;
     585             :         }
     586             : 
     587           0 :         if(mpOutDevData->mpInverseViewTransform)
     588             :         {
     589           0 :             delete mpOutDevData->mpInverseViewTransform;
     590           0 :             mpOutDevData->mpInverseViewTransform = NULL;
     591             :         }
     592             :     }
     593           0 : }
     594             : 
     595           0 : bool OutputDevice::ImplIsRecordLayout() const
     596             : {
     597           0 :     return mpOutDevData && mpOutDevData->mpRecordLayout;
     598             : }
     599             : 
     600           0 : void OutputDevice::ImplDeInitOutDevData()
     601             : {
     602           0 :     if ( mpOutDevData )
     603             :     {
     604           0 :         if ( mpOutDevData->mpRotateDev )
     605           0 :             delete mpOutDevData->mpRotateDev;
     606             : 
     607             :         // #i75163#
     608           0 :         ImplInvalidateViewTransform();
     609             : 
     610           0 :         delete mpOutDevData;
     611             :     }
     612           0 : }
     613             : 
     614           0 : void OutputDevice::ImplInitLineColor()
     615             : {
     616             :     DBG_TESTSOLARMUTEX();
     617             : 
     618           0 :     if( mbLineColor )
     619             :     {
     620           0 :         if( ROP_0 == meRasterOp )
     621           0 :             mpGraphics->SetROPLineColor( SAL_ROP_0 );
     622           0 :         else if( ROP_1 == meRasterOp )
     623           0 :             mpGraphics->SetROPLineColor( SAL_ROP_1 );
     624           0 :         else if( ROP_INVERT == meRasterOp )
     625           0 :             mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
     626             :         else
     627           0 :             mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
     628             :     }
     629             :     else
     630           0 :         mpGraphics->SetLineColor();
     631             : 
     632           0 :     mbInitLineColor = false;
     633           0 : }
     634             : 
     635           0 : void OutputDevice::ImplInitFillColor()
     636             : {
     637             :     DBG_TESTSOLARMUTEX();
     638             : 
     639           0 :     if( mbFillColor )
     640             :     {
     641           0 :         if( ROP_0 == meRasterOp )
     642           0 :             mpGraphics->SetROPFillColor( SAL_ROP_0 );
     643           0 :         else if( ROP_1 == meRasterOp )
     644           0 :             mpGraphics->SetROPFillColor( SAL_ROP_1 );
     645           0 :         else if( ROP_INVERT == meRasterOp )
     646           0 :             mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
     647             :         else
     648           0 :             mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
     649             :     }
     650             :     else
     651           0 :         mpGraphics->SetFillColor();
     652             : 
     653           0 :     mbInitFillColor = false;
     654           0 : }
     655             : 
     656             : // TODO: fdo#74424 - this needs to be moved out of OutputDevice and into the
     657             : // Window, VirtualDevice and Printer classes
     658           0 : void OutputDevice::ImplInitClipRegion()
     659             : {
     660             :     DBG_TESTSOLARMUTEX();
     661             : 
     662           0 :     if ( GetOutDevType() == OUTDEV_WINDOW )
     663             :     {
     664           0 :         Window* pWindow = (Window*)this;
     665           0 :         Region  aRegion;
     666             : 
     667             :         // Put back backed up background
     668           0 :         if ( pWindow->mpWindowImpl->mpFrameData->mpFirstBackWin )
     669           0 :             pWindow->ImplInvalidateAllOverlapBackgrounds();
     670           0 :         if ( pWindow->mpWindowImpl->mbInPaint )
     671           0 :             aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
     672             :         else
     673             :         {
     674           0 :             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           0 :             if( ImplIsAntiparallel() )
     678           0 :                 ReMirror ( aRegion );
     679             :         }
     680           0 :         if ( mbClipRegion )
     681           0 :             aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
     682           0 :         if ( aRegion.IsEmpty() )
     683           0 :             mbOutputClipped = true;
     684             :         else
     685             :         {
     686           0 :             mbOutputClipped = false;
     687           0 :             ImplSelectClipRegion( aRegion );
     688             :         }
     689           0 :         mbClipRegionSet = true;
     690             :     }
     691             :     else
     692             :     {
     693           0 :         if ( mbClipRegion )
     694             :         {
     695           0 :             if ( maRegion.IsEmpty() )
     696           0 :                 mbOutputClipped = true;
     697             :             else
     698             :             {
     699           0 :                 mbOutputClipped = false;
     700             : 
     701             :                 // #102532# Respect output offset also for clip region
     702           0 :                 Region aRegion( ImplPixelToDevicePixel( maRegion ) );
     703           0 :                 const bool bClipDeviceBounds( ! GetPDFWriter()
     704           0 :                                               && GetOutDevType() != OUTDEV_PRINTER );
     705           0 :                 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           0 :                                              mnOutOffX+GetOutputWidthPixel()-1,
     712           0 :                                              mnOutOffY+GetOutputHeightPixel()-1 );
     713           0 :                     aRegion.Intersect( aDeviceBounds );
     714             :                 }
     715             : 
     716           0 :                 if ( aRegion.IsEmpty() )
     717             :                 {
     718           0 :                     mbOutputClipped = true;
     719             :                 }
     720             :                 else
     721             :                 {
     722           0 :                     mbOutputClipped = false;
     723           0 :                     ImplSelectClipRegion( aRegion );
     724           0 :                 }
     725             :             }
     726             : 
     727           0 :             mbClipRegionSet = true;
     728             :         }
     729             :         else
     730             :         {
     731           0 :             if ( mbClipRegionSet )
     732             :             {
     733           0 :                 mpGraphics->ResetClipRegion();
     734           0 :                 mbClipRegionSet = false;
     735             :             }
     736             : 
     737           0 :             mbOutputClipped = false;
     738             :         }
     739             :     }
     740             : 
     741           0 :     mbInitClipRegion = false;
     742           0 : }
     743             : 
     744           0 : void OutputDevice::ImplSetClipRegion( const Region* pRegion )
     745             : {
     746             :     DBG_TESTSOLARMUTEX();
     747             : 
     748           0 :     if ( !pRegion )
     749             :     {
     750           0 :         if ( mbClipRegion )
     751             :         {
     752           0 :             maRegion            = Region(true);
     753           0 :             mbClipRegion        = false;
     754           0 :             mbInitClipRegion    = true;
     755             :         }
     756             :     }
     757             :     else
     758             :     {
     759           0 :         maRegion            = *pRegion;
     760           0 :         mbClipRegion        = true;
     761           0 :         mbInitClipRegion    = true;
     762             :     }
     763           0 : }
     764             : 
     765           0 : void OutputDevice::SetClipRegion()
     766             : {
     767             : 
     768           0 :     if ( mpMetaFile )
     769           0 :         mpMetaFile->AddAction( new MetaClipRegionAction( Region(), false ) );
     770             : 
     771           0 :     ImplSetClipRegion( NULL );
     772             : 
     773           0 :     if( mpAlphaVDev )
     774           0 :         mpAlphaVDev->SetClipRegion();
     775           0 : }
     776             : 
     777           0 : void OutputDevice::SetClipRegion( const Region& rRegion )
     778             : {
     779             : 
     780           0 :     if ( mpMetaFile )
     781           0 :         mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, true ) );
     782             : 
     783           0 :     if ( rRegion.IsNull() )
     784             :     {
     785           0 :         ImplSetClipRegion( NULL );
     786             :     }
     787             :     else
     788             :     {
     789           0 :         Region aRegion = LogicToPixel( rRegion );
     790           0 :         ImplSetClipRegion( &aRegion );
     791             :     }
     792             : 
     793           0 :     if( mpAlphaVDev )
     794           0 :         mpAlphaVDev->SetClipRegion( rRegion );
     795           0 : }
     796             : 
     797           0 : Region OutputDevice::GetClipRegion() const
     798             : {
     799             : 
     800           0 :     return PixelToLogic( maRegion );
     801             : }
     802             : 
     803           0 : Region OutputDevice::GetActiveClipRegion() const
     804             : {
     805             : 
     806           0 :     if ( GetOutDevType() == OUTDEV_WINDOW )
     807             :     {
     808           0 :         Region aRegion(true);
     809           0 :         Window* pWindow = (Window*)this;
     810           0 :         if ( pWindow->mpWindowImpl->mbInPaint )
     811             :         {
     812           0 :             aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
     813           0 :             aRegion.Move( -mnOutOffX, -mnOutOffY );
     814             :         }
     815           0 :         if ( mbClipRegion )
     816           0 :             aRegion.Intersect( maRegion );
     817           0 :         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           0 : void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
     841             : {
     842             : 
     843           0 :     if ( mpMetaFile )
     844           0 :         mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );
     845             : 
     846           0 :     Rectangle aRect = LogicToPixel( rRect );
     847           0 :     maRegion.Intersect( aRect );
     848           0 :     mbClipRegion        = true;
     849           0 :     mbInitClipRegion    = true;
     850             : 
     851           0 :     if( mpAlphaVDev )
     852           0 :         mpAlphaVDev->IntersectClipRegion( rRect );
     853           0 : }
     854             : 
     855           0 : void OutputDevice::IntersectClipRegion( const Region& rRegion )
     856             : {
     857             : 
     858           0 :     if(!rRegion.IsNull())
     859             :     {
     860           0 :         if ( mpMetaFile )
     861           0 :             mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );
     862             : 
     863           0 :         Region aRegion = LogicToPixel( rRegion );
     864           0 :         maRegion.Intersect( aRegion );
     865           0 :         mbClipRegion        = true;
     866           0 :         mbInitClipRegion    = true;
     867             :     }
     868             : 
     869           0 :     if( mpAlphaVDev )
     870           0 :         mpAlphaVDev->IntersectClipRegion( rRegion );
     871           0 : }
     872             : 
     873           0 : void OutputDevice::SetDrawMode( sal_uLong nDrawMode )
     874             : {
     875             : 
     876           0 :     mnDrawMode = nDrawMode;
     877             : 
     878           0 :     if( mpAlphaVDev )
     879           0 :         mpAlphaVDev->SetDrawMode( nDrawMode );
     880           0 : }
     881             : 
     882           0 : void OutputDevice::SetRasterOp( RasterOp eRasterOp )
     883             : {
     884             : 
     885           0 :     if ( mpMetaFile )
     886           0 :         mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
     887             : 
     888           0 :     if ( meRasterOp != eRasterOp )
     889             :     {
     890           0 :         meRasterOp = eRasterOp;
     891           0 :         mbInitLineColor = mbInitFillColor = true;
     892             : 
     893           0 :         if( mpGraphics || ImplGetGraphics() )
     894           0 :             mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
     895             :     }
     896             : 
     897           0 :     if( mpAlphaVDev )
     898           0 :         mpAlphaVDev->SetRasterOp( eRasterOp );
     899           0 : }
     900             : 
     901           0 : void OutputDevice::SetLineColor()
     902             : {
     903             : 
     904           0 :     if ( mpMetaFile )
     905           0 :         mpMetaFile->AddAction( new MetaLineColorAction( Color(), false ) );
     906             : 
     907           0 :     if ( mbLineColor )
     908             :     {
     909           0 :         mbInitLineColor = true;
     910           0 :         mbLineColor = false;
     911           0 :         maLineColor = Color( COL_TRANSPARENT );
     912             :     }
     913             : 
     914           0 :     if( mpAlphaVDev )
     915           0 :         mpAlphaVDev->SetLineColor();
     916           0 : }
     917             : 
     918           0 : Color OutputDevice::ImplDrawModeToColor( const Color& rColor ) const
     919             : {
     920           0 :     Color aColor( rColor );
     921           0 :     sal_uLong  nDrawMode = GetDrawMode();
     922             : 
     923           0 :     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           0 :     return aColor;
     956             : }
     957             : 
     958           0 : void OutputDevice::SetLineColor( const Color& rColor )
     959             : {
     960             : 
     961           0 :     Color aColor = ImplDrawModeToColor( rColor );
     962             : 
     963           0 :     if( mpMetaFile )
     964           0 :         mpMetaFile->AddAction( new MetaLineColorAction( aColor, true ) );
     965             : 
     966           0 :     if( ImplIsColorTransparent( aColor ) )
     967             :     {
     968           0 :         if ( mbLineColor )
     969             :         {
     970           0 :             mbInitLineColor = true;
     971           0 :             mbLineColor = false;
     972           0 :             maLineColor = Color( COL_TRANSPARENT );
     973             :         }
     974             :     }
     975             :     else
     976             :     {
     977           0 :         if( maLineColor != aColor )
     978             :         {
     979           0 :             mbInitLineColor = true;
     980           0 :             mbLineColor = true;
     981           0 :             maLineColor = aColor;
     982             :         }
     983             :     }
     984             : 
     985           0 :     if( mpAlphaVDev )
     986           0 :         mpAlphaVDev->SetLineColor( COL_BLACK );
     987           0 : }
     988             : 
     989           0 : void OutputDevice::SetFillColor()
     990             : {
     991             : 
     992           0 :     if ( mpMetaFile )
     993           0 :         mpMetaFile->AddAction( new MetaFillColorAction( Color(), false ) );
     994             : 
     995           0 :     if ( mbFillColor )
     996             :     {
     997           0 :         mbInitFillColor = true;
     998           0 :         mbFillColor = false;
     999           0 :         maFillColor = Color( COL_TRANSPARENT );
    1000             :     }
    1001             : 
    1002           0 :     if( mpAlphaVDev )
    1003           0 :         mpAlphaVDev->SetFillColor();
    1004           0 : }
    1005             : 
    1006           0 : void OutputDevice::SetFillColor( const Color& rColor )
    1007             : {
    1008             : 
    1009           0 :     Color aColor( rColor );
    1010             : 
    1011           0 :     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           0 :     if ( mpMetaFile )
    1049           0 :         mpMetaFile->AddAction( new MetaFillColorAction( aColor, true ) );
    1050             : 
    1051           0 :     if ( ImplIsColorTransparent( aColor ) )
    1052             :     {
    1053           0 :         if ( mbFillColor )
    1054             :         {
    1055           0 :             mbInitFillColor = true;
    1056           0 :             mbFillColor = false;
    1057           0 :             maFillColor = Color( COL_TRANSPARENT );
    1058             :         }
    1059             :     }
    1060             :     else
    1061             :     {
    1062           0 :         if ( maFillColor != aColor )
    1063             :         {
    1064           0 :             mbInitFillColor = true;
    1065           0 :             mbFillColor = true;
    1066           0 :             maFillColor = aColor;
    1067             :         }
    1068             :     }
    1069             : 
    1070           0 :     if( mpAlphaVDev )
    1071           0 :         mpAlphaVDev->SetFillColor( COL_BLACK );
    1072           0 : }
    1073             : 
    1074           0 : void OutputDevice::SetBackground()
    1075             : {
    1076             : 
    1077           0 :     maBackground = Wallpaper();
    1078           0 :     mbBackground = false;
    1079             : 
    1080           0 :     if( mpAlphaVDev )
    1081           0 :         mpAlphaVDev->SetBackground();
    1082           0 : }
    1083             : 
    1084           0 : void OutputDevice::SetBackground( const Wallpaper& rBackground )
    1085             : {
    1086             : 
    1087           0 :     maBackground = rBackground;
    1088             : 
    1089           0 :     if( rBackground.GetStyle() == WALLPAPER_NULL )
    1090           0 :         mbBackground = false;
    1091             :     else
    1092           0 :         mbBackground = true;
    1093             : 
    1094           0 :     if( mpAlphaVDev )
    1095           0 :         mpAlphaVDev->SetBackground( rBackground );
    1096           0 : }
    1097             : 
    1098           0 : void OutputDevice::SetRefPoint()
    1099             : {
    1100             : 
    1101           0 :     if ( mpMetaFile )
    1102           0 :         mpMetaFile->AddAction( new MetaRefPointAction( Point(), false ) );
    1103             : 
    1104           0 :     mbRefPoint = false;
    1105           0 :     maRefPoint.X() = maRefPoint.Y() = 0L;
    1106             : 
    1107           0 :     if( mpAlphaVDev )
    1108           0 :         mpAlphaVDev->SetRefPoint();
    1109           0 : }
    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           0 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
    1125             : {
    1126             : 
    1127           0 :     if ( mpMetaFile )
    1128           0 :         mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) );
    1129             : 
    1130           0 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
    1131           0 :         return;
    1132             : 
    1133           0 :     if ( !mpGraphics )
    1134             :     {
    1135           0 :         if ( !ImplGetGraphics() )
    1136           0 :             return;
    1137             :     }
    1138             : 
    1139           0 :     if ( mbInitClipRegion )
    1140           0 :         ImplInitClipRegion();
    1141           0 :     if ( mbOutputClipped )
    1142           0 :         return;
    1143             : 
    1144           0 :     if ( mbInitLineColor )
    1145           0 :         ImplInitLineColor();
    1146             : 
    1147             :     // #i101598# support AA and snap for lines, too
    1148           0 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1149           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1150           0 :         && ROP_OVERPAINT == GetRasterOp()
    1151           0 :         && 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           0 :     const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
    1175           0 :     const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
    1176             : 
    1177           0 :     mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
    1178             : 
    1179           0 :     if( mpAlphaVDev )
    1180           0 :         mpAlphaVDev->DrawLine( rStartPt, rEndPt );
    1181             : }
    1182             : 
    1183           0 : void OutputDevice::ImplPaintLineGeometryWithEvtlExpand(
    1184             :     const LineInfo& rInfo,
    1185             :     basegfx::B2DPolyPolygon aLinePolyPolygon)
    1186             : {
    1187           0 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1188           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1189           0 :         && ROP_OVERPAINT == GetRasterOp()
    1190           0 :         && IsLineColor());
    1191           0 :     basegfx::B2DPolyPolygon aFillPolyPolygon;
    1192           0 :     const bool bDashUsed(LINE_DASH == rInfo.GetStyle());
    1193           0 :     const bool bLineWidthUsed(rInfo.GetWidth() > 1);
    1194             : 
    1195           0 :     if(bDashUsed && aLinePolyPolygon.count())
    1196             :     {
    1197           0 :         ::std::vector< double > fDotDashArray;
    1198           0 :         const double fDashLen(rInfo.GetDashLen());
    1199           0 :         const double fDotLen(rInfo.GetDotLen());
    1200           0 :         const double fDistance(rInfo.GetDistance());
    1201             : 
    1202           0 :         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           0 :         for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
    1209             :         {
    1210           0 :             fDotDashArray.push_back(fDotLen);
    1211           0 :             fDotDashArray.push_back(fDistance);
    1212             :         }
    1213             : 
    1214           0 :         const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
    1215             : 
    1216           0 :         if(fAccumulated > 0.0)
    1217             :         {
    1218           0 :             basegfx::B2DPolyPolygon aResult;
    1219             : 
    1220           0 :             for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++)
    1221             :             {
    1222           0 :                 basegfx::B2DPolyPolygon aLineTraget;
    1223             :                 basegfx::tools::applyLineDashing(
    1224             :                     aLinePolyPolygon.getB2DPolygon(c),
    1225             :                     fDotDashArray,
    1226           0 :                     &aLineTraget);
    1227           0 :                 aResult.append(aLineTraget);
    1228           0 :             }
    1229             : 
    1230           0 :             aLinePolyPolygon = aResult;
    1231           0 :         }
    1232             :     }
    1233             : 
    1234           0 :     if(bLineWidthUsed && aLinePolyPolygon.count())
    1235             :     {
    1236           0 :         const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);
    1237             : 
    1238           0 :         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           0 :         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           0 :                 rInfo.GetLineCap()));
    1255             :         }
    1256             : 
    1257           0 :         aLinePolyPolygon.clear();
    1258             :     }
    1259             : 
    1260           0 :     GDIMetaFile* pOldMetaFile = mpMetaFile;
    1261           0 :     mpMetaFile = NULL;
    1262             : 
    1263           0 :     if(aLinePolyPolygon.count())
    1264             :     {
    1265           0 :         for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
    1266             :         {
    1267           0 :             const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
    1268           0 :             bool bDone(false);
    1269             : 
    1270           0 :             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           0 :             if(!bDone)
    1276             :             {
    1277           0 :                 const Polygon aPolygon(aCandidate);
    1278           0 :                 mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
    1279             :             }
    1280           0 :         }
    1281             :     }
    1282             : 
    1283           0 :     if(aFillPolyPolygon.count())
    1284             :     {
    1285           0 :         const Color     aOldLineColor( maLineColor );
    1286           0 :         const Color     aOldFillColor( maFillColor );
    1287             : 
    1288           0 :         SetLineColor();
    1289           0 :         ImplInitLineColor();
    1290           0 :         SetFillColor( aOldLineColor );
    1291           0 :         ImplInitFillColor();
    1292             : 
    1293           0 :         bool bDone(false);
    1294             : 
    1295           0 :         if(bTryAA)
    1296             :         {
    1297           0 :             bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this);
    1298             :         }
    1299             : 
    1300           0 :         if(!bDone)
    1301             :         {
    1302           0 :             for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
    1303             :             {
    1304           0 :                 Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
    1305             : 
    1306             :                 // need to subdivide, mpGraphics->DrawPolygon ignores curves
    1307           0 :                 aPolygon.AdaptiveSubdivide(aPolygon);
    1308           0 :                 mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
    1309           0 :             }
    1310             :         }
    1311             : 
    1312           0 :         SetFillColor( aOldFillColor );
    1313           0 :         SetLineColor( aOldLineColor );
    1314             :     }
    1315             : 
    1316           0 :     mpMetaFile = pOldMetaFile;
    1317           0 : }
    1318             : 
    1319           0 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
    1320             :                              const LineInfo& rLineInfo )
    1321             : {
    1322             : 
    1323           0 :     if ( rLineInfo.IsDefault() )
    1324             :     {
    1325           0 :         DrawLine( rStartPt, rEndPt );
    1326           0 :         return;
    1327             :     }
    1328             : 
    1329           0 :     if ( mpMetaFile )
    1330           0 :         mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );
    1331             : 
    1332           0 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
    1333           0 :         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           0 : void OutputDevice::DrawRect( const Rectangle& rRect )
    1371             : {
    1372             : 
    1373           0 :     if ( mpMetaFile )
    1374           0 :         mpMetaFile->AddAction( new MetaRectAction( rRect ) );
    1375             : 
    1376           0 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
    1377           0 :         return;
    1378             : 
    1379           0 :     Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
    1380             : 
    1381           0 :     if ( aRect.IsEmpty() )
    1382           0 :         return;
    1383           0 :     aRect.Justify();
    1384             : 
    1385           0 :     if ( !mpGraphics )
    1386             :     {
    1387           0 :         if ( !ImplGetGraphics() )
    1388           0 :             return;
    1389             :     }
    1390             : 
    1391           0 :     if ( mbInitClipRegion )
    1392           0 :         ImplInitClipRegion();
    1393           0 :     if ( mbOutputClipped )
    1394           0 :         return;
    1395             : 
    1396           0 :     if ( mbInitLineColor )
    1397           0 :         ImplInitLineColor();
    1398           0 :     if ( mbInitFillColor )
    1399           0 :         ImplInitFillColor();
    1400             : 
    1401           0 :     mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
    1402             : 
    1403           0 :     if( mpAlphaVDev )
    1404           0 :         mpAlphaVDev->DrawRect( rRect );
    1405             : }
    1406             : 
    1407           0 : void OutputDevice::DrawPolyLine( const Polygon& rPoly )
    1408             : {
    1409             : 
    1410           0 :     if( mpMetaFile )
    1411           0 :         mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );
    1412             : 
    1413           0 :     sal_uInt16 nPoints = rPoly.GetSize();
    1414             : 
    1415           0 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() )
    1416           0 :         return;
    1417             : 
    1418             :     // we need a graphics
    1419           0 :     if ( !mpGraphics )
    1420           0 :         if ( !ImplGetGraphics() )
    1421           0 :             return;
    1422             : 
    1423           0 :     if ( mbInitClipRegion )
    1424           0 :         ImplInitClipRegion();
    1425           0 :     if ( mbOutputClipped )
    1426           0 :         return;
    1427             : 
    1428           0 :     if ( mbInitLineColor )
    1429           0 :         ImplInitLineColor();
    1430             : 
    1431           0 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1432           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1433           0 :         && ROP_OVERPAINT == GetRasterOp()
    1434           0 :         && IsLineColor());
    1435             : 
    1436             :     // use b2dpolygon drawing if possible
    1437           0 :     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           0 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1458           0 :     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1459             : 
    1460             :     // #100127# Forward beziers to sal, if any
    1461           0 :     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           0 :         mpGraphics->DrawPolyLine( nPoints, pPtAry, this );
    1474             :     }
    1475             : 
    1476           0 :     if( mpAlphaVDev )
    1477           0 :         mpAlphaVDev->DrawPolyLine( rPoly );
    1478             : }
    1479             : 
    1480           0 : void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo )
    1481             : {
    1482             : 
    1483           0 :     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           0 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1492           0 :         && LINE_SOLID == rLineInfo.GetStyle())
    1493             :     {
    1494           0 :         DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap());
    1495           0 :         return;
    1496             :     }
    1497             : 
    1498           0 :     if ( mpMetaFile )
    1499           0 :         mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
    1500             : 
    1501           0 :     ImplDrawPolyLineWithLineInfo(rPoly, rLineInfo);
    1502             : }
    1503             : 
    1504           0 : void OutputDevice::ImplDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
    1505             : {
    1506           0 :     sal_uInt16 nPoints(rPoly.GetSize());
    1507             : 
    1508           0 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
    1509           0 :         return;
    1510             : 
    1511           0 :     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           0 :     if ( !mpGraphics && !ImplGetGraphics() )
    1530           0 :         return;
    1531             : 
    1532           0 :     if ( mbInitClipRegion )
    1533           0 :         ImplInitClipRegion();
    1534             : 
    1535           0 :     if ( mbOutputClipped )
    1536           0 :         return;
    1537             : 
    1538           0 :     if ( mbInitLineColor )
    1539           0 :         ImplInitLineColor();
    1540             : 
    1541           0 :     const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
    1542           0 :     const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
    1543           0 :     const bool bLineWidthUsed(aInfo.GetWidth() > 1);
    1544             : 
    1545           0 :     if(bDashUsed || bLineWidthUsed)
    1546             :     {
    1547           0 :         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           0 :         if( aPoly.HasFlags() )
    1555             :         {
    1556           0 :             aPoly = ImplSubdivideBezier( aPoly );
    1557           0 :             nPoints = aPoly.GetSize();
    1558             :         }
    1559             : 
    1560           0 :         mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this);
    1561             :     }
    1562             : 
    1563           0 :     if( mpAlphaVDev )
    1564           0 :         mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
    1565             : }
    1566             : 
    1567           0 : void OutputDevice::DrawPolygon( const Polygon& rPoly )
    1568             : {
    1569             : 
    1570           0 :     if( mpMetaFile )
    1571           0 :         mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
    1572             : 
    1573           0 :     sal_uInt16 nPoints = rPoly.GetSize();
    1574             : 
    1575           0 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
    1576           0 :         return;
    1577             : 
    1578             :     // we need a graphics
    1579           0 :     if ( !mpGraphics )
    1580           0 :         if ( !ImplGetGraphics() )
    1581           0 :             return;
    1582             : 
    1583           0 :     if ( mbInitClipRegion )
    1584           0 :         ImplInitClipRegion();
    1585           0 :     if ( mbOutputClipped )
    1586           0 :         return;
    1587             : 
    1588           0 :     if ( mbInitLineColor )
    1589           0 :         ImplInitLineColor();
    1590           0 :     if ( mbInitFillColor )
    1591           0 :         ImplInitFillColor();
    1592             : 
    1593             :     // use b2dpolygon drawing if possible
    1594           0 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1595           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1596           0 :         && ROP_OVERPAINT == GetRasterOp()
    1597           0 :         && (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           0 :     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    1637           0 :     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1638             : 
    1639             :     // #100127# Forward beziers to sal, if any
    1640           0 :     if( aPoly.HasFlags() )
    1641             :     {
    1642           0 :         const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
    1643           0 :         if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
    1644             :         {
    1645           0 :             aPoly = ImplSubdivideBezier(aPoly);
    1646           0 :             pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
    1647           0 :             mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
    1648             :         }
    1649             :     }
    1650             :     else
    1651             :     {
    1652           0 :         mpGraphics->DrawPolygon( nPoints, pPtAry, this );
    1653             :     }
    1654           0 :     if( mpAlphaVDev )
    1655           0 :         mpAlphaVDev->DrawPolygon( rPoly );
    1656             : }
    1657             : 
    1658           0 : void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
    1659             : {
    1660             : 
    1661           0 :     if( mpMetaFile )
    1662           0 :         mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
    1663             : 
    1664           0 :     sal_uInt16 nPoly = rPolyPoly.Count();
    1665             : 
    1666           0 :     if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
    1667           0 :         return;
    1668             : 
    1669             :     // we need a graphics
    1670           0 :     if ( !mpGraphics )
    1671           0 :         if ( !ImplGetGraphics() )
    1672           0 :             return;
    1673             : 
    1674           0 :     if ( mbInitClipRegion )
    1675           0 :         ImplInitClipRegion();
    1676           0 :     if ( mbOutputClipped )
    1677           0 :         return;
    1678             : 
    1679           0 :     if ( mbInitLineColor )
    1680           0 :         ImplInitLineColor();
    1681           0 :     if ( mbInitFillColor )
    1682           0 :         ImplInitFillColor();
    1683             : 
    1684             :     // use b2dpolygon drawing if possible
    1685           0 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1686           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1687           0 :         && ROP_OVERPAINT == GetRasterOp()
    1688           0 :         && (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           0 :     if ( nPoly == 1 )
    1731             :     {
    1732             :         // #100127# Map to DrawPolygon
    1733           0 :         Polygon aPoly = rPolyPoly.GetObject( 0 );
    1734           0 :         if( aPoly.GetSize() >= 2 )
    1735             :         {
    1736           0 :             GDIMetaFile* pOldMF = mpMetaFile;
    1737           0 :             mpMetaFile = NULL;
    1738             : 
    1739           0 :             DrawPolygon( aPoly );
    1740             : 
    1741           0 :             mpMetaFile = pOldMF;
    1742           0 :         }
    1743             :     }
    1744             :     else
    1745             :     {
    1746             :         // #100127# moved real PolyPolygon draw to separate method,
    1747             :         // have to call recursively, avoiding duplicate
    1748             :         // ImplLogicToDevicePixel calls
    1749           0 :         ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
    1750             :     }
    1751           0 :     if( mpAlphaVDev )
    1752           0 :         mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
    1753             : }
    1754             : 
    1755           0 : void OutputDevice::DrawPolygon( const basegfx::B2DPolygon& rB2DPolygon)
    1756             : {
    1757             :     // AW: Do NOT paint empty polygons
    1758           0 :     if(rB2DPolygon.count())
    1759             :     {
    1760           0 :         basegfx::B2DPolyPolygon aPP( rB2DPolygon );
    1761           0 :         DrawPolyPolygon( aPP );
    1762             :     }
    1763           0 : }
    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           0 : void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
    1770             : {
    1771             : 
    1772           0 :     if( mpMetaFile )
    1773           0 :         mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
    1774             : 
    1775             :     // call helper
    1776           0 :     ImplDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
    1777           0 : }
    1778             : 
    1779           0 : void OutputDevice::ImplDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
    1780             : {
    1781             :     // Do not paint empty PolyPolygons
    1782           0 :     if(!rB2DPolyPoly.count() || !IsDeviceOutputNecessary())
    1783           0 :         return;
    1784             : 
    1785             :     // we need a graphics
    1786           0 :     if( !mpGraphics )
    1787           0 :         if( !ImplGetGraphics() )
    1788           0 :             return;
    1789             : 
    1790           0 :     if( mbInitClipRegion )
    1791           0 :         ImplInitClipRegion();
    1792           0 :     if( mbOutputClipped )
    1793           0 :         return;
    1794             : 
    1795           0 :     if( mbInitLineColor )
    1796           0 :         ImplInitLineColor();
    1797           0 :     if( mbInitFillColor )
    1798           0 :         ImplInitFillColor();
    1799             : 
    1800           0 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1801           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1802           0 :         && ROP_OVERPAINT == GetRasterOp()
    1803           0 :         && (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           0 :     const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
    1847           0 :     const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
    1848           0 :     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           0 : 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           0 :     if(!rB2DPolygon.count())
    1900           0 :         return true;
    1901             : 
    1902             :     // we need a graphics
    1903           0 :     if( !mpGraphics )
    1904           0 :         if( !ImplGetGraphics() )
    1905           0 :             return false;
    1906             : 
    1907           0 :     if( mbInitClipRegion )
    1908           0 :         ImplInitClipRegion();
    1909             : 
    1910           0 :     if( mbOutputClipped )
    1911           0 :         return true;
    1912             : 
    1913           0 :     if( mbInitLineColor )
    1914           0 :         ImplInitLineColor();
    1915             : 
    1916           0 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1917           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1918           0 :         && ROP_OVERPAINT == GetRasterOp()
    1919           0 :         && IsLineColor());
    1920             : 
    1921           0 :     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           0 :     return false;
    1940             : }
    1941             : 
    1942           0 : void OutputDevice::DrawPolyLine(
    1943             :     const basegfx::B2DPolygon& rB2DPolygon,
    1944             :     double fLineWidth,
    1945             :     basegfx::B2DLineJoin eLineJoin,
    1946             :     css::drawing::LineCap eLineCap)
    1947             : {
    1948             : 
    1949           0 :     if( mpMetaFile )
    1950             :     {
    1951           0 :         LineInfo aLineInfo;
    1952           0 :         if( fLineWidth != 0.0 )
    1953           0 :             aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    1954           0 :         const Polygon aToolsPolygon( rB2DPolygon );
    1955           0 :         mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
    1956             :     }
    1957             : 
    1958             :     // Do not paint empty PolyPolygons
    1959           0 :     if(!rB2DPolygon.count() || !IsDeviceOutputNecessary())
    1960           0 :         return;
    1961             : 
    1962             :     // we need a graphics
    1963           0 :     if( !mpGraphics )
    1964           0 :         if( !ImplGetGraphics() )
    1965           0 :             return;
    1966             : 
    1967           0 :     if( mbInitClipRegion )
    1968           0 :         ImplInitClipRegion();
    1969           0 :     if( mbOutputClipped )
    1970           0 :         return;
    1971             : 
    1972           0 :     if( mbInitLineColor )
    1973           0 :         ImplInitLineColor();
    1974             : 
    1975           0 :     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
    1976           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
    1977           0 :         && ROP_OVERPAINT == GetRasterOp()
    1978           0 :         && IsLineColor());
    1979             : 
    1980             :     // use b2dpolygon drawing if possible
    1981           0 :     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           0 :     if(fLineWidth >= 2.5
    1991           0 :         && rB2DPolygon.count()
    1992           0 :         && 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           0 :         const Polygon aToolsPolygon( rB2DPolygon );
    2035           0 :         LineInfo aLineInfo;
    2036           0 :         if( fLineWidth != 0.0 )
    2037           0 :             aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
    2038           0 :         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           0 : void OutputDevice::Push( sal_uInt16 nFlags )
    2055             : {
    2056             : 
    2057           0 :     if ( mpMetaFile )
    2058           0 :         mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
    2059             : 
    2060           0 :     ImplObjStack* pData = new ImplObjStack;
    2061           0 :     pData->mpPrev = mpObjStack;
    2062           0 :     mpObjStack = pData;
    2063             : 
    2064           0 :     pData->mnFlags = nFlags;
    2065             : 
    2066           0 :     if ( nFlags & PUSH_LINECOLOR )
    2067             :     {
    2068           0 :         if ( mbLineColor )
    2069           0 :             pData->mpLineColor = new Color( maLineColor );
    2070             :         else
    2071           0 :             pData->mpLineColor = NULL;
    2072             :     }
    2073           0 :     if ( nFlags & PUSH_FILLCOLOR )
    2074             :     {
    2075           0 :         if ( mbFillColor )
    2076           0 :             pData->mpFillColor = new Color( maFillColor );
    2077             :         else
    2078           0 :             pData->mpFillColor = NULL;
    2079             :     }
    2080           0 :     if ( nFlags & PUSH_FONT )
    2081           0 :         pData->mpFont = new Font( maFont );
    2082           0 :     if ( nFlags & PUSH_TEXTCOLOR )
    2083           0 :         pData->mpTextColor = new Color( GetTextColor() );
    2084           0 :     if ( nFlags & PUSH_TEXTFILLCOLOR )
    2085             :     {
    2086           0 :         if ( IsTextFillColor() )
    2087           0 :             pData->mpTextFillColor = new Color( GetTextFillColor() );
    2088             :         else
    2089           0 :             pData->mpTextFillColor = NULL;
    2090             :     }
    2091           0 :     if ( nFlags & PUSH_TEXTLINECOLOR )
    2092             :     {
    2093           0 :         if ( IsTextLineColor() )
    2094           0 :             pData->mpTextLineColor = new Color( GetTextLineColor() );
    2095             :         else
    2096           0 :             pData->mpTextLineColor = NULL;
    2097             :     }
    2098           0 :     if ( nFlags & PUSH_OVERLINECOLOR )
    2099             :     {
    2100           0 :         if ( IsOverlineColor() )
    2101           0 :             pData->mpOverlineColor = new Color( GetOverlineColor() );
    2102             :         else
    2103           0 :             pData->mpOverlineColor = NULL;
    2104             :     }
    2105           0 :     if ( nFlags & PUSH_TEXTALIGN )
    2106           0 :         pData->meTextAlign = GetTextAlign();
    2107           0 :     if( nFlags & PUSH_TEXTLAYOUTMODE )
    2108           0 :         pData->mnTextLayoutMode = GetLayoutMode();
    2109           0 :     if( nFlags & PUSH_TEXTLANGUAGE )
    2110           0 :         pData->meTextLanguage = GetDigitLanguage();
    2111           0 :     if ( nFlags & PUSH_RASTEROP )
    2112           0 :         pData->meRasterOp = GetRasterOp();
    2113           0 :     if ( nFlags & PUSH_MAPMODE )
    2114             :     {
    2115           0 :         pData->mpMapMode = new MapMode( maMapMode );
    2116           0 :         pData->mbMapActive = mbMap;
    2117             :     }
    2118           0 :     if ( nFlags & PUSH_CLIPREGION )
    2119             :     {
    2120           0 :         if ( mbClipRegion )
    2121           0 :             pData->mpClipRegion = new Region( maRegion );
    2122             :         else
    2123           0 :             pData->mpClipRegion = NULL;
    2124             :     }
    2125           0 :     if ( nFlags & PUSH_REFPOINT )
    2126             :     {
    2127           0 :         if ( mbRefPoint )
    2128           0 :             pData->mpRefPoint = new Point( maRefPoint );
    2129             :         else
    2130           0 :             pData->mpRefPoint = NULL;
    2131             :     }
    2132             : 
    2133           0 :     if( mpAlphaVDev )
    2134           0 :         mpAlphaVDev->Push();
    2135           0 : }
    2136             : 
    2137           0 : void OutputDevice::Pop()
    2138             : {
    2139             : 
    2140           0 :     if( mpMetaFile )
    2141           0 :         mpMetaFile->AddAction( new MetaPopAction() );
    2142             : 
    2143           0 :     GDIMetaFile*    pOldMetaFile = mpMetaFile;
    2144           0 :     ImplObjStack*   pData = mpObjStack;
    2145           0 :     mpMetaFile = NULL;
    2146             : 
    2147           0 :     if ( !pData )
    2148             :     {
    2149             :         SAL_WARN( "vcl.gdi", "OutputDevice::Pop() without OutputDevice::Push()" );
    2150           0 :         return;
    2151             :     }
    2152             : 
    2153           0 :     if( mpAlphaVDev )
    2154           0 :         mpAlphaVDev->Pop();
    2155             : 
    2156           0 :     mpObjStack = pData->mpPrev;
    2157             : 
    2158           0 :     if ( pData->mnFlags & PUSH_LINECOLOR )
    2159             :     {
    2160           0 :         if ( pData->mpLineColor )
    2161           0 :             SetLineColor( *pData->mpLineColor );
    2162             :         else
    2163           0 :             SetLineColor();
    2164             :     }
    2165           0 :     if ( pData->mnFlags & PUSH_FILLCOLOR )
    2166             :     {
    2167           0 :         if ( pData->mpFillColor )
    2168           0 :             SetFillColor( *pData->mpFillColor );
    2169             :         else
    2170           0 :             SetFillColor();
    2171             :     }
    2172           0 :     if ( pData->mnFlags & PUSH_FONT )
    2173           0 :         SetFont( *pData->mpFont );
    2174           0 :     if ( pData->mnFlags & PUSH_TEXTCOLOR )
    2175           0 :         SetTextColor( *pData->mpTextColor );
    2176           0 :     if ( pData->mnFlags & PUSH_TEXTFILLCOLOR )
    2177             :     {
    2178           0 :         if ( pData->mpTextFillColor )
    2179           0 :             SetTextFillColor( *pData->mpTextFillColor );
    2180             :         else
    2181           0 :             SetTextFillColor();
    2182             :     }
    2183           0 :     if ( pData->mnFlags & PUSH_TEXTLINECOLOR )
    2184             :     {
    2185           0 :         if ( pData->mpTextLineColor )
    2186           0 :             SetTextLineColor( *pData->mpTextLineColor );
    2187             :         else
    2188           0 :             SetTextLineColor();
    2189             :     }
    2190           0 :     if ( pData->mnFlags & PUSH_OVERLINECOLOR )
    2191             :     {
    2192           0 :         if ( pData->mpOverlineColor )
    2193           0 :             SetOverlineColor( *pData->mpOverlineColor );
    2194             :         else
    2195           0 :             SetOverlineColor();
    2196             :     }
    2197           0 :     if ( pData->mnFlags & PUSH_TEXTALIGN )
    2198           0 :         SetTextAlign( pData->meTextAlign );
    2199           0 :     if( pData->mnFlags & PUSH_TEXTLAYOUTMODE )
    2200           0 :         SetLayoutMode( pData->mnTextLayoutMode );
    2201           0 :     if( pData->mnFlags & PUSH_TEXTLANGUAGE )
    2202           0 :         SetDigitLanguage( pData->meTextLanguage );
    2203           0 :     if ( pData->mnFlags & PUSH_RASTEROP )
    2204           0 :         SetRasterOp( pData->meRasterOp );
    2205           0 :     if ( pData->mnFlags & PUSH_MAPMODE )
    2206             :     {
    2207           0 :         if ( pData->mpMapMode )
    2208           0 :             SetMapMode( *pData->mpMapMode );
    2209             :         else
    2210           0 :             SetMapMode();
    2211           0 :         mbMap = pData->mbMapActive;
    2212             :     }
    2213           0 :     if ( pData->mnFlags & PUSH_CLIPREGION )
    2214           0 :         ImplSetClipRegion( pData->mpClipRegion );
    2215           0 :     if ( pData->mnFlags & PUSH_REFPOINT )
    2216             :     {
    2217           0 :         if ( pData->mpRefPoint )
    2218           0 :             SetRefPoint( *pData->mpRefPoint );
    2219             :         else
    2220           0 :             SetRefPoint();
    2221             :     }
    2222             : 
    2223           0 :     ImplDeleteObjStack( pData );
    2224             : 
    2225           0 :     mpMetaFile = pOldMetaFile;
    2226             : }
    2227             : 
    2228           0 : void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
    2229             : {
    2230           0 :     mpMetaFile = pMtf;
    2231           0 : }
    2232             : 
    2233           0 : void OutputDevice::EnableOutput( bool bEnable )
    2234             : {
    2235           0 :     mbOutput = bEnable;
    2236             : 
    2237           0 :     if( mpAlphaVDev )
    2238           0 :         mpAlphaVDev->EnableOutput( bEnable );
    2239           0 : }
    2240             : 
    2241           0 : void OutputDevice::SetSettings( const AllSettings& rSettings )
    2242             : {
    2243           0 :     *mxSettings = rSettings;
    2244             : 
    2245           0 :     if( mpAlphaVDev )
    2246           0 :         mpAlphaVDev->SetSettings( rSettings );
    2247           0 : }
    2248             : 
    2249           0 : sal_uInt16 OutputDevice::GetBitCount() const
    2250             : {
    2251             :     // we need a graphics instance
    2252           0 :     if ( !mpGraphics )
    2253             :     {
    2254           0 :         if ( !((OutputDevice*)this)->ImplGetGraphics() )
    2255           0 :             return 0;
    2256             :     }
    2257             : 
    2258           0 :     return (sal_uInt16)mpGraphics->GetBitCount();
    2259             : }
    2260             : 
    2261           0 : sal_uInt16 OutputDevice::GetAlphaBitCount() const
    2262             : {
    2263           0 :     return 0;
    2264             : }
    2265             : 
    2266           0 : sal_uLong OutputDevice::GetColorCount() const
    2267             : {
    2268             : 
    2269           0 :     const sal_uInt16 nBitCount = GetBitCount();
    2270           0 :     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           0 : css::uno::Reference< css::awt::XGraphics > OutputDevice::CreateUnoGraphics()
    2279             : {
    2280           0 :     UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
    2281           0 :     return pWrapper ? pWrapper->CreateGraphics( this ) : css::uno::Reference< css::awt::XGraphics >();
    2282             : }
    2283             : 
    2284           0 : SystemGraphicsData OutputDevice::GetSystemGfxData() const
    2285             : {
    2286           0 :     if ( !mpGraphics )
    2287             :     {
    2288           0 :         if ( !ImplGetGraphics() )
    2289           0 :             return SystemGraphicsData();
    2290             :     }
    2291             : 
    2292           0 :     return mpGraphics->GetGraphicsData();
    2293             : }
    2294             : 
    2295           0 : css::uno::Any OutputDevice::GetSystemGfxDataAny() const
    2296             : {
    2297           0 :     const SystemGraphicsData aSysData = GetSystemGfxData();
    2298             :     css::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)&aSysData,
    2299           0 :                                                       aSysData.nSize );
    2300             : 
    2301           0 :     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           3 : }
    2326             : 
    2327             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10