/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include <tools/ref.hxx>
#include <tools/debug.hxx>
#include <tools/poly.hxx>

#include <vcl/svapp.hxx>
#include <vcl/ctrl.hxx>
#include <vcl/region.hxx>
#include <vcl/virdev.hxx>
#include <vcl/window.hxx>
#include <vcl/metaact.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/print.hxx>
#include <vcl/outdev.hxx>
#include <vcl/unowrap.hxx>
// declare system types in sysdata.hxx
#include <svsys.h>
#include <vcl/sysdata.hxx>

#include <salgdi.hxx>
#include <sallayout.hxx>
#include <salframe.hxx>
#include <salvd.hxx>
#include <salprn.hxx>
#include <svdata.hxx>
#include <window.h>
#include <outdev.h>
#include <outdata.hxx>

#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dlinegeometry.hxx>

#include <com/sun/star/awt/XGraphics.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <vcl/unohelp.hxx>

#include <numeric>

using namespace ::com::sun::star;

DBG_NAME( OutputDevice )
DBG_NAME( Polygon )
DBG_NAME( PolyPolygon )
DBG_NAMEEX( Region )

// -----------------------------------------------------------------------

#ifdef DBG_UTIL
const char* ImplDbgCheckOutputDevice( const void* pObj )
{
	DBG_TESTSOLARMUTEX();

	const OutputDevice* pOutDev = (OutputDevice*)pObj;

	if ( (pOutDev->GetOutDevType() != OUTDEV_DONTKNOW) &&
		 (pOutDev->GetOutDevType() != OUTDEV_WINDOW) &&
		 (pOutDev->GetOutDevType() != OUTDEV_PRINTER) &&
		 (pOutDev->GetOutDevType() != OUTDEV_VIRDEV) )
		return "OutputDevice data overwrite";

	return NULL;
}
#endif

// =======================================================================

#define OUTDEV_POLYPOLY_STACKBUF		32

// =======================================================================

struct ImplObjStack
{
    ImplObjStack*   mpPrev;
    MapMode*        mpMapMode;
    bool            mbMapActive;
    Region*         mpClipRegion;
    Color*          mpLineColor;
    Color*          mpFillColor;
    Font*           mpFont;
    Color*          mpTextColor;
    Color*          mpTextFillColor;
    Color*          mpTextLineColor;
    Color*          mpOverlineColor;
    Point*          mpRefPoint;
    TextAlign       meTextAlign;
    RasterOp        meRasterOp;
    sal_uLong           mnTextLayoutMode;
    LanguageType    meTextLanguage;
    sal_uInt16          mnFlags;
};

// -----------------------------------------------------------------------

static void ImplDeleteObjStack( ImplObjStack* pObjStack )
{
	if ( pObjStack->mnFlags & PUSH_LINECOLOR )
	{
		if ( pObjStack->mpLineColor )
			delete pObjStack->mpLineColor;
	}
	if ( pObjStack->mnFlags & PUSH_FILLCOLOR )
	{
		if ( pObjStack->mpFillColor )
			delete pObjStack->mpFillColor;
	}
	if ( pObjStack->mnFlags & PUSH_FONT )
		delete pObjStack->mpFont;
	if ( pObjStack->mnFlags & PUSH_TEXTCOLOR )
		delete pObjStack->mpTextColor;
	if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR )
	{
		if ( pObjStack->mpTextFillColor )
			delete pObjStack->mpTextFillColor;
	}
	if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR )
	{
		if ( pObjStack->mpTextLineColor )
			delete pObjStack->mpTextLineColor;
	}
	if ( pObjStack->mnFlags & PUSH_OVERLINECOLOR )
	{
		if ( pObjStack->mpOverlineColor )
			delete pObjStack->mpOverlineColor;
	}
	if ( pObjStack->mnFlags & PUSH_MAPMODE )
	{
		if ( pObjStack->mpMapMode )
			delete pObjStack->mpMapMode;
	}
	if ( pObjStack->mnFlags & PUSH_CLIPREGION )
	{
		if ( pObjStack->mpClipRegion )
			delete pObjStack->mpClipRegion;
	}
	if ( pObjStack->mnFlags & PUSH_REFPOINT )
	{
		if ( pObjStack->mpRefPoint )
			delete pObjStack->mpRefPoint;
	}

	delete pObjStack;
}

// -----------------------------------------------------------------------

