/**************************************************************
 * 
 * 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/debug.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/window.hxx>
#include <vcl/metaact.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/virdev.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/outdev.hxx>
#include <vcl/window.hxx>
#include <vcl/image.hxx>
#include <bmpfast.hxx>
#include <salbmp.hxx>
#include <salgdi.hxx>
#include <impbmp.hxx>
#include <sallayout.hxx>
#include <image.h>
#include <outdev.h>
#include <window.h>
#include <outdata.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>

#define BAND_MAX_SIZE 512000

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

DBG_NAMEEX( OutputDevice )

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

// -----------
// - Defines -
// -----------

#define OUTDEV_INIT()						\
{											\
	if ( !IsDeviceOutputNecessary() )		\
		return; 							\
											\
	if ( !mpGraphics )						\
		if ( !ImplGetGraphics() )			\
			return; 						\
											\
	if ( mbInitClipRegion ) 				\
		ImplInitClipRegion();				\
											\
	if ( mbOutputClipped )					\
		return; 							\
}

// -------------
// - externals -
// -------------

extern sal_uLong nVCLRLut[ 6 ];
extern sal_uLong nVCLGLut[ 6 ];
extern sal_uLong nVCLBLut[ 6 ];
extern sal_uLong nVCLDitherLut[ 256 ];
extern sal_uLong nVCLLut[ 256 ];

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

sal_uLong ImplAdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
{
	sal_uLong nMirrFlags = 0;

	if ( rTwoRect.mnDestWidth < 0 )
	{
		rTwoRect.mnSrcX = rSizePix.Width() - rTwoRect.mnSrcX - rTwoRect.mnSrcWidth;
		rTwoRect.mnDestWidth = -rTwoRect.mnDestWidth;
		rTwoRect.mnDestX -= rTwoRect.mnDestWidth-1;
		nMirrFlags |= BMP_MIRROR_HORZ;
	}

	if ( rTwoRect.mnDestHeight < 0 )
	{
		rTwoRect.mnSrcY = rSizePix.Height() - rTwoRect.mnSrcY - rTwoRect.mnSrcHeight;
		rTwoRect.mnDestHeight = -rTwoRect.mnDestHeight;
		rTwoRect.mnDestY -= rTwoRect.mnDestHeight-1;
		nMirrFlags |= BMP_MIRROR_VERT;
	}

	if( ( rTwoRect.mnSrcX < 0 ) || ( rTwoRect.mnSrcX >= rSizePix.Width() ) ||
		( rTwoRect.mnSrcY < 0 ) || ( rTwoRect.mnSrcY >= rSizePix.Height() ) ||	
		( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rSizePix.Width() ) ||
		( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rSizePix.Height() ) )
	{
		const Rectangle	aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ), 
									 Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
		Rectangle		aCropRect( aSourceRect );

		aCropRect.Intersection( Rectangle( Point(), rSizePix ) );

		if( aCropRect.IsEmpty() )
			rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
		else
		{
			const double	fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
			const double	fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;

			const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
			const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
			const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
			const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );

			rTwoRect.mnSrcX = aCropRect.Left();
			rTwoRect.mnSrcY = aCropRect.Top();
			rTwoRect.mnSrcWidth = aCropRect.GetWidth();
			rTwoRect.mnSrcHeight = aCropRect.GetHeight();
			rTwoRect.mnDestX = nDstX1;
			rTwoRect.mnDestY = nDstY1;
			rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
			rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
		}
	}

	return nMirrFlags;
}

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

void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, SalTwoRect& rPosAry )
{
	SalGraphics*		pGraphics2;

	if ( rPosAry.mnSrcWidth && rPosAry.mnSrcHeight && rPosAry.mnDestWidth && rPosAry.mnDestHeight )
	{
		if ( this == pSrcDev )
			pGraphics2 = NULL;
		else
		{
			if ( (GetOutDevType() != pSrcDev->GetOutDevType()) ||
				 (GetOutDevType() != OUTDEV_WINDOW) )
			{
				if ( !pSrcDev->mpGraphics )
				{
					if ( !((OutputDevice*)pSrcDev)->ImplGetGraphics() )
						return;
				}
				pGraphics2 = pSrcDev->mpGraphics;
			}
			else
			{
				if ( ((Window*)this)->mpWindowImpl->mpFrameWindow == ((Window*)pSrcDev)->mpWindowImpl->mpFrameWindow )
					pGraphics2 = NULL;
				else
				{
					if ( !pSrcDev->mpGraphics )
					{
						if ( !((OutputDevice*)pSrcDev)->ImplGetGraphics() )
							return;
					}
					pGraphics2 = pSrcDev->mpGraphics;

					if ( !mpGraphics )
					{
						if ( !ImplGetGraphics() )
							return;
					}
					DBG_ASSERT( mpGraphics && pSrcDev->mpGraphics,
								"OutputDevice::DrawOutDev(): We need more than one Graphics" );
				}
			}
		}

        // #102532# Offset only has to be pseudo window offset
		Rectangle	aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ),
								 Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) );
		Rectangle	aSrcRect( Point( rPosAry.mnSrcX, rPosAry.mnSrcY ),
							  Size( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ) );
		const long	nOldRight = aSrcRect.Right();
		const long	nOldBottom = aSrcRect.Bottom();

		if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() )
		{
			if ( (rPosAry.mnSrcX+rPosAry.mnSrcWidth-1) > aSrcOutRect.Right() )
			{
				const long nOldWidth = rPosAry.mnSrcWidth;
				rPosAry.mnSrcWidth -= (nOldRight - aSrcRect.Right());
				rPosAry.mnDestWidth = rPosAry.mnDestWidth * rPosAry.mnSrcWidth / nOldWidth;
			}

			if ( (rPosAry.mnSrcY+rPosAry.mnSrcHeight-1) > aSrcOutRect.Bottom() )
			{
				const long nOldHeight = rPosAry.mnSrcHeight;
				rPosAry.mnSrcHeight -= (nOldBottom - aSrcRect.Bottom());
				rPosAry.mnDestHeight = rPosAry.mnDestHeight * rPosAry.mnSrcHeight / nOldHeight;
			}

            // --- RTL --- if this is no window, but pSrcDev is a window
            // mirroring may be required
            // because only windows have a SalGraphicsLayout
            // mirroring is performed here
            if( (GetOutDevType() != OUTDEV_WINDOW) && pGraphics2 && (pGraphics2->GetLayout() & SAL_LAYOUT_BIDI_RTL) )
            {
		        SalTwoRect aPosAry2 = rPosAry;
			    pGraphics2->mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcDev ); 
			    mpGraphics->CopyBits( aPosAry2, pGraphics2, this, pSrcDev );
            }
            else
			    mpGraphics->CopyBits( rPosAry, pGraphics2, this, pSrcDev );
		}
	}
}

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

void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
							   const Point& rSrcPt,  const Size& rSrcSize )
{
	DBG_TRACE( "OutputDevice::DrawOutDev()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
	DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );

    if( ImplIsRecordLayout() )
        return;

	if ( meOutDevType == OUTDEV_PRINTER )
		return;

	if ( ROP_INVERT == meRasterOp )
	{
		DrawRect( Rectangle( rDestPt, rDestSize ) );
		return;
	}

	if ( mpMetaFile )
	{
		const Bitmap aBmp( GetBitmap( rSrcPt, rSrcSize ) );
		mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
	}

	OUTDEV_INIT();

	SalTwoRect aPosAry;
	aPosAry.mnSrcWidth	 = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
	aPosAry.mnSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
	aPosAry.mnDestWidth  = ImplLogicWidthToDevicePixel( rDestSize.Width() );
	aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );

	if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
	{
		aPosAry.mnSrcX		 = ImplLogicXToDevicePixel( rSrcPt.X() );
		aPosAry.mnSrcY		 = ImplLogicYToDevicePixel( rSrcPt.Y() );
		aPosAry.mnDestX 	 = ImplLogicXToDevicePixel( rDestPt.X() );
		aPosAry.mnDestY 	 = ImplLogicYToDevicePixel( rDestPt.Y() );

		Rectangle	aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
								 Size( mnOutWidth, mnOutHeight ) );
		Rectangle	aSrcRect( Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
							  Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ) );
		long		nOldRight = aSrcRect.Right();
		long		nOldBottom = aSrcRect.Bottom();

		if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() )
		{
			if ( (aPosAry.mnSrcX+aPosAry.mnSrcWidth-1) > aSrcOutRect.Right() )
			{
				long nOldWidth = aPosAry.mnSrcWidth;
				aPosAry.mnSrcWidth -= nOldRight-aSrcRect.Right();
				aPosAry.mnDestWidth = aPosAry.mnDestWidth*aPosAry.mnSrcWidth/nOldWidth;
			}

			if ( (aPosAry.mnSrcY+aPosAry.mnSrcHeight-1) > aSrcOutRect.Bottom() )
			{
				long nOldHeight = aPosAry.mnSrcHeight;
				aPosAry.mnSrcHeight -= nOldBottom-aSrcRect.Bottom();
				aPosAry.mnDestHeight = aPosAry.mnDestHeight*aPosAry.mnSrcHeight/nOldHeight;
			}

			mpGraphics->CopyBits( aPosAry, NULL, this, NULL );
		}
	}

    if( mpAlphaVDev )
        mpAlphaVDev->DrawOutDev( rDestPt, rDestSize, rSrcPt, rSrcSize );
}

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

void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
							   const Point& rSrcPt,  const Size& rSrcSize,
							   const OutputDevice& rOutDev )
{
	DBG_TRACE( "OutputDevice::DrawOutDev()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
	DBG_CHKOBJ( &rOutDev, OutputDevice, ImplDbgCheckOutputDevice );
	DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
	DBG_ASSERT( rOutDev.meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );

	if ( (meOutDevType == OUTDEV_PRINTER) || (rOutDev.meOutDevType == OUTDEV_PRINTER) || ImplIsRecordLayout() )
		return;

	if ( ROP_INVERT == meRasterOp )
	{
		DrawRect( Rectangle( rDestPt, rDestSize ) );
		return;
	}

	if ( mpMetaFile )
	{
		const Bitmap aBmp( rOutDev.GetBitmap( rSrcPt, rSrcSize ) );
		mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
	}

	OUTDEV_INIT();

	SalTwoRect aPosAry;
	aPosAry.mnSrcX		 = rOutDev.ImplLogicXToDevicePixel( rSrcPt.X() );
	aPosAry.mnSrcY		 = rOutDev.ImplLogicYToDevicePixel( rSrcPt.Y() );
	aPosAry.mnSrcWidth	 = rOutDev.ImplLogicWidthToDevicePixel( rSrcSize.Width() );
	aPosAry.mnSrcHeight  = rOutDev.ImplLogicHeightToDevicePixel( rSrcSize.Height() );
	aPosAry.mnDestX 	 = ImplLogicXToDevicePixel( rDestPt.X() );
	aPosAry.mnDestY 	 = ImplLogicYToDevicePixel( rDestPt.Y() );
	aPosAry.mnDestWidth  = ImplLogicWidthToDevicePixel( rDestSize.Width() );
	aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );

    if( mpAlphaVDev )
    {
        if( rOutDev.mpAlphaVDev )
        {
            // alpha-blend source over destination
            DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );

            // This would be mode SOURCE:
            // copy source alpha channel to our alpha channel
            //mpAlphaVDev->DrawOutDev( rDestPt, rDestSize, rSrcPt, rSrcSize, *rOutDev.mpAlphaVDev );
        }
        else
        {
            ImplDrawOutDevDirect( &rOutDev, aPosAry );

            // #i32109#: make destination rectangle opaque - source has no alpha
            mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
        }
    }
    else
    {
        if( rOutDev.mpAlphaVDev )
        {
            // alpha-blend source over destination
            DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );
        }
        else
        {
            // no alpha at all, neither in source nor destination device
            ImplDrawOutDevDirect( &rOutDev, aPosAry );
        }
    }
}

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

void OutputDevice::CopyArea( const Point& rDestPt,
							 const Point& rSrcPt,  const Size& rSrcSize,
							 sal_uInt16 nFlags )
{
	DBG_TRACE( "OutputDevice::CopyArea()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
	DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::CopyArea(...) with printer devices!" );

	if ( meOutDevType == OUTDEV_PRINTER || ImplIsRecordLayout() )
		return;

	RasterOp eOldRop = GetRasterOp();
	SetRasterOp( ROP_OVERPAINT );

	OUTDEV_INIT();

	SalTwoRect aPosAry;
	aPosAry.mnSrcWidth	 = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
	aPosAry.mnSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );

	if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight )
	{
		aPosAry.mnSrcX		 = ImplLogicXToDevicePixel( rSrcPt.X() );
		aPosAry.mnSrcY		 = ImplLogicYToDevicePixel( rSrcPt.Y() );
		aPosAry.mnDestX 	 = ImplLogicXToDevicePixel( rDestPt.X() );
		aPosAry.mnDestY 	 = ImplLogicYToDevicePixel( rDestPt.Y() );

		Rectangle	aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
								 Size( mnOutWidth, mnOutHeight ) );
		Rectangle	aSrcRect( Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
							  Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ) );
		long		nOldRight = aSrcRect.Right();
		long		nOldBottom = aSrcRect.Bottom();

		if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() )
		{
			if ( (aPosAry.mnSrcX+aPosAry.mnSrcWidth-1) > aSrcOutRect.Right() )
				aPosAry.mnSrcWidth -= nOldRight-aSrcRect.Right();

			if ( (aPosAry.mnSrcY+aPosAry.mnSrcHeight-1) > aSrcOutRect.Bottom() )
				aPosAry.mnSrcHeight -= nOldBottom-aSrcRect.Bottom();

			if ( (meOutDevType == OUTDEV_WINDOW) && (nFlags & COPYAREA_WINDOWINVALIDATE) )
			{
				((Window*)this)->ImplMoveAllInvalidateRegions( aSrcRect,
															   aPosAry.mnDestX-aPosAry.mnSrcX,
															   aPosAry.mnDestY-aPosAry.mnSrcY,
															   sal_False );

				mpGraphics->CopyArea( aPosAry.mnDestX, aPosAry.mnDestY,
									  aPosAry.mnSrcX, aPosAry.mnSrcY,
									  aPosAry.mnSrcWidth, aPosAry.mnSrcHeight,
									  SAL_COPYAREA_WINDOWINVALIDATE, this );
			}
			else
			{
				aPosAry.mnDestWidth  = aPosAry.mnSrcWidth;
				aPosAry.mnDestHeight = aPosAry.mnSrcHeight;
				mpGraphics->CopyBits( aPosAry, NULL, this, NULL );
			}
		}
	}

	SetRasterOp( eOldRop );

    if( mpAlphaVDev )
        mpAlphaVDev->CopyArea( rDestPt, rSrcPt, rSrcSize, nFlags );
}

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

void OutputDevice::ImplDrawFrameDev( const Point& rPt, const Point& rDevPt, const Size& rDevSize,
									 const OutputDevice& rOutDev, const Region& rRegion )
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	GDIMetaFile*	pOldMetaFile = mpMetaFile;
	sal_Bool			bOldMap = mbMap;
	RasterOp		eOldROP = GetRasterOp();
	mpMetaFile = NULL;
	mbMap = sal_False;
	SetRasterOp( ROP_OVERPAINT );

	if ( !IsDeviceOutputNecessary() )
		return;

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

	// ClipRegion zuruecksetzen
	if ( rRegion.IsNull() )
		mpGraphics->ResetClipRegion();
	else
		ImplSelectClipRegion( rRegion );

	SalTwoRect aPosAry;
	aPosAry.mnSrcX		 = rDevPt.X();
	aPosAry.mnSrcY		 = rDevPt.Y();
	aPosAry.mnSrcWidth	 = rDevSize.Width();
	aPosAry.mnSrcHeight  = rDevSize.Height();
	aPosAry.mnDestX 	 = rPt.X();
	aPosAry.mnDestY 	 = rPt.Y();
	aPosAry.mnDestWidth  = rDevSize.Width();
	aPosAry.mnDestHeight = rDevSize.Height();
	ImplDrawOutDevDirect( &rOutDev, aPosAry );

	// Dafuer sorgen, das ClipRegion neu berechnet und gesetzt wird
	mbInitClipRegion = sal_True;

	SetRasterOp( eOldROP );
	mbMap = bOldMap;
	mpMetaFile = pOldMetaFile;
}

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

void OutputDevice::ImplGetFrameDev( const Point& rPt, const Point& rDevPt, const Size& rDevSize,
									OutputDevice& rDev )
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	sal_Bool bOldMap = mbMap;
	mbMap = sal_False;
	rDev.DrawOutDev( rDevPt, rDevSize, rPt, rDevSize, *this );
	mbMap = bOldMap;
}

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

void OutputDevice::DrawBitmap( const Point& rDestPt, const Bitmap& rBitmap )
{
	DBG_TRACE( "OutputDevice::DrawBitmap()" );

    if( ImplIsRecordLayout() )
        return;

	const Size aSizePix( rBitmap.GetSizePixel() );
	ImplDrawBitmap( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmap, META_BMP_ACTION );

    if( mpAlphaVDev )
    {
        // #i32109#: Make bitmap area opaque
        mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, PixelToLogic( aSizePix )) );
    }
}

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

void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize, const Bitmap& rBitmap )
{
	DBG_TRACE( "OutputDevice::DrawBitmap( Size )" );

    if( ImplIsRecordLayout() )
        return;

	ImplDrawBitmap( rDestPt, rDestSize, Point(), rBitmap.GetSizePixel(), rBitmap, META_BMPSCALE_ACTION );

    if( mpAlphaVDev )
    {
        // #i32109#: Make bitmap area opaque
        mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
    }
}

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

void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize,
							   const Point& rSrcPtPixel, const Size& rSrcSizePixel,
							   const Bitmap& rBitmap )
{
	DBG_TRACE( "OutputDevice::DrawBitmap( Point, Size )" );

    if( ImplIsRecordLayout() )
        return;

	ImplDrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmap, META_BMPSCALEPART_ACTION );

    if( mpAlphaVDev )
    {
        // #i32109#: Make bitmap area opaque
        mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
    }
}

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

void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize,
								   const Point& rSrcPtPixel, const Size& rSrcSizePixel,
								   const Bitmap& rBitmap, const sal_uLong nAction )
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( ( mnDrawMode & DRAWMODE_NOBITMAP ) )
		return;

    if ( ROP_INVERT == meRasterOp )
	{
		DrawRect( Rectangle( rDestPt, rDestSize ) );
		return;
	}
	
	Bitmap aBmp( rBitmap );

    if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | 
							 DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) )
	{
		if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
		{
			sal_uInt8 cCmpVal;

			if ( mnDrawMode & DRAWMODE_BLACKBITMAP )
				cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 0x80 : 0;
			else
				cCmpVal = 255;

			Color aCol( cCmpVal, cCmpVal, cCmpVal );
			Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
			SetLineColor( aCol );
			SetFillColor( aCol );
			DrawRect( Rectangle( rDestPt, rDestSize ) );
			Pop();
			return;
		}
		else if( !!aBmp )
		{
			if ( mnDrawMode & DRAWMODE_GRAYBITMAP )
				aBmp.Convert( BMP_CONVERSION_8BIT_GREYS );

			if ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP )
				aBmp.Convert( BMP_CONVERSION_GHOSTED );
		}
	}

	if ( mpMetaFile )
	{
		switch( nAction )
		{
			case( META_BMP_ACTION ):
				mpMetaFile->AddAction( new MetaBmpAction( rDestPt, aBmp ) );
			break;

			case( META_BMPSCALE_ACTION ):
				mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
			break;

			case( META_BMPSCALEPART_ACTION ):
				mpMetaFile->AddAction( new MetaBmpScalePartAction(
					rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp ) );
			break;
		}
	}

	OUTDEV_INIT();

	if( !aBmp.IsEmpty() )
	{
		SalTwoRect aPosAry;

		aPosAry.mnSrcX = rSrcPtPixel.X();
		aPosAry.mnSrcY = rSrcPtPixel.Y();
		aPosAry.mnSrcWidth = rSrcSizePixel.Width();
		aPosAry.mnSrcHeight = rSrcSizePixel.Height();
		aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
		aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
		aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
		aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );

		const sal_uLong nMirrFlags = ImplAdjustTwoRect( aPosAry, aBmp.GetSizePixel() );

		if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
		{
			if ( nMirrFlags )
				aBmp.Mirror( nMirrFlags );
            
            /* #i75264# (corrected with #i81576#)
            * sometimes a bitmap is scaled to a ridiculous size and drawn
            * to a quite normal VDev, so only a very small part of
            * the scaled bitmap will be visible. However actually scaling
            * the bitmap will use so much memory that we end with a crash.
            * Workaround: since only a small part of the scaled bitmap will
            * be actually drawn anyway (because of clipping on the device
            * boundary), limit the destination and source rectangles so
            * that the destination rectangle will overlap the device but only
            * be reasonably (say factor 2) larger than the device itself.
            */

            // not needed for win32, it uses GdiPlus and is able to do everything without
            // internally scaling the bitmap