bool OutputDevice::ImplIsAntiparallel() const
{
    bool bRet = false;
    if( ImplGetGraphics() )
    {
        if( ( (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && ! IsRTLEnabled() ) ||
            ( ! (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && IsRTLEnabled() ) )
        {
            bRet = true;
        }
    }
    return bRet;
}

// -----------------------------------------------------------------------


bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGraphics )
{
	DBG_TESTSOLARMUTEX();

	if( !pGraphics )
	{
		if( !mpGraphics )
			if( !ImplGetGraphics() )
				return false;
		pGraphics = mpGraphics;
	}
	
	bool bClipRegion = pGraphics->SetClipRegion( rRegion, this );
	OSL_ENSURE( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" );
	return bClipRegion;
}


// =======================================================================

Polygon ImplSubdivideBezier( const Polygon& rPoly )
{
    Polygon aPoly;

    // #100127# Use adaptive subdivide instead of fixed 25 segments
    rPoly.AdaptiveSubdivide( aPoly );

    return aPoly;
}

// =======================================================================

PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
{
    sal_uInt16 i, nPolys = rPolyPoly.Count();
    PolyPolygon aPolyPoly( nPolys );
    for( i=0; i<nPolys; ++i )
        aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );

    return aPolyPoly;
}

// =======================================================================

// #100127# Extracted from OutputDevice::DrawPolyPolygon()
void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
{
    // AW: This crashes on empty PolyPolygons, avoid that
    if(!nPoly)
        return;

    sal_uInt32			aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
    PCONSTSALPOINT		aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
    sal_uInt8*				aStackAry3[OUTDEV_POLYPOLY_STACKBUF];
    sal_uInt32*			pPointAry;
    PCONSTSALPOINT* 	pPointAryAry;
    const sal_uInt8**	 	pFlagAryAry;
    sal_uInt16				i = 0, j = 0, last = 0;
    sal_Bool				bHaveBezier = sal_False;
    if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
    {
        pPointAry		= new sal_uInt32[nPoly];
        pPointAryAry	= new PCONSTSALPOINT[nPoly];
        pFlagAryAry		= new const sal_uInt8*[nPoly];
    }
    else
    {
        pPointAry		= aStackAry1;
        pPointAryAry	= aStackAry2;
        pFlagAryAry		= (const sal_uInt8**)aStackAry3;
    }
    do
    {
        const Polygon&	rPoly = rPolyPoly.GetObject( i );
        sal_uInt16			nSize = rPoly.GetSize();
        if ( nSize )
        {
            pPointAry[j]	= nSize;
            pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
            pFlagAryAry[j]  = rPoly.GetConstFlagAry();
            last 			= i;

            if( pFlagAryAry[j] )
                bHaveBezier = sal_True;

            ++j;
        }

        ++i;
    }
    while ( i < nPoly );

    if ( j == 1 )
    {
        // #100127# Forward beziers to sal, if any
        if( bHaveBezier )
        {
            if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
            {
                Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
                mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
            }
        }
        else
        {
            mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
        }
    }
    else
    {
        // #100127# Forward beziers to sal, if any
        if( bHaveBezier )
        {
            if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
            {
                PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
                ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
            }
        }
        else
        {
            mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
        }
    }

    if ( pPointAry != aStackAry1 )
    {
        delete[] pPointAry;
        delete[] pPointAryAry;
        delete[] pFlagAryAry;
    }
}

// =======================================================================

OutputDevice::OutputDevice() :
	maRegion(true),
	maFillColor( COL_WHITE ),
	maTextLineColor( COL_TRANSPARENT ),
	maSettings( Application::GetSettings() )
{
	DBG_CTOR( OutputDevice, ImplDbgCheckOutputDevice );

	mpGraphics			= NULL;
	mpUnoGraphicsList	= NULL;
	mpPrevGraphics		= NULL;
	mpNextGraphics		= NULL;
	mpMetaFile			= NULL;
	mpFontEntry 		= NULL;
	mpFontCache 		= NULL;
	mpFontList			= NULL;
	mpGetDevFontList	= NULL;
	mpGetDevSizeList	= NULL;
	mpObjStack			= NULL;
	mpOutDevData		= NULL;
    mpPDFWriter			= NULL;
    mpAlphaVDev			= NULL;
	mpExtOutDevData		= NULL;
	mnOutOffX			= 0;
	mnOutOffY			= 0;
	mnOutWidth			= 0;
	mnOutHeight 		= 0;
	mnDPIX				= 0;
	mnDPIY				= 0;
	mnTextOffX			= 0;
	mnTextOffY			= 0;
	mnOutOffOrigX		= 0;
	mnOutOffLogicX		= 0;
	mnOutOffOrigY		= 0;
	mnOutOffLogicY		= 0;
	mnEmphasisAscent	= 0;
	mnEmphasisDescent	= 0;
	mnDrawMode			= 0;
	mnTextLayoutMode        = TEXT_LAYOUT_DEFAULT;
	if( Application::GetSettings().GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
		mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
	meOutDevType		= OUTDEV_DONTKNOW;
    meOutDevViewType    = OUTDEV_VIEWTYPE_DONTKNOW;
	mbMap				= sal_False;
	mbMapIsDefault		= sal_True;
	mbClipRegion		= sal_False;
	mbBackground		= sal_False;
	mbOutput			= sal_True;
	mbDevOutput 		= sal_False;
	mbOutputClipped 	= sal_False;
	maTextColor 		= Color( COL_BLACK );
	maOverlineColor 	= Color( COL_TRANSPARENT );
	meTextAlign 		= maFont.GetAlign();
	meRasterOp			= ROP_OVERPAINT;
	mnAntialiasing		= 0;
    meTextLanguage      = 0;  // TODO: get default from configuration?
	mbLineColor 		= sal_True;
	mbFillColor 		= sal_True;
	mbInitLineColor 	= sal_True;
	mbInitFillColor 	= sal_True;
	mbInitFont			= sal_True;
	mbInitTextColor 	= sal_True;
	mbInitClipRegion	= sal_True;
	mbClipRegionSet 	= sal_False;
	mbKerning			= sal_False;
	mbNewFont			= sal_True;
	mbTextLines 		= sal_False;
	mbTextSpecial		= sal_False;
	mbRefPoint			= sal_False;
    mbEnableRTL         = sal_False;    // mirroring must be explicitly allowed (typically for windows only)

	// struct ImplMapRes
    maMapRes.mnMapOfsX 			= 0;
    maMapRes.mnMapOfsY 			= 0;
    maMapRes.mnMapScNumX 		= 1;
    maMapRes.mnMapScNumY 		= 1;
    maMapRes.mnMapScDenomX 		= 1;
    maMapRes.mnMapScDenomY		= 1;
	// struct ImplThresholdRes
    maThresRes.mnThresLogToPixX	= 0;
    maThresRes.mnThresLogToPixY	= 0;
    maThresRes.mnThresPixToLogX	= 0;
    maThresRes.mnThresPixToLogY	= 0;
}

// -----------------------------------------------------------------------

OutputDevice::~OutputDevice()
{
	DBG_DTOR( OutputDevice, ImplDbgCheckOutputDevice );

	if ( GetUnoGraphicsList() )
	{
		UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False );
		if ( pWrapper )
			pWrapper->ReleaseAllGraphics( this );
		delete mpUnoGraphicsList;
		mpUnoGraphicsList = NULL;
	}

	if ( mpOutDevData )
		ImplDeInitOutDevData();

	ImplObjStack* pData = mpObjStack;
	if ( pData )
	{
		DBG_ERRORFILE( "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
		while ( pData )
		{
			ImplObjStack* pTemp = pData;
			pData = pData->mpPrev;
			ImplDeleteObjStack( pTemp );
		}
	}

    // release the active font instance
    if( mpFontEntry )
        mpFontCache->Release( mpFontEntry );
    // remove cached results of GetDevFontList/GetDevSizeList
    // TODO: use smart pointers for them
    if( mpGetDevFontList )
        delete mpGetDevFontList;
    if( mpGetDevSizeList )
        delete mpGetDevSizeList;

    // release ImplFontCache specific to this OutputDevice
    // TODO: refcount ImplFontCache
    if( mpFontCache
    && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
    && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
    {
        delete mpFontCache;
        mpFontCache = NULL;
    }

    // release ImplFontList specific to this OutputDevice
    // TODO: refcount ImplFontList
    if( mpFontList
    && (mpFontList != ImplGetSVData()->maGDIData.mpScreenFontList)
    && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
    {
        mpFontList->Clear();
        delete mpFontList;
        mpFontList = NULL;
    }

    delete mpAlphaVDev;
}

bool OutputDevice::supportsOperation( OutDevSupportType eType ) const
{
	if( !mpGraphics )
		if( !ImplGetGraphics() )
			return false;
	const bool bHasSupport = mpGraphics->supportsOperation( eType );
	return bHasSupport;
}

// -----------------------------------------------------------------------

void OutputDevice::EnableRTL( sal_Bool bEnable )
{
    mbEnableRTL = (bEnable != 0);
    if( meOutDevType == OUTDEV_VIRDEV )
    {
        // virdevs default to not mirroring, they will only be set to mirroring
        // under rare circumstances in the UI, eg the valueset control
        // because each virdev has its own SalGraphics we can safely switch the SalGraphics here
        // ...hopefully
        if( ImplGetGraphics() )
            mpGraphics->SetLayout( mbEnableRTL ? SAL_LAYOUT_BIDI_RTL : 0 );
    }

    // convenience: for controls also switch layout mode
    if( dynamic_cast<Control*>(this) != 0 )
        SetLayoutMode( bEnable ? TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT : TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_TEXTORIGIN_LEFT);

    Window* pWin = dynamic_cast<Window*>(this);
    if( pWin )
        pWin->StateChanged( STATE_CHANGE_MIRRORING );
    
    if( mpAlphaVDev )
        mpAlphaVDev->EnableRTL( bEnable );
}

sal_Bool OutputDevice::ImplHasMirroredGraphics()
{
   // HOTFIX for #i55719#
   if( meOutDevType == OUTDEV_PRINTER )
       return sal_False;

   return ( ImplGetGraphics() && (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) );
}

// note: the coordiantes to be remirrored are in frame coordiantes !

void    OutputDevice::ImplReMirror( Point &rPoint ) const
{
    rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
}
void    OutputDevice::ImplReMirror( Rectangle &rRect ) const
{
    long nWidth = rRect.nRight - rRect.nLeft;

    //long lc_x = rRect.nLeft - mnOutOffX;    // normalize
    //lc_x = mnOutWidth - nWidth - 1 - lc_x;  // mirror
    //rRect.nLeft = lc_x + mnOutOffX;         // re-normalize

    rRect.nLeft = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.nLeft + mnOutOffX;
    rRect.nRight = rRect.nLeft + nWidth;
}
void    OutputDevice::ImplReMirror( Region &rRegion ) const
{
    RectangleVector aRectangles;
    rRegion.GetRegionRectangles(aRectangles);
    Region aMirroredRegion;

    for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
    {
        ImplReMirror(*aRectIter);
        aMirroredRegion.Union(*aRectIter);
    }

    rRegion = aMirroredRegion;

//	long				nX;
//	long				nY;
//	long				nWidth;
//	long				nHeight;
//	ImplRegionInfo		aInfo;
//	sal_Bool				bRegionRect;
//    Region              aMirroredRegion;
//
//	bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
//	while ( bRegionRect )
//	{
//        Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
//        ImplReMirror( aRect );
//        aMirroredRegion.Union( aRect );
//		bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
//	}
//    rRegion = aMirroredRegion;
}


// -----------------------------------------------------------------------

int OutputDevice::ImplGetGraphics() const
{
	DBG_TESTSOLARMUTEX();

	if ( mpGraphics )
		return sal_True;

	mbInitLineColor 	= sal_True;
	mbInitFillColor 	= sal_True;
	mbInitFont			= sal_True;
	mbInitTextColor 	= sal_True;
	mbInitClipRegion	= sal_True;

	ImplSVData* pSVData = ImplGetSVData();
	if ( meOutDevType == OUTDEV_WINDOW )
	{
		Window* pWindow = (Window*)this;

		mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
        // try harder if no wingraphics was available directly
		if ( !mpGraphics )
		{
            // find another output device in the same frame
			OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
			while ( pReleaseOutDev )
			{
				if ( ((Window*)pReleaseOutDev)->mpWindowImpl->mpFrame == pWindow->mpWindowImpl->mpFrame )
					break;
				pReleaseOutDev = pReleaseOutDev->mpPrevGraphics;
			}

			if ( pReleaseOutDev )
			{
                // steal the wingraphics from the other outdev
				mpGraphics = pReleaseOutDev->mpGraphics;
				pReleaseOutDev->ImplReleaseGraphics( sal_False );
			}
			else
			{
                // if needed retry after releasing least recently used wingraphics
				while ( !mpGraphics )
				{
					if ( !pSVData->maGDIData.mpLastWinGraphics )
						break;
					pSVData->maGDIData.mpLastWinGraphics->ImplReleaseGraphics();
					mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
				}
			}
		}

        // update global LRU list of wingraphics
		if ( mpGraphics )
		{
			mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics;
			pSVData->maGDIData.mpFirstWinGraphics = const_cast<OutputDevice*>(this);
			if ( mpNextGraphics )
				mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
			if ( !pSVData->maGDIData.mpLastWinGraphics )
				pSVData->maGDIData.mpLastWinGraphics = const_cast<OutputDevice*>(this);
		}
	}
	else if ( meOutDevType == OUTDEV_VIRDEV )
	{
		const VirtualDevice* pVirDev = (const VirtualDevice*)this;

		if ( pVirDev->mpVirDev )
		{
			mpGraphics = pVirDev->mpVirDev->GetGraphics();
            // if needed retry after releasing least recently used virtual device graphics
			while ( !mpGraphics )
			{
				if ( !pSVData->maGDIData.mpLastVirGraphics )
					break;
				pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
				mpGraphics = pVirDev->mpVirDev->GetGraphics();
			}
            // update global LRU list of virtual device graphics
			if ( mpGraphics )
			{
				mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
				pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
				if ( mpNextGraphics )
					mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
				if ( !pSVData->maGDIData.mpLastVirGraphics )
					pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
			}
		}
	}
	else if ( meOutDevType == OUTDEV_PRINTER )
	{
		const Printer* pPrinter = (const Printer*)this;

		if ( pPrinter->mpJobGraphics )
			mpGraphics = pPrinter->mpJobGraphics;
		else if ( pPrinter->mpDisplayDev )
		{
			const VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
			mpGraphics = pVirDev->mpVirDev->GetGraphics();
            // if needed retry after releasing least recently used virtual device graphics
			while ( !mpGraphics )
			{
				if ( !pSVData->maGDIData.mpLastVirGraphics )
					break;
				pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
				mpGraphics = pVirDev->mpVirDev->GetGraphics();
			}
            // update global LRU list of virtual device graphics
			if ( mpGraphics )
			{
				mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
				pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
				if ( mpNextGraphics )
					mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
				if ( !pSVData->maGDIData.mpLastVirGraphics )
					pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
			}
		}
		else
		{
			mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
            // if needed retry after releasing least recently used printer graphics
			while ( !mpGraphics )
			{
				if ( !pSVData->maGDIData.mpLastPrnGraphics )
					break;
				pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics();
				mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
			}
            // update global LRU list of printer graphics
			if ( mpGraphics )
			{
				mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
				pSVData->maGDIData.mpFirstPrnGraphics = const_cast<OutputDevice*>(this);
				if ( mpNextGraphics )
					mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
				if ( !pSVData->maGDIData.mpLastPrnGraphics )
					pSVData->maGDIData.mpLastPrnGraphics = const_cast<OutputDevice*>(this);
			}
		}
	}

	if ( mpGraphics )
	{
		mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
        mpGraphics->setAntiAliasB2DDraw(mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW);
        return sal_True;
	}

	return sal_False;
}

// -----------------------------------------------------------------------

void OutputDevice::ImplReleaseGraphics( sal_Bool bRelease )
{
	DBG_TESTSOLARMUTEX();

	if ( !mpGraphics )
		return;

    // release the fonts of the physically released graphics device
    if( bRelease )
    {
#ifndef UNX
        // HACK to fix an urgent P1 printing issue fast
        // WinSalPrinter does not respect GetGraphics/ReleaseGraphics conventions
        // so Printer::mpGraphics often points to a dead WinSalGraphics
        // TODO: fix WinSalPrinter's GetGraphics/ReleaseGraphics handling
        if( meOutDevType != OUTDEV_PRINTER )
#endif
        mpGraphics->ReleaseFonts();

        mbNewFont = true;
        mbInitFont = true;

        if ( mpFontEntry )
        {
            mpFontCache->Release( mpFontEntry );
            mpFontEntry = NULL;
        }

        if ( mpGetDevFontList )
        {
            delete mpGetDevFontList;
            mpGetDevFontList = NULL;
        }

        if ( mpGetDevSizeList )
        {
            delete mpGetDevSizeList;
            mpGetDevSizeList = NULL;
        }
    }

	ImplSVData* pSVData = ImplGetSVData();
	if ( meOutDevType == OUTDEV_WINDOW )
	{
		Window* pWindow = (Window*)this;

		if ( bRelease )
			pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
        // remove from global LRU list of window graphics
		if ( mpPrevGraphics )
			mpPrevGraphics->mpNextGraphics = mpNextGraphics;
		else
			pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics;
		if ( mpNextGraphics )
			mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
		else
			pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics;
	}
	else if ( meOutDevType == OUTDEV_VIRDEV )
	{
		VirtualDevice* pVirDev = (VirtualDevice*)this;

		if ( bRelease )
			pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
        // remove from global LRU list of virtual device graphics
		if ( mpPrevGraphics )
			mpPrevGraphics->mpNextGraphics = mpNextGraphics;
		else
			pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
		if ( mpNextGraphics )
			mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
		else
			pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
	}
	else if ( meOutDevType == OUTDEV_PRINTER )
	{
		Printer* pPrinter = (Printer*)this;

		if ( !pPrinter->mpJobGraphics )
		{
			if ( pPrinter->mpDisplayDev )
			{
				VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
				if ( bRelease )
					pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
                // remove from global LRU list of virtual device graphics
				if ( mpPrevGraphics )
					mpPrevGraphics->mpNextGraphics = mpNextGraphics;
				else
					pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
				if ( mpNextGraphics )
					mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
				else
					pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
			}
			else
			{
				if ( bRelease )
					pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics );
                // remove from global LRU list of printer graphics
				if ( mpPrevGraphics )
					mpPrevGraphics->mpNextGraphics = mpNextGraphics;
				else
					pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics;
				if ( mpNextGraphics )
					mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
				else
					pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics;
		   }
		}
	}

	mpGraphics		= NULL;
	mpPrevGraphics	= NULL;
	mpNextGraphics	= NULL;
}

// -----------------------------------------------------------------------

void OutputDevice::ImplInitOutDevData()
{
	if ( !mpOutDevData )
	{
		mpOutDevData = new ImplOutDevData;
		mpOutDevData->mpRotateDev = NULL;
        mpOutDevData->mpRecordLayout = NULL;

		// #i75163#
		mpOutDevData->mpViewTransform = NULL;
		mpOutDevData->mpInverseViewTransform = NULL;
	}
}

// -----------------------------------------------------------------------

// #i75163#
void OutputDevice::ImplInvalidateViewTransform()
{
	if(mpOutDevData)
	{
		if(mpOutDevData->mpViewTransform)
		{
			delete mpOutDevData->mpViewTransform;
			mpOutDevData->mpViewTransform = NULL;
		}

		if(mpOutDevData->mpInverseViewTransform)
		{
			delete mpOutDevData->mpInverseViewTransform;
			mpOutDevData->mpInverseViewTransform = NULL;
		}
	}
}

// -----------------------------------------------------------------------

sal_Bool OutputDevice::ImplIsRecordLayout() const
{
    return mpOutDevData && mpOutDevData->mpRecordLayout;
}

// -----------------------------------------------------------------------

void OutputDevice::ImplDeInitOutDevData()
{
	if ( mpOutDevData )
	{
		if ( mpOutDevData->mpRotateDev )
			delete mpOutDevData->mpRotateDev;

		// #i75163#
		ImplInvalidateViewTransform();

		delete mpOutDevData;
	}
}

// -----------------------------------------------------------------------

void OutputDevice::ImplInitLineColor()
{
	DBG_TESTSOLARMUTEX();

	if( mbLineColor )
	{
		if( ROP_0 == meRasterOp )
			mpGraphics->SetROPLineColor( SAL_ROP_0 );
		else if( ROP_1 == meRasterOp )
			mpGraphics->SetROPLineColor( SAL_ROP_1 );
		else if( ROP_INVERT == meRasterOp )
			mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
		else
			mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
	}
	else
		mpGraphics->SetLineColor();

	mbInitLineColor = sal_False;
}

// -----------------------------------------------------------------------

void OutputDevice::ImplInitFillColor()
{
	DBG_TESTSOLARMUTEX();

	if( mbFillColor )
	{
		if( ROP_0 == meRasterOp )
			mpGraphics->SetROPFillColor( SAL_ROP_0 );
		else if( ROP_1 == meRasterOp )
			mpGraphics->SetROPFillColor( SAL_ROP_1 );
		else if( ROP_INVERT == meRasterOp )
			mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
		else
			mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
	}
	else
		mpGraphics->SetFillColor();

	mbInitFillColor = sal_False;
}

// -----------------------------------------------------------------------

void OutputDevice::ImplInitClipRegion()
{
	DBG_TESTSOLARMUTEX();

	if ( GetOutDevType() == OUTDEV_WINDOW )
	{
		Window* pWindow = (Window*)this;
		Region	aRegion;

		// Hintergrund-Sicherung zuruecksetzen
		if ( pWindow->mpWindowImpl->mpFrameData->mpFirstBackWin )
			pWindow->ImplInvalidateAllOverlapBackgrounds();
		if ( pWindow->mpWindowImpl->mbInPaint )
			aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
		else
        {
			aRegion = *(pWindow->ImplGetWinChildClipRegion());
            // --- RTL -- only this region is in frame coordinates, so re-mirror it
            // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) !
            if( ImplIsAntiparallel() )
	            ImplReMirror ( aRegion );
        }
		if ( mbClipRegion )
			aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
		if ( aRegion.IsEmpty() )
			mbOutputClipped = sal_True;
		else
		{
			mbOutputClipped = sal_False;
			ImplSelectClipRegion( aRegion );
		}
		mbClipRegionSet = sal_True;
	}
	else
	{
		if ( mbClipRegion )
		{
			if ( maRegion.IsEmpty() )
				mbOutputClipped = sal_True;
			else
			{
				mbOutputClipped = sal_False;
            
				// #102532# Respect output offset also for clip region
                Region aRegion( ImplPixelToDevicePixel( maRegion ) );
                const bool bClipDeviceBounds( ! GetPDFWriter()
                                              && GetOutDevType() != OUTDEV_PRINTER );
                if( bClipDeviceBounds )
                {
                    // #b6520266# Perform actual rect clip against outdev
                    // dimensions, to generate empty clips whenever one of the
                    // values is completely off the device.
                    Rectangle aDeviceBounds( mnOutOffX, mnOutOffY,
                                             mnOutOffX+GetOutputWidthPixel()-1,
                                             mnOutOffY+GetOutputHeightPixel()-1 );
                    aRegion.Intersect( aDeviceBounds );
                }
		        
                if ( aRegion.IsEmpty() )
                {
			        mbOutputClipped = sal_True;
                }
		        else
		        {
			        mbOutputClipped = sal_False;
			        ImplSelectClipRegion( aRegion );
		        }
			}

			mbClipRegionSet = sal_True;
		}
		else
		{
			if ( mbClipRegionSet )
			{
				mpGraphics->ResetClipRegion();
				mbClipRegionSet = sal_False;
			}

			mbOutputClipped = sal_False;
		}
	}

	mbInitClipRegion = sal_False;
}

// -----------------------------------------------------------------------

void OutputDevice::ImplSetClipRegion( const Region* pRegion )
{
	DBG_TESTSOLARMUTEX();

	if ( !pRegion )
	{
		if ( mbClipRegion )
		{
			maRegion			= Region(true);
			mbClipRegion		= sal_False;
			mbInitClipRegion	= sal_True;
		}
	}
	else
	{
		maRegion			= *pRegion;
		mbClipRegion		= sal_True;
		mbInitClipRegion	= sal_True;
	}
}

// -----------------------------------------------------------------------

void OutputDevice::SetClipRegion()
{
	DBG_TRACE( "OutputDevice::SetClipRegion()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaClipRegionAction( Region(), sal_False ) );

	ImplSetClipRegion( NULL );

    if( mpAlphaVDev )
        mpAlphaVDev->SetClipRegion();
}

// -----------------------------------------------------------------------

void OutputDevice::SetClipRegion( const Region& rRegion )
{
	DBG_TRACE( "OutputDevice::SetClipRegion( rRegion )" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, sal_True ) );

	if ( rRegion.IsNull() )
    {
		ImplSetClipRegion( NULL );
    }
	else
	{
		Region aRegion = LogicToPixel( rRegion );
		ImplSetClipRegion( &aRegion );
	}

    if( mpAlphaVDev )
        mpAlphaVDev->SetClipRegion( rRegion );
}

// -----------------------------------------------------------------------

Region OutputDevice::GetClipRegion() const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	return PixelToLogic( maRegion );
}

// -----------------------------------------------------------------------

Region OutputDevice::GetActiveClipRegion() const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( GetOutDevType() == OUTDEV_WINDOW )
	{
		Region aRegion(true);
		Window* pWindow = (Window*)this;
		if ( pWindow->mpWindowImpl->mbInPaint )
		{
			aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
			aRegion.Move( -mnOutOffX, -mnOutOffY );
		}
		if ( mbClipRegion )
			aRegion.Intersect( maRegion );
		return PixelToLogic( aRegion );
	}
	else
		return GetClipRegion();
}

// -----------------------------------------------------------------------

void OutputDevice::MoveClipRegion( long nHorzMove, long nVertMove )
{
	DBG_TRACE( "OutputDevice::MoveClipRegion()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mbClipRegion )
	{
		if( mpMetaFile )
			mpMetaFile->AddAction( new MetaMoveClipRegionAction( nHorzMove, nVertMove ) );

		maRegion.Move( ImplLogicWidthToDevicePixel( nHorzMove ),
					   ImplLogicHeightToDevicePixel( nVertMove ) );
		mbInitClipRegion = sal_True;
	}

    if( mpAlphaVDev )
        mpAlphaVDev->MoveClipRegion( nHorzMove, nVertMove );
}

// -----------------------------------------------------------------------

void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
{
	DBG_TRACE( "OutputDevice::IntersectClipRegion( rRect )" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );

	Rectangle aRect = LogicToPixel( rRect );
	maRegion.Intersect( aRect );
	mbClipRegion		= sal_True;
	mbInitClipRegion	= sal_True;

    if( mpAlphaVDev )
        mpAlphaVDev->IntersectClipRegion( rRect );
}

// -----------------------------------------------------------------------

void OutputDevice::IntersectClipRegion( const Region& rRegion )
{
	DBG_TRACE( "OutputDevice::IntersectClipRegion( rRegion )" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if(!rRegion.IsNull())
	{
		if ( mpMetaFile )
			mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );

		Region aRegion = LogicToPixel( rRegion );
		maRegion.Intersect( aRegion );
		mbClipRegion		= sal_True;
		mbInitClipRegion	= sal_True;
	}

    if( mpAlphaVDev )
        mpAlphaVDev->IntersectClipRegion( rRegion );
}

// -----------------------------------------------------------------------

void OutputDevice::SetDrawMode( sal_uLong nDrawMode )
{
	DBG_TRACE1( "OutputDevice::SetDrawMode( %lx )", nDrawMode );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	mnDrawMode = nDrawMode;

    if( mpAlphaVDev )
        mpAlphaVDev->SetDrawMode( nDrawMode );
}

// -----------------------------------------------------------------------

void OutputDevice::SetRasterOp( RasterOp eRasterOp )
{
	DBG_TRACE1( "OutputDevice::SetRasterOp( %d )", (int)eRasterOp );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );

	if ( meRasterOp != eRasterOp )
	{
		meRasterOp = eRasterOp;
		mbInitLineColor = mbInitFillColor = sal_True;

		if( mpGraphics || ImplGetGraphics() )
			mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
	}

    if( mpAlphaVDev )
        mpAlphaVDev->SetRasterOp( eRasterOp );
}

// -----------------------------------------------------------------------

void OutputDevice::SetLineColor()
{
	DBG_TRACE( "OutputDevice::SetLineColor()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );

	if ( mbLineColor )
	{
		mbInitLineColor = sal_True;
		mbLineColor = sal_False;
		maLineColor = Color( COL_TRANSPARENT );
	}

    if( mpAlphaVDev )
        mpAlphaVDev->SetLineColor();
}

// -----------------------------------------------------------------------

void OutputDevice::SetLineColor( const Color& rColor )
{
	DBG_TRACE1( "OutputDevice::SetLineColor( %lx )", rColor.GetColor() );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	Color aColor( rColor );

	if( mnDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
					   DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE |
                       DRAWMODE_SETTINGSLINE ) )
	{
		if( !ImplIsColorTransparent( aColor ) )
		{
			if( mnDrawMode & DRAWMODE_BLACKLINE )
			{
				aColor = Color( COL_BLACK );
			}
			else if( mnDrawMode & DRAWMODE_WHITELINE )
			{
				aColor = Color( COL_WHITE );
			}
			else if( mnDrawMode & DRAWMODE_GRAYLINE )
			{
				const sal_uInt8 cLum = aColor.GetLuminance();
				aColor = Color( cLum, cLum, cLum );
			}
            else if( mnDrawMode & DRAWMODE_SETTINGSLINE )
            {
                aColor = GetSettings().GetStyleSettings().GetFontColor();
            }

			if( mnDrawMode & DRAWMODE_GHOSTEDLINE )
			{
				aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
								( aColor.GetGreen() >> 1 ) | 0x80,
								( aColor.GetBlue() >> 1 ) | 0x80);
			}
		}
	}

	if( mpMetaFile )
		mpMetaFile->AddAction( new MetaLineColorAction( aColor, sal_True ) );

	if( ImplIsColorTransparent( aColor ) )
	{
		if ( mbLineColor )
		{
			mbInitLineColor = sal_True;
			mbLineColor = sal_False;
			maLineColor = Color( COL_TRANSPARENT );
		}
	}
	else
	{
		if( maLineColor != aColor )
		{
			mbInitLineColor = sal_True;
			mbLineColor = sal_True;
			maLineColor = aColor;
		}
	}

    if( mpAlphaVDev )
        mpAlphaVDev->SetLineColor( COL_BLACK );
}