#ifndef WIN32 

            if( aPosAry.mnDestWidth > 2048 || aPosAry.mnDestHeight > 2048 )
            {
                 if( meOutDevType == OUTDEV_WINDOW ||
                     (meOutDevType == OUTDEV_VIRDEV && mpPDFWriter == 0 ) )
                {
                    // #i81576# do the following trick only if there is overlap at all
                    // else the formulae don't work
                    // theoretically in this case we wouldn't need to draw the bitmap at all
                    // however there are some esoteric case where that is needed
                    if( aPosAry.mnDestX + aPosAry.mnDestWidth >= 0
                        && aPosAry.mnDestX < mnOutWidth
                        && aPosAry.mnDestY + aPosAry.mnDestHeight >= 0
                        && aPosAry.mnDestY < mnOutHeight )
                    {
                        // reduce scaling to something reasonable taking into account the output size
                        if( aPosAry.mnDestWidth > 3*mnOutWidth && aPosAry.mnSrcWidth )
                        {
                            const double nScaleX = aPosAry.mnDestWidth/double(aPosAry.mnSrcWidth);
    
                            if( aPosAry.mnDestX + aPosAry.mnDestWidth > mnOutWidth )
                            {
                                aPosAry.mnDestWidth = Max(long(0),mnOutWidth-aPosAry.mnDestX);
                            }
                            if( aPosAry.mnDestX < 0 )
                            {
                                aPosAry.mnDestWidth += aPosAry.mnDestX;
                                aPosAry.mnSrcX -= sal::static_int_cast<long>(aPosAry.mnDestX / nScaleX);
                                aPosAry.mnDestX = 0;
                            }
    
                            aPosAry.mnSrcWidth = sal::static_int_cast<long>(aPosAry.mnDestWidth / nScaleX);
                        }
    
                        if( aPosAry.mnDestHeight > 3*mnOutHeight && aPosAry.mnSrcHeight != 0 )
                        {
                            const double nScaleY = aPosAry.mnDestHeight/double(aPosAry.mnSrcHeight);
    
                            if( aPosAry.mnDestY + aPosAry.mnDestHeight > mnOutHeight )
                            {
                                aPosAry.mnDestHeight = Max(long(0),mnOutHeight-aPosAry.mnDestY);
                            }
                            if( aPosAry.mnDestY < 0 )
                            {
                                aPosAry.mnDestHeight += aPosAry.mnDestY;
                                aPosAry.mnSrcY -= sal::static_int_cast<long>(aPosAry.mnDestY / nScaleY);
                                aPosAry.mnDestY = 0;
                            }
    
                            aPosAry.mnSrcHeight = sal::static_int_cast<long>(aPosAry.mnDestHeight / nScaleY);
                        }
                    }
                }
            }