// -----------------------------------------------------------------------

void OutputDevice::SetFillColor()
{
	DBG_TRACE( "OutputDevice::SetFillColor()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaFillColorAction( Color(), sal_False ) );

	if ( mbFillColor )
	{
		mbInitFillColor = sal_True;
		mbFillColor = sal_False;
		maFillColor = Color( COL_TRANSPARENT );
	}

    if( mpAlphaVDev )
        mpAlphaVDev->SetFillColor();
}

// -----------------------------------------------------------------------

void OutputDevice::SetFillColor( const Color& rColor )
{
	DBG_TRACE1( "OutputDevice::SetFillColor( %lx )", rColor.GetColor() );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	Color aColor( rColor );

	if( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL |
					   DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
					   DRAWMODE_GHOSTEDFILL | DRAWMODE_SETTINGSFILL ) )
	{
		if( !ImplIsColorTransparent( aColor ) )
		{
			if( mnDrawMode & DRAWMODE_BLACKFILL )
			{
				aColor = Color( COL_BLACK );
			}
			else if( mnDrawMode & DRAWMODE_WHITEFILL )
			{
				aColor = Color( COL_WHITE );
			}
			else if( mnDrawMode & DRAWMODE_GRAYFILL )
			{
				const sal_uInt8 cLum = aColor.GetLuminance();
				aColor = Color( cLum, cLum, cLum );
			}
			else if( mnDrawMode & DRAWMODE_NOFILL )
			{
				aColor = Color( COL_TRANSPARENT );
			}
            else if( mnDrawMode & DRAWMODE_SETTINGSFILL )
            {
                aColor = GetSettings().GetStyleSettings().GetWindowColor();
            }

			if( mnDrawMode & DRAWMODE_GHOSTEDFILL )
			{
				aColor = Color( (aColor.GetRed() >> 1) | 0x80,
								(aColor.GetGreen() >> 1) | 0x80,
								(aColor.GetBlue() >> 1) | 0x80);
			}
		}
	}

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaFillColorAction( aColor, sal_True ) );

	if ( ImplIsColorTransparent( aColor ) )
	{
		if ( mbFillColor )
		{
			mbInitFillColor = sal_True;
			mbFillColor = sal_False;
			maFillColor = Color( COL_TRANSPARENT );
		}
	}
	else
	{
		if ( maFillColor != aColor )
		{
			mbInitFillColor = sal_True;
			mbFillColor = sal_True;
			maFillColor = aColor;
		}
	}

    if( mpAlphaVDev )
        mpAlphaVDev->SetFillColor( COL_BLACK );
}

// -----------------------------------------------------------------------

void OutputDevice::SetBackground()
{
	DBG_TRACE( "OutputDevice::SetBackground()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	maBackground = Wallpaper();
	mbBackground = sal_False;

    if( mpAlphaVDev )
        mpAlphaVDev->SetBackground();
}

// -----------------------------------------------------------------------

void OutputDevice::SetBackground( const Wallpaper& rBackground )
{
	DBG_TRACE( "OutputDevice::SetBackground( rBackground )" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	maBackground = rBackground;

	if( rBackground.GetStyle() == WALLPAPER_NULL )
		mbBackground = sal_False;
	else
		mbBackground = sal_True;

    if( mpAlphaVDev )
        mpAlphaVDev->SetBackground( rBackground );
}

// -----------------------------------------------------------------------

void OutputDevice::SetRefPoint()
{
	DBG_TRACE( "OutputDevice::SetRefPoint()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaRefPointAction( Point(), sal_False ) );

	mbRefPoint = sal_False;
	maRefPoint.X() = maRefPoint.Y() = 0L;

    if( mpAlphaVDev )
        mpAlphaVDev->SetRefPoint();
}

// -----------------------------------------------------------------------

void OutputDevice::SetRefPoint( const Point& rRefPoint )
{
	DBG_TRACE( "OutputDevice::SetRefPoint( rRefPoint )" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, sal_True ) );

	mbRefPoint = sal_True;
	maRefPoint = rRefPoint;

    if( mpAlphaVDev )
        mpAlphaVDev->SetRefPoint( rRefPoint );
}

// -----------------------------------------------------------------------

void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
{
	DBG_TRACE( "OutputDevice::DrawLine()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) );

	if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
		return;

	if ( !mpGraphics )
	{
		if ( !ImplGetGraphics() )
			return;
	}

	if ( mbInitClipRegion )
		ImplInitClipRegion();
	if ( mbOutputClipped )
		return;

	if ( mbInitLineColor )
		ImplInitLineColor();

	// #i101598# support AA and snap for lines, too
	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
		&& ROP_OVERPAINT == GetRasterOp()
		&& IsLineColor())
	{
		// at least transform with double precision to device coordinates; this will
		// avoid pixel snap of single, appended lines
		const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
        const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
		basegfx::B2DPolygon aB2DPolyLine;

		aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y()));
		aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y()));
		aB2DPolyLine.transform( aTransform );

        if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
        {
            aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
        }

		if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this))
		{
			return;
		}
	}

	const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
	const Point aEndPt(ImplLogicToDevicePixel(rEndPt));

	mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );

    if( mpAlphaVDev )
        mpAlphaVDev->DrawLine( rStartPt, rEndPt );
}