#endif

            if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
            {
                mpGraphics->DrawBitmap( aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this );
            }
		}
	}
}

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

void OutputDevice::DrawBitmapEx( const Point& rDestPt,
								 const BitmapEx& rBitmapEx )
{
	DBG_TRACE( "OutputDevice::DrawBitmapEx()" );

    if( ImplIsRecordLayout() )
        return;

	if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
    {
		DrawBitmap( rDestPt, rBitmapEx.GetBitmap() );
    }
	else
	{
		const Size aSizePix( rBitmapEx.GetSizePixel() );
		ImplDrawBitmapEx( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmapEx, META_BMPEX_ACTION );
	}
}

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

void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
								 const BitmapEx& rBitmapEx )
{
	DBG_TRACE( "OutputDevice::DrawBitmapEx( Size )" );

    if( ImplIsRecordLayout() )
        return;

	if ( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
    {
		DrawBitmap( rDestPt, rDestSize, rBitmapEx.GetBitmap() );
    }
	else
    {
		ImplDrawBitmapEx( rDestPt, rDestSize, Point(), rBitmapEx.GetSizePixel(), rBitmapEx, META_BMPEXSCALE_ACTION );
    }
}

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

void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
								 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
								 const BitmapEx& rBitmapEx )
{
	DBG_TRACE( "OutputDevice::DrawBitmapEx( Point, Size )" );

    if( ImplIsRecordLayout() )
        return;

	if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
    {
		DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx.GetBitmap() );
    }
	else
    {
		ImplDrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx, META_BMPEXSCALEPART_ACTION );
    }
}

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

void OutputDevice::DrawTransformedBitmapEx(
    const basegfx::B2DHomMatrix& rTransformation,
    const BitmapEx& rBitmapEx)
{
	DBG_TRACE( "OutputDevice::DrawBitmapEx( Point, Size )" );

    if( ImplIsRecordLayout() )
        return;

    if(rBitmapEx.IsEmpty())
        return;

    if ( mnDrawMode & DRAWMODE_NOBITMAP )
        return;

    // decompose matrix to check rotation and shear
    basegfx::B2DVector aScale, aTranslate;
    double fRotate, fShearX;
    rTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
    const bool bRotated(!basegfx::fTools::equalZero(fRotate));
    const bool bSheared(!basegfx::fTools::equalZero(fShearX));
    const bool bMirroredX(basegfx::fTools::less(aScale.getX(), 0.0));
    const bool bMirroredY(basegfx::fTools::less(aScale.getY(), 0.0));

    if(!bRotated && !bSheared && !bMirroredX && !bMirroredY)
    {
        // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx
        // do *not* execute the mirroring here, it's done in the fallback
        const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY()));
        const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY()));

        DrawBitmapEx(aDestPt, aDestSize, rBitmapEx);
        return;
    }

    // we have rotation,shear or mirror, check if some crazy mode needs the
    // created transformed bitmap
    const bool bInvert(ROP_INVERT == meRasterOp);
    const bool bBitmapChangedColor(mnDrawMode & (DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP));
    const bool bMetafile(mpMetaFile);
    const bool bPrinter(OUTDEV_PRINTER == meOutDevType);
    bool bDone(false);
    const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation);
    const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile && !bPrinter);

    if(bTryDirectPaint)
    {
        // try to paint directly
        const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 0.0));
        const basegfx::B2DPoint aTopX(aFullTransform * basegfx::B2DPoint(1.0, 0.0));
        const basegfx::B2DPoint aTopY(aFullTransform * basegfx::B2DPoint(0.0, 1.0));
        SalBitmap* pSalSrcBmp = rBitmapEx.GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap();
        SalBitmap* pSalAlphaBmp = 0;

        if(rBitmapEx.IsTransparent())
        {
            if(rBitmapEx.IsAlpha())
            {
                pSalAlphaBmp = rBitmapEx.GetAlpha().ImplGetImpBitmap()->ImplGetSalBitmap();
            }
            else
            {
                pSalAlphaBmp = rBitmapEx.GetMask().ImplGetImpBitmap()->ImplGetSalBitmap();
            }
        }

        bDone = mpGraphics->DrawTransformedBitmap(
            aNull, 
            aTopX, 
            aTopY,
            *pSalSrcBmp,
            pSalAlphaBmp,
            this);
    }

    if(!bDone)
    {
        // take the fallback when no rotate and shear, but mirror (else we would have done this above)
        if(!bRotated && !bSheared)
        {
            // with no rotation or shear it can be mapped to DrawBitmapEx
            // do *not* execute the mirroring here, it's done in the fallback
            const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY()));
            const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY()));

            DrawBitmapEx(aDestPt, aDestSize, rBitmapEx);
            return;
        }

        // fallback; create transformed bitmap the hard way (back-transform
        // the pixels) and paint
        basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0);
        const double fMaximumArea(bMetafile ? 800000.0 : 200000.0);
        const BitmapEx aTransformed(rBitmapEx.getTransformed(aFullTransform, fMaximumArea));
        aTargetRange.transform(rTransformation);
        const Point aDestPt(basegfx::fround(aTargetRange.getMinX()), basegfx::fround(aTargetRange.getMinY()));
        const Size aDestSize(basegfx::fround(aTargetRange.getWidth()), basegfx::fround(aTargetRange.getHeight()));

        DrawBitmapEx(aDestPt, aDestSize, aTransformed);
    }
}

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

void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
									 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
									 const BitmapEx& rBitmapEx, const sal_uLong nAction )
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    OSL_ENSURE(TRANSPARENT_NONE != rBitmapEx.GetTransparentType(), "ImplDrawBitmapEx not needed, no transparency in BitmapEx (!)");

	if ( mnDrawMode & DRAWMODE_NOBITMAP )
		return;

    if ( ROP_INVERT == meRasterOp )
	{
		DrawRect( Rectangle( rDestPt, rDestSize ) );
		return;
	}

	BitmapEx aBmpEx( rBitmapEx );

    if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | 
							 DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) )
	{
		if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
		{
			Bitmap	aColorBmp( aBmpEx.GetSizePixel(), ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 4 : 1 );
			sal_uInt8	cCmpVal;

			if ( mnDrawMode & DRAWMODE_BLACKBITMAP )
				cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 0x80 : 0;
			else
				cCmpVal = 255;

			aColorBmp.Erase( Color( cCmpVal, cCmpVal, cCmpVal ) );

			if( aBmpEx.IsAlpha() )
            {
                // Create one-bit mask out of alpha channel, by
                // thresholding it at alpha=0.5. As
                // DRAWMODE_BLACK/WHITEBITMAP requires monochrome
                // output, having alpha-induced grey levels is not
                // acceptable.
                Bitmap aMask( aBmpEx.GetAlpha().GetBitmap() );
                aMask.MakeMono( 128 );
				aBmpEx = BitmapEx( aColorBmp, aMask );
            }
			else
            {
				aBmpEx = BitmapEx( aColorBmp, aBmpEx.GetMask() );
            }
		}
		else if( !!aBmpEx )
		{
			if ( mnDrawMode & DRAWMODE_GRAYBITMAP )
				aBmpEx.Convert( BMP_CONVERSION_8BIT_GREYS );

			if ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP )
				aBmpEx.Convert( BMP_CONVERSION_GHOSTED );
		}
	}

	if ( mpMetaFile )
	{
		switch( nAction )
		{
			case( META_BMPEX_ACTION ):
				mpMetaFile->AddAction( new MetaBmpExAction( rDestPt, aBmpEx ) );
			break;

			case( META_BMPEXSCALE_ACTION ):
				mpMetaFile->AddAction( new MetaBmpExScaleAction( rDestPt, rDestSize, aBmpEx ) );
			break;

			case( META_BMPEXSCALEPART_ACTION ):
				mpMetaFile->AddAction( new MetaBmpExScalePartAction( rDestPt, rDestSize,
																	 rSrcPtPixel, rSrcSizePixel, aBmpEx ) );
			break;
		}
	}

	OUTDEV_INIT();

	if( OUTDEV_PRINTER == meOutDevType )
	{
        if( aBmpEx.IsAlpha() )
        {
            // #107169# For true alpha bitmaps, no longer masking the
            // bitmap, but perform a full alpha blend against a white
            // background here.
            Bitmap aBmp( aBmpEx.GetBitmap() );
            aBmp.Blend( aBmpEx.GetAlpha(), Color( COL_WHITE) );
            DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp );
        }
        else
        {
            Bitmap aBmp( aBmpEx.GetBitmap() ), aMask( aBmpEx.GetMask() );
            aBmp.Replace( aMask, Color( COL_WHITE ) );
            ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
        }
	
        return;
	}

    if(aBmpEx.IsAlpha())
	{
		ImplDrawAlpha( aBmpEx.GetBitmap(), aBmpEx.GetAlpha(), rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
		return;
	}

	if( !( !aBmpEx ) )
	{
		SalTwoRect aPosAry;

		aPosAry.mnSrcX = rSrcPtPixel.X();
		aPosAry.mnSrcY = rSrcPtPixel.Y();
		aPosAry.mnSrcWidth = rSrcSizePixel.Width();
		aPosAry.mnSrcHeight = rSrcSizePixel.Height();
		aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
		aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
		aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
		aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );

		const sal_uLong nMirrFlags = ImplAdjustTwoRect( aPosAry, aBmpEx.GetSizePixel() );

		if( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
		{

			if( nMirrFlags )
				aBmpEx.Mirror( nMirrFlags );

            const SalBitmap* pSalSrcBmp = aBmpEx.ImplGetBitmapImpBitmap()->ImplGetSalBitmap();
			const ImpBitmap* pMaskBmp = aBmpEx.ImplGetMaskImpBitmap();

			if ( pMaskBmp )
            {
                SalBitmap* pSalAlphaBmp = pMaskBmp->ImplGetSalBitmap();
                bool bTryDirectPaint(pSalSrcBmp && pSalAlphaBmp);

                if(bTryDirectPaint)
                {
                    // only paint direct when no scaling and no MapMode, else the
                    // more expensive conversions may be done for short-time Bitmap/BitmapEx
                    // used for buffering only
                    if(!IsMapMode() && aPosAry.mnSrcWidth == aPosAry.mnDestWidth && aPosAry.mnSrcHeight == aPosAry.mnDestHeight)
                    {
                        bTryDirectPaint = false;
                    }
                }

                if(bTryDirectPaint && mpGraphics->DrawAlphaBitmap(aPosAry, *pSalSrcBmp, *pSalAlphaBmp, this))
                {
                    // tried to paint as alpha directly. If tis worked, we are done (except
                    // alpha, see below)
                }
                else
                {
                    // #4919452# reduce operation area to bounds of
                    // cliprect. since masked transparency involves
                    // creation of a large vdev and copying the screen
                    // content into that (slooow read from framebuffer),
                    // that should considerably increase performance for
                    // large bitmaps and small clippings.

                    // Note that this optimisation is a workaround for a
                    // Writer peculiarity, namely, to decompose background
                    // graphics into myriads of disjunct, tiny
                    // rectangles. That otherwise kills us here, since for
                    // transparent output, SAL always prepares the whole
                    // bitmap, if aPosAry contains the whole bitmap (and
                    // it's _not_ to blame for that).

                    // Note the call to ImplPixelToDevicePixel(), since
                    // aPosAry already contains the mnOutOff-offsets, they
                    // also have to be applied to the region
                    Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() );

                    // TODO: Also respect scaling (that's a bit tricky,
                    // since the source points have to move fractional
                    // amounts (which is not possible, thus has to be
                    // emulated by increases copy area)
                    // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth );
                    // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight );

                    // for now, only identity scales allowed
                    if( !aClipRegionBounds.IsEmpty() &&
                        aPosAry.mnDestWidth == aPosAry.mnSrcWidth &&
                        aPosAry.mnDestHeight == aPosAry.mnSrcHeight )
                    {
                        // now intersect dest rect with clip region
                        aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX, 
                                                                   aPosAry.mnDestY,
                                                                   aPosAry.mnDestX + aPosAry.mnDestWidth - 1,
                                                                   aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) );

                        // Note: I could theoretically optimize away the
                        // DrawBitmap below, if the region is empty
                        // here. Unfortunately, cannot rule out that
                        // somebody relies on the side effects.
                        if( !aClipRegionBounds.IsEmpty() )
                        {
                            aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX;
                            aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY;
                            aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth();
                            aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight();
                        
                            aPosAry.mnDestX = aClipRegionBounds.Left();
                            aPosAry.mnDestY = aClipRegionBounds.Top();
                            aPosAry.mnDestWidth = aClipRegionBounds.GetWidth();
                            aPosAry.mnDestHeight = aClipRegionBounds.GetHeight();
                        }
                    }

                    mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, 
                                            *pMaskBmp->ImplGetSalBitmap(), 
                                            this );
                }

                // #110958# Paint mask to alpha channel. Luckily, the
                // black and white representation of the mask maps to
                // the alpha channel 

                // #i25167# Restrict mask painting to _opaque_ areas
                // of the mask, otherwise we spoil areas where no
                // bitmap content was ever visible. Interestingly
                // enough, this can be achieved by taking the mask as
                // the transparency mask of itself
                if( mpAlphaVDev )
                    mpAlphaVDev->DrawBitmapEx( rDestPt, 
                                               rDestSize, 
                                               BitmapEx( aBmpEx.GetMask(),
                                                         aBmpEx.GetMask() ) );
            }
			else
            {
				mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, this );

                if( mpAlphaVDev )
                {
                    // #i32109#: Make bitmap area opaque
                    mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
                }
            }
		}
	}
}

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

void OutputDevice::DrawMask( const Point& rDestPt,
							 const Bitmap& rBitmap, const Color& rMaskColor )
{
	DBG_TRACE( "OutputDevice::DrawMask()" );

    if( ImplIsRecordLayout() )
        return;

	const Size aSizePix( rBitmap.GetSizePixel() );
	ImplDrawMask( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmap, rMaskColor, META_MASK_ACTION );

    if( mpAlphaVDev )
    {
        const Bitmap& rMask( rBitmap.CreateMask( rMaskColor ) );

        // #i25167# Restrict mask painting to _opaque_ areas
        // of the mask, otherwise we spoil areas where no
        // bitmap content was ever visible. Interestingly
        // enough, this can be achieved by taking the mask as
        // the transparency mask of itself
        mpAlphaVDev->DrawBitmapEx( rDestPt, 
                                   PixelToLogic( aSizePix ), 
                                   BitmapEx( rMask, rMask ) );
    }
}

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

void OutputDevice::DrawMask( const Point& rDestPt, const Size& rDestSize,
							 const Bitmap& rBitmap, const Color& rMaskColor )
{
	DBG_TRACE( "OutputDevice::DrawMask( Size )" );

    if( ImplIsRecordLayout() )
        return;

	ImplDrawMask( rDestPt, rDestSize, Point(), rBitmap.GetSizePixel(), rBitmap, rMaskColor, META_MASKSCALE_ACTION );

    // TODO: Use mask here
    if( mpAlphaVDev )
    {
        const Bitmap& rMask( rBitmap.CreateMask( rMaskColor ) );

        // #i25167# Restrict mask painting to _opaque_ areas
        // of the mask, otherwise we spoil areas where no
        // bitmap content was ever visible. Interestingly
        // enough, this can be achieved by taking the mask as
        // the transparency mask of itself
        mpAlphaVDev->DrawBitmapEx( rDestPt, 
                                   rDestSize, 
                                   BitmapEx( rMask, rMask ) );
    }
}

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