// -----------------------------------------------------------------------

void OutputDevice::impPaintLineGeometryWithEvtlExpand(
    const LineInfo& rInfo,
    basegfx::B2DPolyPolygon aLinePolyPolygon)
{
    const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
        && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
        && ROP_OVERPAINT == GetRasterOp()
        && IsLineColor());
    basegfx::B2DPolyPolygon aFillPolyPolygon;
    const bool bDashUsed(LINE_DASH == rInfo.GetStyle());
    const bool bLineWidthUsed(rInfo.GetWidth() > 1);

    if(bDashUsed && aLinePolyPolygon.count())
    {
        ::std::vector< double > fDotDashArray;
        const double fDashLen(rInfo.GetDashLen());
        const double fDotLen(rInfo.GetDotLen());
        const double fDistance(rInfo.GetDistance());

        for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++)
        {
            fDotDashArray.push_back(fDashLen);
            fDotDashArray.push_back(fDistance);
        }

        for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
        {
            fDotDashArray.push_back(fDotLen);
            fDotDashArray.push_back(fDistance);
        }

        const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));

        if(fAccumulated > 0.0)
        {
            basegfx::B2DPolyPolygon aResult;

            for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++)
            {
                basegfx::B2DPolyPolygon aLineTraget;
                basegfx::tools::applyLineDashing(
                    aLinePolyPolygon.getB2DPolygon(c),
                    fDotDashArray,
                    &aLineTraget);
                aResult.append(aLineTraget);
            }

            aLinePolyPolygon = aResult;
        }
    }

    if(bLineWidthUsed && aLinePolyPolygon.count())
    {
	    const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);

		if(aLinePolyPolygon.areControlPointsUsed())
		{
			// #i110768# When area geometry has to be created, do not
			// use the fallback bezier decomposition inside createAreaGeometry,
			// but one that is at least as good as ImplSubdivideBezier was.
			// There, Polygon::AdaptiveSubdivide was used with default parameter 
			// 1.0 as quality index.
			aLinePolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0);
		}
        
        for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
        {
	        aFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
                aLinePolyPolygon.getB2DPolygon(a), 
                fHalfLineWidth, 
                rInfo.GetLineJoin(),
                rInfo.GetLineCap()));
        }
        
        aLinePolyPolygon.clear();
    }

    GDIMetaFile* pOldMetaFile = mpMetaFile;
    mpMetaFile = NULL;

    if(aLinePolyPolygon.count())
    {
        for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
        {
            const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
            bool bDone(false);

            if(bTryAA)
            {
                bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this);
            }

            if(!bDone)
            {
                const Polygon aPolygon(aCandidate);
		        mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
            }
        }
    }

    if(aFillPolyPolygon.count())
    {
        const Color 	aOldLineColor( maLineColor );
        const Color 	aOldFillColor( maFillColor );

        SetLineColor();
        ImplInitLineColor();
        SetFillColor( aOldLineColor );
        ImplInitFillColor();

        bool bDone(false);
        
        if(bTryAA)
        {
            bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this);
        }

        if(!bDone)
        {
            for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
            {
                Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));

                // need to subdivide, mpGraphics->DrawPolygon ignores curves
                aPolygon.AdaptiveSubdivide(aPolygon);
			    mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
            }
        }
        
        SetFillColor( aOldFillColor );
        SetLineColor( aOldLineColor );
    }

    mpMetaFile = pOldMetaFile;
}

// -----------------------------------------------------------------------

void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
							 const LineInfo& rLineInfo )
{
	DBG_TRACE( "OutputDevice::DrawLine()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( rLineInfo.IsDefault() )
	{
		DrawLine( rStartPt, rEndPt );
		return;
	}

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );

	if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
		return;

	if( !mpGraphics && !ImplGetGraphics() )
		return;

	if ( mbInitClipRegion )
		ImplInitClipRegion();

	if ( mbOutputClipped )
		return;

	const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
	const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
	const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
    const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
    const bool bLineWidthUsed(aInfo.GetWidth() > 1);

    if ( mbInitLineColor )
        ImplInitLineColor();

    if(bDashUsed || bLineWidthUsed)
    {
        basegfx::B2DPolygon aLinePolygon;
        aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y()));
        aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y()));

        impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon));
    }
	else
	{
		mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
	}

    if( mpAlphaVDev )
        mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo );
}