void OutputDevice::DrawMask( const Point& rDestPt, const Size& rDestSize,
							 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
							 const Bitmap& rBitmap, const Color& rMaskColor )
{
	DBG_TRACE( "OutputDevice::DrawMask( Point, Size )" );

    if( ImplIsRecordLayout() )
        return;

	ImplDrawMask( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmap, rMaskColor, META_MASKSCALEPART_ACTION );

    // TODO: Use mask here
    if( mpAlphaVDev )
    {
        const Bitmap& rMask( rBitmap.CreateMask( rMaskColor ) );

        // #i25167# Restrict mask painting to _opaque_ areas
        // of the mask, otherwise we spoil areas where no
        // bitmap content was ever visible. Interestingly
        // enough, this can be achieved by taking the mask as
        // the transparency mask of itself
        mpAlphaVDev->DrawBitmapEx( rDestPt, 
                                   rDestSize, 
                                   rSrcPtPixel, 
                                   rSrcSizePixel,
                                   BitmapEx( rMask, rMask ) );
    }
}

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

void OutputDevice::ImplDrawMask( const Point& rDestPt, const Size& rDestSize,
								 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
								 const Bitmap& rBitmap, const Color& rMaskColor,
								 const sal_uLong nAction )
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if( ROP_INVERT == meRasterOp )
	{
		DrawRect( Rectangle( rDestPt, rDestSize ) );
		return;
	}

	if ( mpMetaFile )
	{
		switch( nAction )
		{
			case( META_MASK_ACTION ):
				mpMetaFile->AddAction( new MetaMaskAction( rDestPt,
					rBitmap, rMaskColor ) );
			break;

			case( META_MASKSCALE_ACTION ):
				mpMetaFile->AddAction( new MetaMaskScaleAction( rDestPt,
					rDestSize, rBitmap, rMaskColor ) );
			break;

			case( META_MASKSCALEPART_ACTION ):
				mpMetaFile->AddAction( new MetaMaskScalePartAction( rDestPt, rDestSize,
					rSrcPtPixel, rSrcSizePixel, rBitmap, rMaskColor ) );
			break;
		}
	}

	OUTDEV_INIT();

	if ( OUTDEV_PRINTER == meOutDevType )
	{
		ImplPrintMask( rBitmap, rMaskColor, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
		return;
	}

	const ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap();
	if ( pImpBmp )
	{
		SalTwoRect aPosAry;

		aPosAry.mnSrcX = rSrcPtPixel.X();
		aPosAry.mnSrcY = rSrcPtPixel.Y();
		aPosAry.mnSrcWidth = rSrcSizePixel.Width();
		aPosAry.mnSrcHeight = rSrcSizePixel.Height();
		aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
		aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
		aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
		aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );

		// spiegeln via Koordinaten wollen wir nicht
		const sal_uLong nMirrFlags = ImplAdjustTwoRect( aPosAry, pImpBmp->ImplGetSize() );

		// check if output is necessary
		if( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
		{

			if( nMirrFlags )
			{
				Bitmap aTmp( rBitmap );
				aTmp.Mirror( nMirrFlags );
				mpGraphics->DrawMask( aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(),
									  ImplColorToSal( rMaskColor ) , this);
			}
			else
				mpGraphics->DrawMask( aPosAry, *pImpBmp->ImplGetSalBitmap(),
									  ImplColorToSal( rMaskColor ), this );

		}
	}
}

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

void OutputDevice::DrawImage( const Point& rPos, const Image& rImage, sal_uInt16 nStyle )
{
	DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER, "DrawImage(): Images can't be drawn on any mprinter" );
	
	if( !rImage.mpImplData || ImplIsRecordLayout() )
		return;
	
	switch( rImage.mpImplData->meType )
	{
		case IMAGETYPE_BITMAP:
			DrawBitmap( rPos, *static_cast< Bitmap* >( rImage.mpImplData->mpData ) );
		break;

		case IMAGETYPE_IMAGE:
		{
			ImplImageData* pData = static_cast< ImplImageData* >( rImage.mpImplData->mpData );

			if( !pData->mpImageBitmap )
			{
				const Size aSize( pData->maBmpEx.GetSizePixel() );
			
				pData->mpImageBitmap = new ImplImageBmp;
				pData->mpImageBitmap->Create( pData->maBmpEx, aSize.Width(), aSize.Height(), 1 );
			}

			pData->mpImageBitmap->Draw( 0, this, rPos, nStyle );
		}
		break;

		default:
		break;
	}
}

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

void OutputDevice::DrawImage( const Point& rPos, const Size& rSize,
							  const Image& rImage, sal_uInt16 nStyle )
{
	DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER, "DrawImage(): Images can't be drawn on any mprinter" );

	if( rImage.mpImplData && !ImplIsRecordLayout() )
	{
		switch( rImage.mpImplData->meType )
		{
			case IMAGETYPE_BITMAP:
				DrawBitmap( rPos, rSize, *static_cast< Bitmap* >( rImage.mpImplData->mpData ) );
			break;
	
			case IMAGETYPE_IMAGE:
			{
				ImplImageData* pData = static_cast< ImplImageData* >( rImage.mpImplData->mpData );
	
				if ( !pData->mpImageBitmap )
				{
					const Size aSize( pData->maBmpEx.GetSizePixel() );
					
					pData->mpImageBitmap = new ImplImageBmp;
					pData->mpImageBitmap->Create( pData->maBmpEx, aSize.Width(), aSize.Height(), 1 );
				}
	
				pData->mpImageBitmap->Draw( 0, this, rPos, nStyle, &rSize );
			}
			break;
				
			default:
			break;
		}
	}
}

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

Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    OSL_ENSURE(OUTDEV_PRINTER != GetOutDevType(), "OutputDevice::GetBitmap with sorce type OUTDEV_PRINTER should not be used (!)");

	Bitmap	aBmp;
	long	nX = ImplLogicXToDevicePixel( rSrcPt.X() );
	long	nY = ImplLogicYToDevicePixel( rSrcPt.Y() );
	long	nWidth = ImplLogicWidthToDevicePixel( rSize.Width() );
	long	nHeight = ImplLogicHeightToDevicePixel( rSize.Height() );

	if ( mpGraphics || ( (OutputDevice*) this )->ImplGetGraphics() )
	{
		if ( nWidth > 0 && nHeight  > 0 && nX <= (mnOutWidth + mnOutOffX) && nY <= (mnOutHeight + mnOutOffY))
		{
			Rectangle	aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
			sal_Bool		bClipped = sal_False;

			// X-Koordinate ausserhalb des Bereichs?
			if ( nX < mnOutOffX )
			{
				nWidth -= ( mnOutOffX - nX );
				nX = mnOutOffX;
				bClipped = sal_True;
			}

			// Y-Koordinate ausserhalb des Bereichs?
			if ( nY < mnOutOffY )
			{
				nHeight -= ( mnOutOffY - nY );
				nY = mnOutOffY;
				bClipped = sal_True;
			}

			// Breite ausserhalb des Bereichs?
			if ( (nWidth + nX) > (mnOutWidth + mnOutOffX) )
			{
				nWidth	= mnOutOffX + mnOutWidth - nX;
				bClipped = sal_True;
			}

			// Hoehe ausserhalb des Bereichs?
			if ( (nHeight + nY) > (mnOutHeight + mnOutOffY) )
			{
				nHeight = mnOutOffY + mnOutHeight - nY;
				bClipped = sal_True;
			}

			if ( bClipped )
			{
				// Falls auf den sichtbaren Bereich geclipped wurde,
				// muessen wir eine Bitmap in der rchtigen Groesse
				// erzeugen, in die die geclippte Bitmap an die angepasste
				// Position kopiert wird
				VirtualDevice aVDev( *this );

				if ( aVDev.SetOutputSizePixel( aRect.GetSize() ) )
				{
					if ( ((OutputDevice*)&aVDev)->mpGraphics || ((OutputDevice*)&aVDev)->ImplGetGraphics() )
					{
						SalTwoRect aPosAry;

						aPosAry.mnSrcX = nX;
						aPosAry.mnSrcY = nY;
						aPosAry.mnSrcWidth = nWidth;
						aPosAry.mnSrcHeight = nHeight;
						aPosAry.mnDestX = ( aRect.Left() < mnOutOffX ) ? ( mnOutOffX - aRect.Left() ) : 0L;
						aPosAry.mnDestY = ( aRect.Top() < mnOutOffY ) ? ( mnOutOffY - aRect.Top() ) : 0L;
						aPosAry.mnDestWidth = nWidth;
						aPosAry.mnDestHeight = nHeight;

						if ( (nWidth > 0) && (nHeight > 0) )
                        {
							(((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( aPosAry, mpGraphics, this, this );
                        }
                        else
                        {
                            OSL_ENSURE(false, "CopyBits with negative width or height (!)");
                        }

						aBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
					 }
					 else
						bClipped = sal_False;
				}
				else
					bClipped = sal_False;
			}

			if ( !bClipped )
			{
				SalBitmap* pSalBmp = mpGraphics->GetBitmap( nX, nY, nWidth, nHeight, this );

				if( pSalBmp )
				{
					ImpBitmap* pImpBmp = new ImpBitmap;
					pImpBmp->ImplSetSalBitmap( pSalBmp );
					aBmp.ImplSetImpBitmap( pImpBmp );
				}
			}
		}
	}

	return aBmp;
}

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

BitmapEx OutputDevice::GetBitmapEx( const Point& rSrcPt, const Size& rSize ) const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

    // #110958# Extract alpha value from VDev, if any
    if( mpAlphaVDev )
    {
        Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( rSrcPt, rSize ) );

        // ensure 8 bit alpha
        if( aAlphaBitmap.GetBitCount() > 8 )
            aAlphaBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );

        return BitmapEx(GetBitmap( rSrcPt, rSize ), AlphaMask( aAlphaBitmap ) );
    }
    else
        return GetBitmap( rSrcPt, rSize );
}

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