// -----------------------------------------------------------------------

void OutputDevice::DrawRect( const Rectangle& rRect )
{
	DBG_TRACE( "OutputDevice::DrawRect()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaRectAction( rRect ) );

	if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
		return;

	Rectangle aRect( ImplLogicToDevicePixel( rRect ) );

	if ( aRect.IsEmpty() )
		return;
	aRect.Justify();

	if ( !mpGraphics )
	{
		if ( !ImplGetGraphics() )
			return;
	}

	if ( mbInitClipRegion )
		ImplInitClipRegion();
	if ( mbOutputClipped )
		return;

	if ( mbInitLineColor )
		ImplInitLineColor();
	if ( mbInitFillColor )
		ImplInitFillColor();

	mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );

    if( mpAlphaVDev )
        mpAlphaVDev->DrawRect( rRect );
}

// -----------------------------------------------------------------------

void OutputDevice::DrawPolyLine( const Polygon& rPoly )
{
	DBG_TRACE( "OutputDevice::DrawPolyLine()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
	DBG_CHKOBJ( &rPoly, Polygon, NULL );

	if( mpMetaFile )
		mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );

	sal_uInt16 nPoints = rPoly.GetSize();

	if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() )
		return;

	// we need a graphics
	if ( !mpGraphics )
		if ( !ImplGetGraphics() )
			return;

	if ( mbInitClipRegion )
		ImplInitClipRegion();
	if ( mbOutputClipped )
		return;

	if ( mbInitLineColor )
		ImplInitLineColor();

    const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
        && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
        && ROP_OVERPAINT == GetRasterOp()
        && IsLineColor());

	// use b2dpolygon drawing if possible
	if(bTryAA && ImpTryDrawPolyLineDirect(rPoly.getB2DPolygon()))
	{
		basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon());
		const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
        const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );

        // transform the polygon
		aB2DPolyLine.transform( aTransform );

        if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
        {
            aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
        }

		if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this))
		{
			return;
		}
	}

	Polygon aPoly = ImplLogicToDevicePixel( rPoly );
    const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();

    // #100127# Forward beziers to sal, if any
    if( aPoly.HasFlags() )
    {
        const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
        if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, this ) )
        {
            aPoly = ImplSubdivideBezier(aPoly);
            pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
            mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, this );
        }
    }
    else
    {
        mpGraphics->DrawPolyLine( nPoints, pPtAry, this );
    }

    if( mpAlphaVDev )
        mpAlphaVDev->DrawPolyLine( rPoly );
}

// -----------------------------------------------------------------------

void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo )
{
	DBG_TRACE( "OutputDevice::DrawPolyLine()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
	DBG_CHKOBJ( &rPoly, Polygon, NULL );

	if ( rLineInfo.IsDefault() )
	{
		DrawPolyLine( rPoly );
		return;
	}

    // #i101491#
    // Try direct Fallback to B2D-Version of DrawPolyLine
    if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
        && LINE_SOLID == rLineInfo.GetStyle())
    {
		DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap());
		return;
    }

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );

    ImpDrawPolyLineWithLineInfo(rPoly, rLineInfo);
}

void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
{
	sal_uInt16 nPoints(rPoly.GetSize());

	if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
		return;

    Polygon aPoly = ImplLogicToDevicePixel( rPoly );

    // #100127# LineInfo is not curve-safe, subdivide always
    // 
    // What shall this mean? It's wrong to subdivide here when the
    // polygon is a fat line. In that case, the painted geometry
    // WILL be much different.
    // I also have no idea how this could be related to the given ID
    // which reads 'consolidate boost versions' in the task description.
    // Removing.
    //
    //if( aPoly.HasFlags() )
    //{
    //    aPoly = ImplSubdivideBezier( aPoly );
    //    nPoints = aPoly.GetSize();
    //}

	// we need a graphics
	if ( !mpGraphics && !ImplGetGraphics() )
		return;

	if ( mbInitClipRegion )
		ImplInitClipRegion();

	if ( mbOutputClipped )
		return;

	if ( mbInitLineColor )
		ImplInitLineColor();

    const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
    const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
    const bool bLineWidthUsed(aInfo.GetWidth() > 1);

    if(bDashUsed || bLineWidthUsed)
    {
        impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon()));
    }
    else
    {
        // #100127# the subdivision HAS to be done here since only a pointer
        // to an array of points is given to the DrawPolyLine method, there is
        // NO way to find out there that it's a curve.
        if( aPoly.HasFlags() )
        {
            aPoly = ImplSubdivideBezier( aPoly );
            nPoints = aPoly.GetSize();
        }
		
        mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this);
    }

    if( mpAlphaVDev )
        mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
}

// -----------------------------------------------------------------------

void OutputDevice::DrawPolygon( const Polygon& rPoly )
{
	DBG_TRACE( "OutputDevice::DrawPolygon()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
	DBG_CHKOBJ( &rPoly, Polygon, NULL );

	if( mpMetaFile )
		mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );

	sal_uInt16 nPoints = rPoly.GetSize();

	if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
		return;

	// we need a graphics
	if ( !mpGraphics )
		if ( !ImplGetGraphics() )
			return;

	if ( mbInitClipRegion )
		ImplInitClipRegion();
	if ( mbOutputClipped )
		return;

	if ( mbInitLineColor )
		ImplInitLineColor();
	if ( mbInitFillColor )
		ImplInitFillColor();

	// use b2dpolygon drawing if possible
	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
		&& ROP_OVERPAINT == GetRasterOp()
		&& (IsLineColor() || IsFillColor()))
	{
		const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
		basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
		bool bSuccess(true);

        // transform the polygon and ensure closed
		aB2DPolygon.transform(aTransform);
        aB2DPolygon.setClosed(true);

		if(IsFillColor())
		{
			bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
		}

		if(bSuccess && IsLineColor())
		{
			const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );

			if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
			{
				aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
			}

			bSuccess = mpGraphics->DrawPolyLine( 
                aB2DPolygon, 
                0.0, 
                aB2DLineWidth, 
                basegfx::B2DLINEJOIN_NONE, 
                com::sun::star::drawing::LineCap_BUTT,
                this);
		}

		if(bSuccess)
		{
			return;
		}
	}

	Polygon aPoly = ImplLogicToDevicePixel( rPoly );
	const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();

    // #100127# Forward beziers to sal, if any
    if( aPoly.HasFlags() )
    {
        const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
        if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
        {
            aPoly = ImplSubdivideBezier(aPoly);
            pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
            mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
        }
    }
    else
    {
        mpGraphics->DrawPolygon( nPoints, pPtAry, this );
    }
    if( mpAlphaVDev )
        mpAlphaVDev->DrawPolygon( rPoly );
}

// -----------------------------------------------------------------------

void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
{
	DBG_TRACE( "OutputDevice::DrawPolyPolygon()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
	DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );

	if( mpMetaFile )
		mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );

	sal_uInt16 nPoly = rPolyPoly.Count();

	if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
		return;

	// we need a graphics
	if ( !mpGraphics )
		if ( !ImplGetGraphics() )
			return;

	if ( mbInitClipRegion )
		ImplInitClipRegion();
	if ( mbOutputClipped )
		return;

	if ( mbInitLineColor )
		ImplInitLineColor();
	if ( mbInitFillColor )
		ImplInitFillColor();

	// use b2dpolygon drawing if possible
	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
		&& ROP_OVERPAINT == GetRasterOp()
		&& (IsLineColor() || IsFillColor()))
	{
		const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
		basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
		bool bSuccess(true);

		// transform the polygon and ensure closed
		aB2DPolyPolygon.transform(aTransform);
        aB2DPolyPolygon.setClosed(true);

		if(IsFillColor())
		{
			bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
		}

		if(bSuccess && IsLineColor())
		{
			const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );

			if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
			{
				aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
			}

			for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
			{
				bSuccess = mpGraphics->DrawPolyLine( 
                    aB2DPolyPolygon.getB2DPolygon(a), 
                    0.0, 
                    aB2DLineWidth, 
                    basegfx::B2DLINEJOIN_NONE, 
                    com::sun::star::drawing::LineCap_BUTT,
                    this);
			}
		}

		if(bSuccess)
		{
			return;
		}
	}

	if ( nPoly == 1 )
	{
        // #100127# Map to DrawPolygon
        Polygon aPoly = rPolyPoly.GetObject( 0 );
		if( aPoly.GetSize() >= 2 )
        {
            GDIMetaFile* pOldMF = mpMetaFile;
            mpMetaFile = NULL;

			DrawPolygon( aPoly );

            mpMetaFile = pOldMF;
        }
	}
	else
	{
        // #100127# moved real PolyPolygon draw to separate method,
        // have to call recursively, avoiding duplicate
        // ImplLogicToDevicePixel calls
        ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
	}
    if( mpAlphaVDev )
        mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
}