void OutputDevice::ImplGetFrameBitmap( const Point& rDestPt, const Size& rSize,
									   Bitmap& rBitmap ) const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	sal_Bool bOldMap = mbMap;
	((OutputDevice*)this)->mbMap = sal_False;
	rBitmap = GetBitmap( rDestPt, rSize );
	((OutputDevice*)this)->mbMap = bOldMap;
}

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

Color OutputDevice::GetPixel( const Point& rPt ) const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	Color aColor;

	if ( mpGraphics || ((OutputDevice*)this)->ImplGetGraphics() )
	{
		if ( mbInitClipRegion )
			((OutputDevice*)this)->ImplInitClipRegion();

		if ( !mbOutputClipped )
		{
			const long		nX = ImplLogicXToDevicePixel( rPt.X() );
			const long		nY = ImplLogicYToDevicePixel( rPt.Y() );
			const SalColor	aSalCol = mpGraphics->GetPixel( nX, nY, this );
			aColor.SetRed( SALCOLOR_RED( aSalCol ) );
			aColor.SetGreen( SALCOLOR_GREEN( aSalCol ) );
			aColor.SetBlue( SALCOLOR_BLUE( aSalCol ) );
		}
	}
	return aColor;
}

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

Color* OutputDevice::GetPixel( const Polygon& rPts ) const
{
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	Color*			pColors = NULL;
	const sal_uInt16	nSize = rPts.GetSize();

	if( nSize )
	{
		if ( mpGraphics || ((OutputDevice*)this)->ImplGetGraphics() )
		{
			if ( mbInitClipRegion )
				((OutputDevice*)this)->ImplInitClipRegion();

			if ( !mbOutputClipped )
			{
				pColors = new Color[ nSize ];

				for( sal_uInt16 i = 0; i < nSize; i++ )
				{
					Color&			rCol = pColors[ i ];
					const Point&	rPt = rPts[ i ];
					const SalColor	aSalCol( mpGraphics->GetPixel( ImplLogicXToDevicePixel( rPt.X() ),
																   ImplLogicYToDevicePixel( rPt.Y() ) , this) );

					rCol.SetRed( SALCOLOR_RED( aSalCol ) );
					rCol.SetGreen( SALCOLOR_GREEN( aSalCol ) );
					rCol.SetBlue( SALCOLOR_BLUE( aSalCol ) );
				}
			}
		}
	}

	return pColors;
}

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

void OutputDevice::DrawPixel( const Point& rPt )
{
	DBG_TRACE( "OutputDevice::DrawPixel()" );
	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );

	if ( mpMetaFile )
		mpMetaFile->AddAction( new MetaPointAction( rPt ) );

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

	Point aPt = ImplLogicToDevicePixel( rPt );

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

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

	if ( mbInitLineColor )
		ImplInitLineColor();

	mpGraphics->DrawPixel( aPt.X(), aPt.Y(), this );

    if( mpAlphaVDev )
        mpAlphaVDev->DrawPixel( rPt );
}

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

void OutputDevice::DrawPixel( const Point& rPt, const Color& rColor )
{
	DBG_TRACE( "OutputDevice::DrawPixel()" );
	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 MetaPixelAction( rPt, aColor ) );

	if ( !IsDeviceOutputNecessary() || ImplIsColorTransparent( aColor ) || ImplIsRecordLayout() )
		return;

	Point aPt = ImplLogicToDevicePixel( rPt );

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

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

	mpGraphics->DrawPixel( aPt.X(), aPt.Y(), ImplColorToSal( aColor ), this );

    if( mpAlphaVDev )
        mpAlphaVDev->DrawPixel( rPt );
}

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

void OutputDevice::DrawPixel( const Polygon& rPts, const Color* pColors )
{
	if ( !pColors )
		DrawPixel( rPts, GetLineColor() );
	else
	{
		DBG_TRACE( "OutputDevice::DrawPixel()" );
		DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
		DBG_ASSERT( pColors, "OutputDevice::DrawPixel: No color array specified" );

		const sal_uInt16 nSize = rPts.GetSize();

		if ( nSize )
		{
			if ( mpMetaFile )
				for ( sal_uInt16 i = 0; i < nSize; i++ )
					mpMetaFile->AddAction( new MetaPixelAction( rPts[ i ], pColors[ i ] ) );

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

			// we need a graphics
			if ( mpGraphics || ImplGetGraphics() )
			{
				if ( mbInitClipRegion )
					ImplInitClipRegion();

				if ( mbOutputClipped )
					return;

				for ( sal_uInt16 i = 0; i < nSize; i++ )
				{
					const Point aPt( ImplLogicToDevicePixel( rPts[ i ] ) );
					mpGraphics->DrawPixel( aPt.X(), aPt.Y(), ImplColorToSal( pColors[ i ] ), this );
				}
			}
		}
	}

    if( mpAlphaVDev )
        mpAlphaVDev->DrawPixel( rPts, pColors );
}

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

void OutputDevice::DrawPixel( const Polygon& rPts, const Color& rColor )
{
	if( rColor != COL_TRANSPARENT && ! ImplIsRecordLayout() )
	{
		const sal_uInt16	nSize = rPts.GetSize();
		Color*			pColArray = new Color[ nSize ];

		for( sal_uInt16 i = 0; i < nSize; i++ )
			pColArray[ i ] = rColor;

		DrawPixel( rPts, pColArray );
		delete[] pColArray;
	}

    if( mpAlphaVDev )
        mpAlphaVDev->DrawPixel( rPts, rColor );
}

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

namespace
{
    sal_uInt8 lcl_calcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceOpaq, const sal_uInt8 nDestColor )
    {
        int c = ( (int)nDestColor * ( 255 - nSourceOpaq ) )
            +     (int)nSourceOpaq * (int)nSourceColor;
        return sal_uInt8( c / 255 );
    }
}

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

Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap              aBmp,
                                         BitmapReadAccess*	 pP,
                                         BitmapReadAccess*	 pA,
                                         const Rectangle&    aDstRect,
                                         const sal_Int32     nOffY, 
                                         const sal_Int32     nDstHeight, 
                                         const sal_Int32     nOffX, 
                                         const sal_Int32     nDstWidth,
                                         const long*         pMapX,
                                         const long*         pMapY )
{
    BitmapColor aDstCol,aSrcCol;
    Bitmap      res;
    int         nX, nOutX, nY, nOutY;

    OSL_ENSURE(mpAlphaVDev,
               "ImplBlendWithAlpha(): call me only with valid alpha VDev!" );

    sal_Bool bOldMapMode( mpAlphaVDev->IsMapModeEnabled() );
    mpAlphaVDev->EnableMapMode(sal_False);

    Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
    BitmapWriteAccess*	pAlphaW = aAlphaBitmap.AcquireWriteAccess();

    if( GetBitCount() <= 8 )
    {
        Bitmap				aDither( aBmp.GetSizePixel(), 8 );
        BitmapColor 		aIndex( 0 );
        BitmapReadAccess*	pB = aBmp.AcquireReadAccess();
        BitmapWriteAccess*	pW = aDither.AcquireWriteAccess();

        if( pB && pP && pA && pW && pAlphaW )
        {
            for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
            {
                const long nMapY = pMapY[ nY ];
                const long nModY = ( nOutY & 0x0FL ) << 4L;

                for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
                {
                    const long	nMapX = pMapX[ nX ];
                    const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];

                    aSrcCol = pP->GetColor( nMapY, nMapX );
                    aDstCol = pB->GetColor( nY, nX );
                    const sal_uInt8 nSrcOpaq = 255 - pA->GetPixelIndex( nMapY, nMapX );
                    const sal_uInt8 nDstOpaq  = 255 - pAlphaW->GetPixelIndex( nY, nX );

                    aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) );
                    aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) );
                    aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) );

                    aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] +
                                              nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] +
                                              nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) );
                    pW->SetPixel( nY, nX, aIndex );

                    // Have to perform the compositing 'algebra' in
                    // the inverse alpha space (with 255 meaning
                    // opaque), otherwise, transitivity is not
                    // achieved.
                    const sal_uInt8 nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (sal_uInt8)nDstOpaq, nSrcOpaq );

                    aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] +
                                              nVCLGLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] +
                                              nVCLBLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] ) );
                    pAlphaW->SetPixel( nY, nX, aIndex );
                }
            }
        }

        aBmp.ReleaseAccess( pB );
        aDither.ReleaseAccess( pW );
        res = aDither;
    }
    else
    {
        BitmapWriteAccess*	pB = aBmp.AcquireWriteAccess();
        if( pP && pA && pB )
        {
            for( nY = 0; nY < nDstHeight; nY++ )
            {
                const long	nMapY = pMapY[ nY ];

                for( nX = 0; nX < nDstWidth; nX++ )
                {
                    const long nMapX = pMapX[ nX ];

                    aSrcCol = pP->GetColor( nMapY, nMapX );
                    aDstCol = pB->GetColor( nY, nX );
                    const sal_uInt8 nSrcOpaq  = 255 - pA->GetPixelIndex( nMapY, nMapX );
                    const sal_uInt8 nDstOpaq  = 255 - pAlphaW->GetPixelIndex( nY, nX );

                    aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) );
                    aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) );
                    aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) );

                    pB->SetPixel( nY, nX, aDstCol );

                    // Have to perform the compositing 'algebra' in
                    // the inverse alpha space (with 255 meaning
                    // opaque), otherwise, transitivity is not
                    // achieved.
                    const sal_uInt8 nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (sal_uInt8)nDstOpaq, nSrcOpaq );

                    pAlphaW->SetPixel( nY, nX, Color(nSrcAlpha, nSrcAlpha, nSrcAlpha) );
                }
            }
        }

        aBmp.ReleaseAccess( pB );
        res = aBmp;
    }

    aAlphaBitmap.ReleaseAccess( pAlphaW );
    mpAlphaVDev->DrawBitmap( aDstRect.TopLeft(), aAlphaBitmap );
    mpAlphaVDev->EnableMapMode( bOldMapMode );

    return res;
}

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