// -----------------------------------------------------------------------

void OutputDevice::DrawPolygon( const ::basegfx::B2DPolygon& rB2DPolygon)
{
    // AW: Do NOT paint empty polygons
    if(rB2DPolygon.count())
    {
        ::basegfx::B2DPolyPolygon aPP( rB2DPolygon );
        DrawPolyPolygon( aPP );
    }
}

// -----------------------------------------------------------------------
// Caution: This method is nearly the same as
// OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
// so when changes are made here do not forget to make change sthere, too

void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
{
	DBG_TRACE( "OutputDevice::DrawPolyPolygon(B2D&)" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

#if 0
    // MetaB2DPolyPolygonAction is not implemented yet:
    // according to AW adding it is very dangerous since there is a lot
    // of code that uses the metafile actions directly and unless every
    // place that does this knows about the new action we need to fallback
    if( mpMetaFile )
        mpMetaFile->AddAction( new MetaB2DPolyPolygonAction( rB2DPolyPoly ) );
#else
    if( mpMetaFile )
        mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
#endif

	// call helper
	ImpDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
}

void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
{
    // AW: Do NOT paint empty PolyPolygons
    if(!rB2DPolyPoly.count())
        return;

    // we need a graphics
    if( !mpGraphics )
	    if( !ImplGetGraphics() )
		    return;

    if( mbInitClipRegion )
	    ImplInitClipRegion();
    if( mbOutputClipped )
	    return;

    if( mbInitLineColor )
	    ImplInitLineColor();
    if( mbInitFillColor )
	    ImplInitFillColor();

	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
		&& ROP_OVERPAINT == GetRasterOp()
		&& (IsLineColor() || IsFillColor()))
    {
		const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
		basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
		bool bSuccess(true);

		// transform the polygon and ensure closed
		aB2DPolyPolygon.transform(aTransform);
        aB2DPolyPolygon.setClosed(true);

		if(IsFillColor())
		{
			bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
		}

		if(bSuccess && IsLineColor())
		{
			const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );

			if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
			{
				aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
			}

			for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
			{
				bSuccess = mpGraphics->DrawPolyLine( 
                    aB2DPolyPolygon.getB2DPolygon(a), 
                    0.0, 
                    aB2DLineWidth, 
                    basegfx::B2DLINEJOIN_NONE, 
                    com::sun::star::drawing::LineCap_BUTT,
                    this);
			}
		}

		if(bSuccess)
		{
			return;
		}
    }

    // fallback to old polygon drawing if needed
    const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
    const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
    ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon );
}

// -----------------------------------------------------------------------

bool OutputDevice::ImpTryDrawPolyLineDirect(
	const basegfx::B2DPolygon& rB2DPolygon,
    double fLineWidth,
    double fTransparency,
    basegfx::B2DLineJoin eLineJoin,
    com::sun::star::drawing::LineCap eLineCap)
{
    const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
    basegfx::B2DVector aB2DLineWidth(1.0, 1.0);
    
	// transform the line width if used
    if( fLineWidth != 0.0 )
	{
        aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
	}

    // transform the polygon
    basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
    aB2DPolygon.transform(aTransform);
    
    if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) 
		&& aB2DPolygon.count() < 1000)
    {
		// #i98289#, #i101491#
        // better to remove doubles on device coordinates. Also assume from a given amount
        // of points that the single edges are not long enough to smooth
        aB2DPolygon.removeDoublePoints();
        aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
    }

    // draw the polyline
    return mpGraphics->DrawPolyLine( 
        aB2DPolygon, 
        fTransparency, 
        aB2DLineWidth, 
        eLineJoin, 
        eLineCap,
        this);
}

bool OutputDevice::TryDrawPolyLineDirect(
    const basegfx::B2DPolygon& rB2DPolygon, 
    double fLineWidth, 
    double fTransparency,
    basegfx::B2DLineJoin eLineJoin,
    com::sun::star::drawing::LineCap eLineCap)
{
    // AW: Do NOT paint empty PolyPolygons
    if(!rB2DPolygon.count())
        return true;

    // we need a graphics
    if( !mpGraphics )
        if( !ImplGetGraphics() )
            return false;

    if( mbInitClipRegion )
        ImplInitClipRegion();

    if( mbOutputClipped )
        return true;

    if( mbInitLineColor )
        ImplInitLineColor();

    const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
        && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
        && ROP_OVERPAINT == GetRasterOp()
        && IsLineColor());

    if(bTryAA)
    {
        if(ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, fTransparency, eLineJoin, eLineCap))
        {
            // worked, add metafile action (if recorded) and return true
            if( mpMetaFile )
            {
                LineInfo aLineInfo;
                if( fLineWidth != 0.0 )
                    aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
                const Polygon aToolsPolygon( rB2DPolygon );
                mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
            }

            return true;
        }
    }

    return false;
}

void OutputDevice::DrawPolyLine(
    const basegfx::B2DPolygon& rB2DPolygon,
    double fLineWidth,
    basegfx::B2DLineJoin eLineJoin,
    com::sun::star::drawing::LineCap eLineCap)
{
	DBG_TRACE( "OutputDevice::DrawPolyLine(B2D&)" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

#if 0 // MetaB2DPolyLineAction is not implemented yet:
      // according to AW adding it is very dangerous since there is a lot
      // of code that uses the metafile actions directly and unless every
      // place that does this knows about the new action we need to fallback
    if( mpMetaFile )
        mpMetaFile->AddAction( new MetaB2DPolyLineAction( rB2DPolygon ) );
#else
    if( mpMetaFile )
    {
        LineInfo aLineInfo;
        if( fLineWidth != 0.0 )
            aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
        const Polygon aToolsPolygon( rB2DPolygon );
        mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
    }
#endif

    // AW: Do NOT paint empty PolyPolygons
    if(!rB2DPolygon.count())
        return;

    // we need a graphics
	if( !mpGraphics )
		if( !ImplGetGraphics() )
			return;

	if( mbInitClipRegion )
		ImplInitClipRegion();
	if( mbOutputClipped )
		return;

	if( mbInitLineColor )
		ImplInitLineColor();

    const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 
        && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
        && ROP_OVERPAINT == GetRasterOp()
        && IsLineColor());

	// use b2dpolygon drawing if possible
	if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap))
	{
		return;
	}

	// #i101491#
	// no output yet; fallback to geometry decomposition and use filled polygon paint
	// when line is fat and not too complex. ImpDrawPolyPolygonWithB2DPolyPolygon
	// will do internal needed AA checks etc.
	if(fLineWidth >= 2.5 
		&& rB2DPolygon.count()
		&& rB2DPolygon.count() <= 1000)
	{
		const double fHalfLineWidth((fLineWidth * 0.5) + 0.5);
		const basegfx::B2DPolyPolygon aAreaPolyPolygon(
            basegfx::tools::createAreaGeometry(
			    rB2DPolygon, 
                fHalfLineWidth, 
                eLineJoin,
                eLineCap));
		const Color aOldLineColor(maLineColor);
		const Color aOldFillColor(maFillColor);

		SetLineColor();
		ImplInitLineColor();
		SetFillColor(aOldLineColor);
		ImplInitFillColor();

		// draw usig a loop; else the topology will paint a PolyPolygon
		for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
		{
			ImpDrawPolyPolygonWithB2DPolyPolygon(
				basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a)));
		}

        SetLineColor(aOldLineColor);
		ImplInitLineColor();
		SetFillColor(aOldFillColor);
		ImplInitFillColor();

		if(bTryAA)
		{
			// when AA it is necessary to also paint the filled polygon's outline
			// to avoid optical gaps
			for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
			{
				ImpTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a));
			}
		}
	}
	else
	{
		// fallback to old polygon drawing if needed
		const Polygon aToolsPolygon( rB2DPolygon );
		LineInfo aLineInfo;
		if( fLineWidth != 0.0 )
			aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
		ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
	}
}

// -----------------------------------------------------------------------

sal_uInt32 OutputDevice::GetGCStackDepth() const
{
    const ImplObjStack* pData = mpObjStack;
    sal_uInt32 nDepth = 0;
    while( pData )
    {
        nDepth++;
        pData = pData->mpPrev;
    }
    return nDepth;
}

// -----------------------------------------------------------------------

void OutputDevice::Push( sal_uInt16 nFlags )
{
	DBG_TRACE( "OutputDevice::Push()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaPushAction( nFlags ) );

	ImplObjStack* pData = new ImplObjStack;
	pData->mpPrev = mpObjStack;
	mpObjStack = pData;

	pData->mnFlags = nFlags;

	if ( nFlags & PUSH_LINECOLOR )
	{
		if ( mbLineColor )
			pData->mpLineColor = new Color( maLineColor );
		else
			pData->mpLineColor = NULL;
	}
	if ( nFlags & PUSH_FILLCOLOR )
	{
		if ( mbFillColor )
			pData->mpFillColor = new Color( maFillColor );
		else
			pData->mpFillColor = NULL;
	}
	if ( nFlags & PUSH_FONT )
		pData->mpFont = new Font( maFont );
	if ( nFlags & PUSH_TEXTCOLOR )
		pData->mpTextColor = new Color( GetTextColor() );
	if ( nFlags & PUSH_TEXTFILLCOLOR )
	{
		if ( IsTextFillColor() )
			pData->mpTextFillColor = new Color( GetTextFillColor() );
		else
			pData->mpTextFillColor = NULL;
	}
	if ( nFlags & PUSH_TEXTLINECOLOR )
	{
		if ( IsTextLineColor() )
			pData->mpTextLineColor = new Color( GetTextLineColor() );
		else
			pData->mpTextLineColor = NULL;
	}
	if ( nFlags & PUSH_OVERLINECOLOR )
	{
		if ( IsOverlineColor() )
			pData->mpOverlineColor = new Color( GetOverlineColor() );
		else
			pData->mpOverlineColor = NULL;
	}
	if ( nFlags & PUSH_TEXTALIGN )
		pData->meTextAlign = GetTextAlign();
	if( nFlags & PUSH_TEXTLAYOUTMODE )
		pData->mnTextLayoutMode = GetLayoutMode();
	if( nFlags & PUSH_TEXTLANGUAGE )
		pData->meTextLanguage = GetDigitLanguage();
	if ( nFlags & PUSH_RASTEROP )
		pData->meRasterOp = GetRasterOp();
	if ( nFlags & PUSH_MAPMODE )
	{
		pData->mpMapMode = new MapMode( maMapMode );
        pData->mbMapActive = mbMap;
	}
	if ( nFlags & PUSH_CLIPREGION )
	{
		if ( mbClipRegion )
			pData->mpClipRegion = new Region( maRegion );
		else
			pData->mpClipRegion = NULL;
	}
	if ( nFlags & PUSH_REFPOINT )
	{
		if ( mbRefPoint )
			pData->mpRefPoint = new Point( maRefPoint );
		else
			pData->mpRefPoint = NULL;
	}

    if( mpAlphaVDev )
        mpAlphaVDev->Push();
}

// -----------------------------------------------------------------------

void OutputDevice::Pop()
{
	DBG_TRACE( "OutputDevice::Pop()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if( mpMetaFile )
		mpMetaFile->AddAction( new MetaPopAction() );

	GDIMetaFile*	pOldMetaFile = mpMetaFile;
	ImplObjStack*	pData = mpObjStack;
	mpMetaFile = NULL;

	if ( !pData )
	{
		DBG_ERRORFILE( "OutputDevice::Pop() without OutputDevice::Push()" );
		return;
	}

    if( mpAlphaVDev )
        mpAlphaVDev->Pop();

	mpObjStack = pData->mpPrev;

	if ( pData->mnFlags & PUSH_LINECOLOR )
	{
		if ( pData->mpLineColor )
			SetLineColor( *pData->mpLineColor );
		else
			SetLineColor();
	}
	if ( pData->mnFlags & PUSH_FILLCOLOR )
	{
		if ( pData->mpFillColor )
			SetFillColor( *pData->mpFillColor );
		else
			SetFillColor();
	}
	if ( pData->mnFlags & PUSH_FONT )
		SetFont( *pData->mpFont );
	if ( pData->mnFlags & PUSH_TEXTCOLOR )
		SetTextColor( *pData->mpTextColor );
	if ( pData->mnFlags & PUSH_TEXTFILLCOLOR )
	{
		if ( pData->mpTextFillColor )
			SetTextFillColor( *pData->mpTextFillColor );
		else
			SetTextFillColor();
	}
	if ( pData->mnFlags & PUSH_TEXTLINECOLOR )
	{
		if ( pData->mpTextLineColor )
			SetTextLineColor( *pData->mpTextLineColor );
		else
			SetTextLineColor();
	}
	if ( pData->mnFlags & PUSH_OVERLINECOLOR )
	{
		if ( pData->mpOverlineColor )
			SetOverlineColor( *pData->mpOverlineColor );
		else
			SetOverlineColor();
	}
	if ( pData->mnFlags & PUSH_TEXTALIGN )
		SetTextAlign( pData->meTextAlign );
	if( pData->mnFlags & PUSH_TEXTLAYOUTMODE )
		SetLayoutMode( pData->mnTextLayoutMode );
	if( pData->mnFlags & PUSH_TEXTLANGUAGE )
		SetDigitLanguage( pData->meTextLanguage );
	if ( pData->mnFlags & PUSH_RASTEROP )
		SetRasterOp( pData->meRasterOp );
	if ( pData->mnFlags & PUSH_MAPMODE )
	{
		if ( pData->mpMapMode )
			SetMapMode( *pData->mpMapMode );
		else
			SetMapMode();
        mbMap = pData->mbMapActive;
	}
	if ( pData->mnFlags & PUSH_CLIPREGION )
		ImplSetClipRegion( pData->mpClipRegion );
	if ( pData->mnFlags & PUSH_REFPOINT )
	{
		if ( pData->mpRefPoint )
			SetRefPoint( *pData->mpRefPoint );
		else
			SetRefPoint();
	}

	ImplDeleteObjStack( pData );

	mpMetaFile = pOldMetaFile;
}

// -----------------------------------------------------------------------

void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
{
    mpMetaFile = pMtf;
}

// -----------------------------------------------------------------------

void OutputDevice::EnableOutput( sal_Bool bEnable )
{
    mbOutput = (bEnable != 0);

    if( mpAlphaVDev )
        mpAlphaVDev->EnableOutput( bEnable );
}

// -----------------------------------------------------------------------

void OutputDevice::SetSettings( const AllSettings& rSettings )
{
    maSettings = rSettings;

    if( mpAlphaVDev )
        mpAlphaVDev->SetSettings( rSettings );
}

// -----------------------------------------------------------------------

sal_uInt16 OutputDevice::GetBitCount() const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( meOutDevType == OUTDEV_VIRDEV )
		return ((VirtualDevice*)this)->mnBitCount;

	// we need a graphics
	if ( !mpGraphics )
	{
		if ( !((OutputDevice*)this)->ImplGetGraphics() )
			return 0;
	}

	return (sal_uInt16)mpGraphics->GetBitCount();
}

// -----------------------------------------------------------------------

sal_uInt16 OutputDevice::GetAlphaBitCount() const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( meOutDevType == OUTDEV_VIRDEV &&
        mpAlphaVDev != NULL )
    {
		return mpAlphaVDev->GetBitCount();
    }

    return 0;
}

// -----------------------------------------------------------------------

sal_uLong OutputDevice::GetColorCount() const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	const sal_uInt16 nBitCount = GetBitCount();
	return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) );
}

// -----------------------------------------------------------------------

sal_Bool OutputDevice::HasAlpha()
{
    return mpAlphaVDev != NULL;
}

// -----------------------------------------------------------------------

::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > OutputDevice::CreateUnoGraphics()
{
	UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
	return pWrapper ? pWrapper->CreateGraphics( this ) : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >();
}

// -----------------------------------------------------------------------

SystemGraphicsData OutputDevice::GetSystemGfxData() const
{
	if ( !mpGraphics )
	{
		if ( !ImplGetGraphics() )
			return SystemGraphicsData();
	}

    return mpGraphics->GetGraphicsData();
}

// -----------------------------------------------------------------------

::com::sun::star::uno::Any OutputDevice::GetSystemGfxDataAny() const
{
    ::com::sun::star::uno::Any aRet;
    const SystemGraphicsData aSysData = GetSystemGfxData();
    ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)&aSysData,
                                                      aSysData.nSize );

    return uno::makeAny(aSeq);
}

// -----------------------------------------------------------------------

::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > OutputDevice::GetCanvas() const
{
    uno::Sequence< uno::Any > aArg(6);

    aArg[ 0 ] = uno::makeAny( reinterpret_cast<sal_Int64>(this) );
    aArg[ 2 ] = uno::makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
    aArg[ 3 ] = uno::makeAny( sal_False );
    aArg[ 5 ] = GetSystemGfxDataAny();

    uno::Reference<lang::XMultiServiceFactory> xFactory = vcl::unohelper::GetMultiServiceFactory();

    uno::Reference<rendering::XCanvas> xCanvas;

    // Create canvas instance with window handle
    // =========================================
    if ( xFactory.is() )
    {
        static uno::Reference<lang::XMultiServiceFactory> xCanvasFactory(
            xFactory->createInstance(
                OUString( RTL_CONSTASCII_USTRINGPARAM(
                              "com.sun.star."
                              "rendering.CanvasFactory") ) ),
            uno::UNO_QUERY );
        if(xCanvasFactory.is())
        {
            xCanvas.set(
                xCanvasFactory->createInstanceWithArguments(
                    OUString( RTL_CONSTASCII_USTRINGPARAM(
                                  "com.sun.star.rendering.Canvas" )),
                    aArg ),
                uno::UNO_QUERY );
        }
    }

    return xCanvas;
}

// -----------------------------------------------------------------------