Bitmap OutputDevice::ImplBlend( Bitmap              aBmp,
                                BitmapReadAccess*	pP,
                                BitmapReadAccess*	pA,
                                const sal_Int32     nOffY, 
                                const sal_Int32     nDstHeight, 
                                const sal_Int32     nOffX, 
                                const sal_Int32     nDstWidth,
                                const Rectangle&    aBmpRect, 
                                const Size&         aOutSz,
                                const bool          bHMirr,
                                const bool          bVMirr,
                                const long*         pMapX,
                                const long*         pMapY )
{
    BitmapColor aDstCol;
    Bitmap      res;
    int         nX, nOutX, nY, nOutY;

    if( GetBitCount() <= 8 )
    {
        Bitmap				aDither( aBmp.GetSizePixel(), 8 );
        BitmapColor 		aIndex( 0 );
        BitmapReadAccess*	pB = aBmp.AcquireReadAccess();
        BitmapWriteAccess*	pW = aDither.AcquireWriteAccess();

        if( pB && pP && pA && pW )
        {
            for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
            {
                const long nMapY = pMapY[ nY ];
                const long nModY = ( nOutY & 0x0FL ) << 4L;

                for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
                {
                    const long	nMapX = pMapX[ nX ];
                    const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];

                    aDstCol = pB->GetColor( nY, nX );
                    aDstCol.Merge( pP->GetColor( nMapY, nMapX ), pA->GetPixelIndex( nMapY, nMapX ) );
                    aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] +
                                              nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] +
                                              nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) );
                    pW->SetPixel( nY, nX, aIndex );
                }
            }
        }

        aBmp.ReleaseAccess( pB );
        aDither.ReleaseAccess( pW );
        res = aDither;
    }
    else
    {
        BitmapWriteAccess*	pB = aBmp.AcquireWriteAccess();

        bool bFastBlend = false;
        if( pP && pA && pB )
        {
            SalTwoRect aTR;
            aTR.mnSrcX      = aBmpRect.Left();
            aTR.mnSrcY      = aBmpRect.Top();
            aTR.mnSrcWidth  = aBmpRect.GetWidth();
            aTR.mnSrcHeight = aBmpRect.GetHeight();
            aTR.mnDestX     = nOffX;
            aTR.mnDestY     = nOffY;
            aTR.mnDestWidth = aOutSz.Width();
            aTR.mnDestHeight= aOutSz.Height();

            if( !bHMirr || !bVMirr )
                bFastBlend = ImplFastBitmapBlending( *pB,*pP,*pA, aTR );
        }

        if( pP && pA && pB && !bFastBlend )
        {
            switch( pP->GetScanlineFormat() )
            {
                case( BMP_FORMAT_8BIT_PAL ):
                    {
                        for( nY = 0; nY < nDstHeight; nY++ )
                        {
                            const long	nMapY = pMapY[ nY ];
                            Scanline	pPScan = pP->GetScanline( nMapY );
                            Scanline	pAScan = pA->GetScanline( nMapY );

                            for( nX = 0; nX < nDstWidth; nX++ )
                            {
                                const long nMapX = pMapX[ nX ];
                                aDstCol = pB->GetPixel( nY, nX );
                                pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetPaletteColor( pPScan[ nMapX ] ),
                                                                     pAScan[ nMapX ] ) );
                            }
                        }
                    }
                    break;

                case( BMP_FORMAT_24BIT_TC_BGR ):
                    {
                        for( nY = 0; nY < nDstHeight; nY++ )
                        {
                            const long	nMapY = pMapY[ nY ];
                            Scanline	pPScan = pP->GetScanline( nMapY );
                            Scanline	pAScan = pA->GetScanline( nMapY );

                            for( nX = 0; nX < nDstWidth; nX++ )
                            {
                                const long	nMapX = pMapX[ nX ];
                                Scanline	pTmp = pPScan + nMapX * 3;

                                aDstCol = pB->GetPixel( nY, nX );
                                pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 2 ], pTmp[ 1 ], pTmp[ 0 ],
                                                                     pAScan[ nMapX ] ) );
                            }
                        }
                    }
                    break;

                case( BMP_FORMAT_24BIT_TC_RGB ):
                    {
                        for( nY = 0; nY < nDstHeight; nY++ )
                        {
                            const long	nMapY = pMapY[ nY ];
                            Scanline	pPScan = pP->GetScanline( nMapY );
                            Scanline	pAScan = pA->GetScanline( nMapY );

                            for( nX = 0; nX < nDstWidth; nX++ )
                            {
                                const long	nMapX = pMapX[ nX ];
                                Scanline    pTmp = pPScan + nMapX * 3;

                                aDstCol = pB->GetPixel( nY, nX );
                                pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 0 ], pTmp[ 1 ], pTmp[ 2 ],
                                                                     pAScan[ nMapX ] ) );
                            }
                        }
                    }
                    break;

                default:
                {
                    for( nY = 0; nY < nDstHeight; nY++ )
                    {
                        const long	nMapY = pMapY[ nY ];
                        Scanline	pAScan = pA->GetScanline( nMapY );

                        for( nX = 0; nX < nDstWidth; nX++ )
                        {
                            const long nMapX = pMapX[ nX ];
                            aDstCol = pB->GetPixel( nY, nX );
                            pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetColor( nMapY, nMapX ),
                                                                 pAScan[ nMapX ] ) );
                        }
                    }
                }
                break;
            }
        }

        aBmp.ReleaseAccess( pB );
        res = aBmp;
    }

    return res;
}

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

void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha,
								  const Point& rDestPt, const Size& rDestSize,
								  const Point& rSrcPtPixel, const Size& rSrcSizePixel )
{
	const Point aNullPt;
	Point		aOutPt( LogicToPixel( rDestPt ) );
	Size        aOutSz( LogicToPixel( rDestSize ) );
	Rectangle	aDstRect( aNullPt, GetOutputSizePixel() );
	const sal_Bool	bHMirr = aOutSz.Width() < 0, bVMirr = aOutSz.Height() < 0;

	if( OUTDEV_WINDOW == meOutDevType )
	{
		const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );

		if( !aPaintRgn.IsNull() )
			aDstRect.Intersection( LogicToPixel( aPaintRgn.GetBoundRect() ) );
	}

	if( bHMirr )
	{
		aOutSz.Width() = -aOutSz.Width();
		aOutPt.X() -= ( aOutSz.Width() - 1L );
	}

	if( bVMirr )
	{
		aOutSz.Height() = -aOutSz.Height();
		aOutPt.Y() -= ( aOutSz.Height() - 1L );
	}

	if( !aDstRect.Intersection( Rectangle( aOutPt, aOutSz ) ).IsEmpty() )
	{
        bool bNativeAlpha = false;
        static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
        // #i83087# Naturally, system alpha blending cannot work with
        // separate alpha VDev
        bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr);

#ifdef WNT
        if(bTryDirectPaint)
        {
            // only paint direct when no scaling and no MapMode, else the
            // more expensive conversions may be done for short-time Bitmap/BitmapEx
            // used for buffering only
            if(!IsMapMode() && rSrcSizePixel.Width() == aOutSz.Width() && rSrcSizePixel.Height() == aOutSz.Height())
            {
                bTryDirectPaint = false;
            }
        }
#endif

        if(bTryDirectPaint) 
        {
            Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY );
            SalTwoRect aTR = {
                rSrcPtPixel.X(), rSrcPtPixel.Y(),
                rSrcSizePixel.Width(), rSrcSizePixel.Height(),
                aRelPt.X(), aRelPt.Y(),
                aOutSz.Width(), aOutSz.Height()
            };
            SalBitmap* pSalSrcBmp = rBmp.ImplGetImpBitmap()->ImplGetSalBitmap();
            SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap();
            bNativeAlpha = mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this );
        }

        VirtualDevice* pOldVDev = mpAlphaVDev;

		Rectangle aBmpRect( aNullPt, rBmp.GetSizePixel() );
		if( !bNativeAlpha
                &&  !aBmpRect.Intersection( Rectangle( rSrcPtPixel, rSrcSizePixel ) ).IsEmpty() ) 
		{
			GDIMetaFile*	pOldMetaFile = mpMetaFile; mpMetaFile = NULL;
			const sal_Bool		bOldMap = mbMap; mbMap = sal_False;
			Bitmap			aBmp( GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );

            // #109044# The generated bitmap need not necessarily be
            // of aDstRect dimensions, it's internally clipped to
            // window bounds. Thus, we correct the dest size here,
            // since we later use it (in nDstWidth/Height) for pixel
            // access)
            // #i38887# reading from screen may sometimes fail
            if( aBmp.ImplGetImpBitmap() )
                aDstRect.SetSize( aBmp.GetSizePixel() );

			BitmapColor 	aDstCol;
			const long		nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight();
			const long		nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight();
			const long		nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height();
			// calculate offset in original bitmap
			// in RTL case this is a little more complicated since the contents of the
			// bitmap is not mirrored (it never is), however the paint region and bmp region
			// are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these
			// is content wise somewhere else and needs to take mirroring into account
			const long		nOffX = IsRTLEnabled()
			                        ? aOutSz.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPt.X())
			                        : aDstRect.Left() - aOutPt.X(),
				            nOffY = aDstRect.Top() - aOutPt.Y();
			long			nX, nOutX, nY, nOutY;
			long			nMirrOffX = 0;
			long			nMirrOffY = 0;
			long*			pMapX = new long[ nDstWidth ];
			long*			pMapY = new long[ nDstHeight ];

			// create horizontal mapping table
			if( bHMirr )
				nMirrOffX = ( aBmpRect.Left() << 1 ) + nSrcWidth - 1;

			for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
			{
				pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth;
				if( bHMirr )
					pMapX[ nX ] = nMirrOffX - pMapX[ nX ];
			}
            
			// create vertical mapping table
			if( bVMirr )
				nMirrOffY = ( aBmpRect.Top() << 1 ) + nSrcHeight - 1;

			for( nY = 0L, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
			{
				pMapY[ nY ] = aBmpRect.Top() + nOutY * nSrcHeight / nOutHeight;

				if( bVMirr )
					pMapY[ nY ] = nMirrOffY - pMapY[ nY ];
			}

            BitmapReadAccess*	pP = ( (Bitmap&) rBmp ).AcquireReadAccess();
            BitmapReadAccess*	pA = ( (AlphaMask&) rAlpha ).AcquireReadAccess();

            DBG_ASSERT( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
                        pA->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK, 
                        "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );

            // #i38887# reading from screen may sometimes fail
            if( aBmp.ImplGetImpBitmap() )
            {
                Bitmap aTmp;

                if( mpAlphaVDev )
                {
                    aTmp = ImplBlendWithAlpha(
                        aBmp,pP,pA,
                        aDstRect,
                        nOffY,nDstHeight,
                        nOffX,nDstWidth,
                        pMapX,pMapY );
                }
                else
                {
                    aTmp = ImplBlend(
                        aBmp,pP,pA,
                        nOffY,nDstHeight,
                        nOffX,nDstWidth,
                        aBmpRect,aOutSz,
                        bHMirr,bVMirr,
                        pMapX,pMapY );
                }

                // #110958# Disable alpha VDev, we're doing the necessary
                // stuff explicitely furher below
                if( mpAlphaVDev )
                    mpAlphaVDev = NULL;

                DrawBitmap( aDstRect.TopLeft(), 
                            aTmp );

                // #110958# Enable alpha VDev again
                mpAlphaVDev = pOldVDev;
            }
            
            ( (Bitmap&) rBmp ).ReleaseAccess( pP );
            ( (AlphaMask&) rAlpha ).ReleaseAccess( pA );

			delete[] pMapX;
			delete[] pMapY;
			mbMap = bOldMap;
			mpMetaFile = pOldMetaFile;
		}
	}
}

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

void OutputDevice::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask,
										 const Point& rDestPt, const Size& rDestSize,
										 const Point& rSrcPtPixel, const Size& rSrcSizePixel )
{
	Point		aPt;
	Point		aDestPt( LogicToPixel( rDestPt ) );
	Size		aDestSz( LogicToPixel( rDestSize ) );
	Rectangle	aSrcRect( rSrcPtPixel, rSrcSizePixel );

	aSrcRect.Justify();

	if( !rBmp.IsEmpty() && aSrcRect.GetWidth() && aSrcRect.GetHeight() && aDestSz.Width() && aDestSz.Height() )
	{
		Bitmap	aPaint( rBmp ), aMask( rMask );
		sal_uLong	nMirrFlags = 0UL;

		if( aMask.GetBitCount() > 1 )
			aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );

		// mirrored horizontically
		if( aDestSz.Width() < 0L )
		{
			aDestSz.Width() = -aDestSz.Width();
			aDestPt.X() -= ( aDestSz.Width() - 1L );
			nMirrFlags |= BMP_MIRROR_HORZ;
		}

		// mirrored vertically
		if( aDestSz.Height() < 0L )
		{
			aDestSz.Height() = -aDestSz.Height();
			aDestPt.Y() -= ( aDestSz.Height() - 1L );
			nMirrFlags |= BMP_MIRROR_VERT;
		}

		// source cropped?
		if( aSrcRect != Rectangle( aPt, aPaint.GetSizePixel() ) )
		{
			aPaint.Crop( aSrcRect );
			aMask.Crop( aSrcRect );
		}

		// destination mirrored
		if( nMirrFlags )
		{
			aPaint.Mirror( nMirrFlags );
			aMask.Mirror( nMirrFlags );
		}

		// we always want to have a mask
		if( aMask.IsEmpty() )
		{
			aMask = Bitmap( aSrcRect.GetSize(), 1 );
			aMask.Erase( Color( COL_BLACK ) );
		}

		// do painting
        const long		nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
		long			nX, nY; // , nWorkX, nWorkY, nWorkWidth, nWorkHeight;
		long*			pMapX = new long[ nSrcWidth + 1 ];
		long*			pMapY = new long[ nSrcHeight + 1 ];
		const sal_Bool		bOldMap = mbMap;

		mbMap = sal_False;

		// create forward mapping tables
		for( nX = 0L; nX <= nSrcWidth; nX++ )
			pMapX[ nX ] = aDestPt.X() + FRound( (double) aDestSz.Width() * nX / nSrcWidth );

		for( nY = 0L; nY <= nSrcHeight; nY++ )
			pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
    
        // walk through all rectangles of mask
        const Region aWorkRgn(aMask.CreateRegion(COL_BLACK, Rectangle(Point(), aMask.GetSizePixel())));
        RectangleVector aRectangles;
        aWorkRgn.GetRegionRectangles(aRectangles);

        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
        {
            const Point aMapPt(pMapX[aRectIter->Left()], pMapY[aRectIter->Top()]);
            const Size aMapSz(
                pMapX[aRectIter->Right() + 1] - aMapPt.X(),      // pMapX[L + W] -> L + ((R - L) + 1) -> R + 1
                pMapY[aRectIter->Bottom() + 1] - aMapPt.Y());    // same for Y
            Bitmap aBandBmp(aPaint);

            aBandBmp.Crop(*aRectIter);
            ImplDrawBitmap(aMapPt, aMapSz, Point(), aBandBmp.GetSizePixel(), aBandBmp, META_BMPSCALEPART_ACTION);
        }

        //Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
		//ImplRegionInfo	aInfo;
		//sal_Bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
        //
		//while( bRgnRect )
		//{
		//	Bitmap          aBandBmp( aPaint );
        //    const Rectangle aBandRect( Point( nWorkX, nWorkY ), Size( nWorkWidth, nWorkHeight ) );
        //    const Point     aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
        //    const Size      aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
		//	
		//	aBandBmp.Crop( aBandRect );
        //    ImplDrawBitmap( aMapPt, aMapSz, Point(), aBandBmp.GetSizePixel(), aBandBmp, META_BMPSCALEPART_ACTION );
        //    bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
		//}

        mbMap = bOldMap;

        delete[] pMapX;
        delete[] pMapY;
	}
}

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

void OutputDevice::ImplPrintMask( const Bitmap& rMask, const Color& rMaskColor,
								  const Point& rDestPt, const Size& rDestSize,
								  const Point& rSrcPtPixel, const Size& rSrcSizePixel )
{
    Point		aPt;
	Point		aDestPt( LogicToPixel( rDestPt ) );
	Size		aDestSz( LogicToPixel( rDestSize ) );
	Rectangle	aSrcRect( rSrcPtPixel, rSrcSizePixel );

	aSrcRect.Justify();

	if( !rMask.IsEmpty() && aSrcRect.GetWidth() && aSrcRect.GetHeight() && aDestSz.Width() && aDestSz.Height() )
	{
		Bitmap	aMask( rMask );
		sal_uLong	nMirrFlags = 0UL;

		if( aMask.GetBitCount() > 1 )
			aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );

		// mirrored horizontically
		if( aDestSz.Width() < 0L )
		{
			aDestSz.Width() = -aDestSz.Width();
			aDestPt.X() -= ( aDestSz.Width() - 1L );
			nMirrFlags |= BMP_MIRROR_HORZ;
		}

		// mirrored vertically
		if( aDestSz.Height() < 0L )
		{
			aDestSz.Height() = -aDestSz.Height();
			aDestPt.Y() -= ( aDestSz.Height() - 1L );
			nMirrFlags |= BMP_MIRROR_VERT;
		}

		// source cropped?
		if( aSrcRect != Rectangle( aPt, aMask.GetSizePixel() ) )
			aMask.Crop( aSrcRect );

		// destination mirrored
		if( nMirrFlags )
			aMask.Mirror( nMirrFlags );

		// do painting
        const long		nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
		long			nX, nY; //, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
		long*			pMapX = new long[ nSrcWidth + 1 ];
		long*			pMapY = new long[ nSrcHeight + 1 ];
        GDIMetaFile*    pOldMetaFile = mpMetaFile;
		const sal_Bool		bOldMap = mbMap;

		mpMetaFile = NULL;
		mbMap = sal_False;
		Push( PUSH_FILLCOLOR | PUSH_LINECOLOR );
		SetLineColor( rMaskColor );
		SetFillColor( rMaskColor );
		ImplInitLineColor();
		ImplInitFillColor();

		// create forward mapping tables
		for( nX = 0L; nX <= nSrcWidth; nX++ )
			pMapX[ nX ] = aDestPt.X() + FRound( (double) aDestSz.Width() * nX / nSrcWidth );

		for( nY = 0L; nY <= nSrcHeight; nY++ )
			pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
    
        // walk through all rectangles of mask
        const Region aWorkRgn(aMask.CreateRegion(COL_BLACK, Rectangle(Point(), aMask.GetSizePixel())));
        RectangleVector aRectangles;
        aWorkRgn.GetRegionRectangles(aRectangles);

        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
        {
            const Point aMapPt(pMapX[aRectIter->Left()], pMapY[aRectIter->Top()]);
            const Size aMapSz(
                pMapX[aRectIter->Right() + 1] - aMapPt.X(),      // pMapX[L + W] -> L + ((R - L) + 1) -> R + 1
                pMapY[aRectIter->Bottom() + 1] - aMapPt.Y());    // same for Y

            DrawRect(Rectangle(aMapPt, aMapSz));
        }

        //Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
		//ImplRegionInfo	aInfo;
		//sal_Bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
        //
		//while( bRgnRect )
		//{
        //    const Point aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
        //    const Size  aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
        //
		//	DrawRect( Rectangle( aMapPt, aMapSz ) );
		//	bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
		//}

		Pop();
		delete[] pMapX;
		delete[] pMapY;
		mbMap = bOldMap;
		mpMetaFile = pOldMetaFile;
	}
}
