/**************************************************************
 * 
 * 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_svtools.hxx"

#include <vos/macros.hxx>
#include <vcl/bmpacc.hxx>
#include <tools/poly.hxx>
#include <vcl/outdev.hxx>
#include <vcl/window.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/metaact.hxx>
#include <vcl/metric.hxx>
#include <vcl/animate.hxx>
#include <vcl/alpha.hxx>
#include <vcl/virdev.hxx>
#include "grfcache.hxx"
#include <svtools/grfmgr.hxx>

// -----------
// - defines -
// -----------

#define MAX_PRINTER_EXT				1024
#define MAP( cVal0, cVal1, nFrac )	((sal_uInt8)((((long)(cVal0)<<20L)+nFrac*((long)(cVal1)-(cVal0)))>>20L))
#define WATERMARK_LUM_OFFSET		50
#define WATERMARK_CON_OFFSET		-70

// -----------
// - helpers -
// -----------

namespace {

void muckWithBitmap( const Point&    rDestPoint,
                     const Size&     rDestSize,
                     const Size&     rRefSize,
                     bool&           o_rbNonBitmapActionEncountered )
{
    const Point aEmptyPoint;

    if( aEmptyPoint != rDestPoint ||
        rDestSize != rRefSize )
    {
        // non-fullscale, or offsetted bmp -> fallback to mtf
        // rendering
        o_rbNonBitmapActionEncountered = true;
    }
}

BitmapEx muckWithBitmap( const BitmapEx& rBmpEx,
                         const Point&    rSrcPoint,
                         const Size&     rSrcSize,
                         const Point&    rDestPoint,
                         const Size&     rDestSize,
                         const Size&     rRefSize,
                         bool&           o_rbNonBitmapActionEncountered )
{
    BitmapEx aBmpEx;

    muckWithBitmap(rDestPoint,
                   rDestSize,
                   rRefSize,
                   o_rbNonBitmapActionEncountered);

    if( o_rbNonBitmapActionEncountered )
        return aBmpEx;

    aBmpEx = rBmpEx;

    if( (rSrcPoint.X() != 0 && rSrcPoint.Y() != 0) ||
        rSrcSize != rBmpEx.GetSizePixel() )
    {
        // crop bitmap to given source rectangle (no
        // need to copy and convert the whole bitmap)
        const Rectangle aCropRect( rSrcPoint,
                                   rSrcSize );
        aBmpEx.Crop( aCropRect );
    }

    return aBmpEx;
}

} // namespace {


// ------------------
// - GraphicManager -
// ------------------

GraphicManager::GraphicManager( sal_uLong nCacheSize, sal_uLong nMaxObjCacheSize ) :
		mpCache( new GraphicCache( *this, nCacheSize, nMaxObjCacheSize ) )
{
}

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

GraphicManager::~GraphicManager()
{
	for( void* pObj = maObjList.First(); pObj; pObj = maObjList.Next() )
		( (GraphicObject*) pObj )->GraphicManagerDestroyed();

	delete mpCache;
}

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

void GraphicManager::SetMaxCacheSize( sal_uLong nNewCacheSize )
{
	mpCache->SetMaxDisplayCacheSize( nNewCacheSize );
}

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

sal_uLong GraphicManager::GetMaxCacheSize() const
{
	return mpCache->GetMaxDisplayCacheSize();
}

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

void GraphicManager::SetMaxObjCacheSize( sal_uLong nNewMaxObjSize, sal_Bool bDestroyGreaterCached )
{
	mpCache->SetMaxObjDisplayCacheSize( nNewMaxObjSize, bDestroyGreaterCached );
}

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

sal_uLong GraphicManager::GetMaxObjCacheSize() const
{
	return mpCache->GetMaxObjDisplayCacheSize();
}

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

sal_uLong GraphicManager::GetUsedCacheSize() const 
{ 
	return mpCache->GetUsedDisplayCacheSize(); 
}

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

sal_uLong GraphicManager::GetFreeCacheSize() const
{
	return mpCache->GetFreeDisplayCacheSize();
}

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

void GraphicManager::SetCacheTimeout( sal_uLong nTimeoutSeconds )
{
	mpCache->SetCacheTimeout( nTimeoutSeconds );
}

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

sal_uLong GraphicManager::GetCacheTimeout() const
{
	return mpCache->GetCacheTimeout();
}

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

void GraphicManager::ClearCache()
{
	mpCache->ClearDisplayCache();
}

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

void GraphicManager::ReleaseFromCache( const GraphicObject& /*rObj*/ )
{
	// !!!
}

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

sal_Bool GraphicManager::IsInCache( OutputDevice* pOut, const Point& rPt,
									const Size& rSz, const GraphicObject& rObj, 
									const GraphicAttr& rAttr ) const
{
	return mpCache->IsInDisplayCache( pOut, rPt, rSz, rObj, rAttr );
}

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

sal_Bool GraphicManager::DrawObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
							  GraphicObject& rObj, const GraphicAttr& rAttr,
							  const sal_uLong nFlags, sal_Bool& rCached )
{
	Point   aPt( rPt );
	Size	aSz( rSz );
	sal_Bool	bRet = sal_False;

	rCached = sal_False;

	if( ( rObj.GetType() == GRAPHIC_BITMAP ) || ( rObj.GetType() == GRAPHIC_GDIMETAFILE ) )
	{
		// create output and fill cache
		const Size aOutSize( pOut->GetOutputSizePixel() );

		if( rObj.IsAnimated() || ( pOut->GetOutDevType() == OUTDEV_PRINTER ) ||
		    ( !( nFlags & GRFMGR_DRAW_NO_SUBSTITUTE ) &&
		      ( ( nFlags & GRFMGR_DRAW_SUBSTITUTE ) ||
		        !( nFlags & GRFMGR_DRAW_CACHED ) ||
		        ( pOut->GetConnectMetaFile() && !pOut->IsOutputEnabled() ) ) ) )
		{
			// simple output of transformed graphic
			const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );

			if( aGraphic.IsSupportedGraphic() )
			{
				const sal_uInt16 nRot10 = rAttr.GetRotation() % 3600;
	
				if( nRot10 )
				{
					Polygon aPoly( Rectangle( aPt, aSz ) );

					aPoly.Rotate( aPt, nRot10 );
					const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
					aPt = aRotBoundRect.TopLeft();
					aSz = aRotBoundRect.GetSize();
				}

				aGraphic.Draw( pOut, aPt, aSz );
			}

			bRet = sal_True;
		}

		if( !bRet )
		{
			// cached/direct drawing
			if( !mpCache->DrawDisplayCacheObj( pOut, aPt, aSz, rObj, rAttr ) )
				bRet = ImplDraw( pOut, aPt, aSz, rObj, rAttr, nFlags, rCached );
			else
				bRet = rCached = sal_True;
		}
	}

	return bRet;
}

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

void GraphicManager::ImplRegisterObj( const GraphicObject& rObj, Graphic& rSubstitute,
                                      const ByteString* pID, const GraphicObject* pCopyObj )
{
	maObjList.Insert( (void*) &rObj, LIST_APPEND );
	mpCache->AddGraphicObject( rObj, rSubstitute, pID, pCopyObj );
}

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

void GraphicManager::ImplUnregisterObj( const GraphicObject& rObj )
{
	mpCache->ReleaseGraphicObject( rObj );
	maObjList.Remove( (void*) &rObj );
}

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

void GraphicManager::ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj )
{
	mpCache->GraphicObjectWasSwappedOut( rObj );
}

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

ByteString GraphicManager::ImplGetUniqueID( const GraphicObject& rObj ) const
{
	return mpCache->GetUniqueID( rObj );
}

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

sal_Bool GraphicManager::ImplFillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
{
	return( mpCache->FillSwappedGraphicObject( rObj, rSubstitute ) );
}

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

void GraphicManager::ImplGraphicObjectWasSwappedIn( const GraphicObject& rObj )
{
	mpCache->GraphicObjectWasSwappedIn( rObj );
}

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

sal_Bool GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
							   const Size& rSz, GraphicObject& rObj,
							   const GraphicAttr& rAttr, 
                               const sal_uLong nFlags, sal_Bool& rCached )
{
	const Graphic&	rGraphic = rObj.GetGraphic();
	sal_Bool			bRet = sal_False;

	if( rGraphic.IsSupportedGraphic() && !rGraphic.IsSwapOut() )
	{
		if( GRAPHIC_BITMAP == rGraphic.GetType() )
		{
			const BitmapEx aSrcBmpEx( rGraphic.GetBitmapEx() );

            // #i46805# No point in caching a bitmap that is rendered
            // via RectFill on the OutDev
			if( !(pOut->GetDrawMode() & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP )) &&
                mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
			{
				BitmapEx aDstBmpEx;

				if( ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags, &aDstBmpEx ) )
				{
					rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
					bRet = sal_True;
				}
			}

			if( !bRet )
				bRet = ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags );
		}
		else
		{
			const GDIMetaFile& rSrcMtf = rGraphic.GetGDIMetaFile();

			if( mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
			{
				GDIMetaFile aDstMtf;
                BitmapEx    aContainedBmpEx;

				if( ImplCreateOutput( pOut, rPt, rSz, rSrcMtf, rAttr, nFlags, aDstMtf, aContainedBmpEx ) )
				{
                    if( !!aContainedBmpEx )
                    {
                        // #117889# Use bitmap output method, if
                        // metafile basically contains only a single
                        // bitmap
                        BitmapEx aDstBmpEx;

                        if( ImplCreateOutput( pOut, rPt, rSz, aContainedBmpEx, rAttr, nFlags, &aDstBmpEx ) )
                        {
                            rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
                            bRet = sal_True;
                        }
                    }
                    else
                    {
                        rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstMtf );
                        bRet = sal_True;
                    }
				}
			}

			if( !bRet )
			{
				const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );

				if( aGraphic.IsSupportedGraphic() )
				{
					aGraphic.Draw( pOut, rPt, rSz );
					bRet = sal_True;
				}
			}
		}
	}

	return bRet;
}

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

sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut, 
                                       const Point& rPt, const Size& rSz,
									   const BitmapEx& rBmpEx, const GraphicAttr& rAttr,
									   const sal_uLong nFlags, BitmapEx* pBmpEx )
{
	sal_uInt16	nRot10 = rAttr.GetRotation() % 3600;
	Point	aOutPtPix;
	Size	aOutSzPix;
	Size	aUnrotatedSzPix( pOut->LogicToPixel( rSz ) );
	sal_Bool	bRet = sal_False;

	if( nRot10 )
	{
		Polygon aPoly( Rectangle( rPt, rSz ) );

		aPoly.Rotate( rPt, nRot10 );
		const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
		aOutPtPix = pOut->LogicToPixel( aRotBoundRect.TopLeft() );
		aOutSzPix = pOut->LogicToPixel( aRotBoundRect.GetSize() );
	}
	else
	{
		aOutPtPix = pOut->LogicToPixel( rPt );
		aOutSzPix = aUnrotatedSzPix;
	}

	if( aUnrotatedSzPix.Width() && aUnrotatedSzPix.Height() )
	{
		BitmapEx		aBmpEx( rBmpEx );
		BitmapEx		aOutBmpEx;
		Point			aOutPt;
		Size			aOutSz;
		const Size&		rBmpSzPix = rBmpEx.GetSizePixel();
		const long		nW = rBmpSzPix.Width();
		const long		nH = rBmpSzPix.Height();
		const long		nNewW = aUnrotatedSzPix.Width();
		const long		nNewH = aUnrotatedSzPix.Height();
		double			fTmp;
		long*			pMapIX = new long[ nNewW ];
		long*			pMapFX = new long[ nNewW ];
		long*			pMapIY = new long[ nNewH ];
		long*			pMapFY = new long[ nNewH ];
		long			nStartX = -1, nStartY = -1, nEndX = -1, nEndY = -1;
		long			nX, nY, nTmp, nTmpX, nTmpY;
		sal_Bool			bHMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
		sal_Bool			bVMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;

        if( nFlags & GRFMGR_DRAW_BILINEAR )
        {
            const double	fRevScaleX = ( nNewW > 1L ) ? ( (double) ( nW - 1L ) / ( nNewW - 1L ) ) : 0.0;
            const double	fRevScaleY = ( nNewH > 1L ) ? ( (double) ( nH - 1L ) / ( nNewH - 1L ) ) : 0.0;

            // create horizontal mapping table
            for( nX = 0L, nTmpX = nW - 1L, nTmp = nW - 2L; nX < nNewW; nX++ )
            {
                fTmp = nX * fRevScaleX;

                if( bHMirr )
                    fTmp = nTmpX - fTmp;

                pMapFX[ nX ] = (long) ( ( fTmp - ( pMapIX[ nX ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
            }

            // create vertical mapping table
            for( nY = 0L, nTmpY = nH - 1L, nTmp = nH - 2L; nY < nNewH; nY++ )
            {
                fTmp = nY * fRevScaleY;

                if( bVMirr )
                    fTmp = nTmpY - fTmp;

                pMapFY[ nY ] = (long) ( ( fTmp - ( pMapIY[ nY ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
            }
        }
        else
        {
            // #98290# Use a different mapping for non-interpolating mode, to avoid missing rows/columns
            const double	fRevScaleX = ( nNewW > 1L ) ? ( (double) nW / nNewW ) : 0.0;
            const double	fRevScaleY = ( nNewH > 1L ) ? ( (double) nH / nNewH ) : 0.0;

            // create horizontal mapping table
            for( nX = 0L, nTmpX = nW - 1L, nTmp = nW - 2L; nX < nNewW; nX++ )
            {
                fTmp = nX * fRevScaleX;

                if( bHMirr )
                    fTmp = nTmpX - fTmp;

                // #98290# Do not use round to zero, otherwise last column will be missing
                pMapIX[ nX ] = MinMax( (long) fTmp, 0, nTmp );
                pMapFX[ nX ] = fTmp >= nTmp+1 ? 1048576 : 0;
            }

            // create vertical mapping table
            for( nY = 0L, nTmpY = nH - 1L, nTmp = nH - 2L; nY < nNewH; nY++ )
            {
                fTmp = nY * fRevScaleY;

                if( bVMirr )
                    fTmp = nTmpY - fTmp;

                // #98290# Do not use round to zero, otherwise last row will be missing
                pMapIY[ nY ] = MinMax( (long) fTmp, 0, nTmp );
                pMapFY[ nY ] = fTmp >= nTmp+1 ? 1048576 : 0;
            }
        }

        // calculate output sizes
		if( !pBmpEx )
		{
			Point		aPt;
			Rectangle	aOutRect( aPt, pOut->GetOutputSizePixel() );
			Rectangle	aBmpRect( aOutPtPix, aOutSzPix );

			if( pOut->GetOutDevType() == OUTDEV_WINDOW )
			{
				const Region aPaintRgn( ( (Window*) pOut )->GetPaintRegion() );
				if( !aPaintRgn.IsNull() )
					aOutRect.Intersection( pOut->LogicToPixel( aPaintRgn.GetBoundRect() ) );
			}

			aOutRect.Intersection( aBmpRect );

			if( !aOutRect.IsEmpty() )
			{
				aOutPt = pOut->PixelToLogic( aOutRect.TopLeft() );
				aOutSz = pOut->PixelToLogic( aOutRect.GetSize() );
				nStartX = aOutRect.Left() - aBmpRect.Left();
				nStartY = aOutRect.Top() - aBmpRect.Top();
				nEndX = aOutRect.Right() - aBmpRect.Left();
				nEndY = aOutRect.Bottom() - aBmpRect.Top();
			}
			else
				nStartX = -1L; // invalid
		}
		else
		{
			aOutPt = pOut->PixelToLogic( aOutPtPix );
			aOutSz = pOut->PixelToLogic( aOutSzPix );
			nStartX = nStartY = 0;
			nEndX = aOutSzPix.Width() - 1L;
			nEndY = aOutSzPix.Height() - 1L;
		}

		// do transformation
		if( nStartX >= 0L )
		{
			const sal_Bool bSimple = ( 1 == nW || 1 == nH );

			if( nRot10 )
			{
				if( bSimple )
				{
					bRet = ( aOutBmpEx = aBmpEx ).Scale( aUnrotatedSzPix );

					if( bRet )
						aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
				}
				else
				{
					bRet = ImplCreateRotatedScaled( aBmpEx,
													nRot10, aOutSzPix, aUnrotatedSzPix,
													pMapIX, pMapFX, pMapIY, pMapFY, nStartX, nEndX, nStartY, nEndY,
													aOutBmpEx );
				}
			}
			else
			{
                // #105229# Don't scale if output size equals bitmap size
                // #107226# Copy through only if we're not mirroring
                if( !bHMirr && !bVMirr && aOutSzPix == rBmpSzPix )
                {
                    // #107226# Use original dimensions when just copying through
                    aOutPt = pOut->PixelToLogic( aOutPtPix );
                    aOutSz = pOut->PixelToLogic( aOutSzPix );
                    aOutBmpEx = aBmpEx;
                    bRet = sal_True;
                }
                else
                {
                    if( bSimple )
                        bRet = ( aOutBmpEx = aBmpEx ).Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ) );
                    else
                    {
                        bRet = ImplCreateScaled( aBmpEx,
                                                 pMapIX, pMapFX, pMapIY, pMapFY,
                                                 nStartX, nEndX, nStartY, nEndY,
                                                 aOutBmpEx );
                    }
                }
			}

			if( bRet )
			{
				// attribute adjustment if neccessary
				if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsTransparent() )
					ImplAdjust( aOutBmpEx, rAttr, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );

				// OutDev adjustment if neccessary
				if( pOut->GetOutDevType() != OUTDEV_PRINTER && pOut->GetBitCount() <= 8 && aOutBmpEx.GetBitCount() >= 8 )
					aOutBmpEx.Dither( BMP_DITHER_MATRIX );
			}
		}

		// delete lookup tables
		delete[] pMapIX;
		delete[] pMapFX;
		delete[] pMapIY;
		delete[] pMapFY;

		// create output
		if( bRet )
		{
			if( !pBmpEx )
				pOut->DrawBitmapEx( aOutPt, aOutSz, aOutBmpEx );
			else
			{
				if( !rAttr.IsTransparent() && !aOutBmpEx.IsAlpha() )
					aOutBmpEx = BitmapEx( aOutBmpEx.GetBitmap().CreateDisplayBitmap( pOut ), aOutBmpEx.GetMask() );

				pOut->DrawBitmapEx( aOutPt, aOutSz, *pBmpEx = aOutBmpEx );
			}
		}
	}

	return bRet;
}

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

sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
									   const Point& rPt, const Size& rSz,
									   const GDIMetaFile& rMtf, const GraphicAttr& rAttr,
									   const sal_uLong /*nFlags*/, GDIMetaFile& rOutMtf, BitmapEx& rOutBmpEx )
{
    const Size aNewSize( rMtf.GetPrefSize() );

    rOutMtf = rMtf;

    // #117889# count bitmap actions, and flag actions that paint, but
    // are no bitmaps.
    sal_Int32   nNumBitmaps(0);
    bool        bNonBitmapActionEncountered(false);
    if( aNewSize.Width() && aNewSize.Height() && rSz.Width() && rSz.Height() )
    {
        const double fGrfWH = (double) aNewSize.Width() / aNewSize.Height();
        const double fOutWH = (double) rSz.Width() / rSz.Height();

        const double fScaleX = fOutWH / fGrfWH;
        const double fScaleY = 1.0;

        const MapMode& rPrefMapMode( rMtf.GetPrefMapMode() );
        const Size&    rSizePix( pOut->LogicToPixel( aNewSize,
                                                     rPrefMapMode ) );

        // taking care of font width default if scaling metafile.
        // #117889# use existing metafile scan, to determine whether
        // the metafile basically displays a single bitmap. Note that
        // the solution, as implemented here, is quite suboptimal (the
        // cases where a mtf consisting basically of a single bitmap,
        // that fail to pass the test below, are probably frequent). A
        // better solution would involve FSAA, but that's currently
        // expensive, and might trigger bugs on display drivers, if
        // VDevs get bigger than the actual screen.
        sal_uInt32  nCurPos;
        MetaAction* pAct;
        for( nCurPos = 0, pAct = (MetaAction*)rOutMtf.FirstAction(); pAct;
             pAct = (MetaAction*)rOutMtf.NextAction(), nCurPos++ )
        {
            MetaAction* pModAct = NULL;
            switch( pAct->GetType() )
            {
                case META_FONT_ACTION:
                {
                    MetaFontAction* pA = (MetaFontAction*)pAct;
                    Font aFont( pA->GetFont() );
                    if ( !aFont.GetWidth() )
                    {
                        FontMetric aFontMetric( pOut->GetFontMetric( aFont ) );
                        aFont.SetWidth( aFontMetric.GetWidth() );
                        pModAct = new MetaFontAction( aFont );
                    }
                }
                    // FALLTHROUGH intended
                case META_NULL_ACTION:
                    // FALLTHROUGH intended

                    // OutDev state changes (which don't affect bitmap
                    // output)
                case META_LINECOLOR_ACTION:
                    // FALLTHROUGH intended
                case META_FILLCOLOR_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTCOLOR_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTFILLCOLOR_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTALIGN_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTLINECOLOR_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTLINE_ACTION:
                    // FALLTHROUGH intended
                case META_PUSH_ACTION:
                    // FALLTHROUGH intended
                case META_POP_ACTION:
                    // FALLTHROUGH intended
                case META_LAYOUTMODE_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTLANGUAGE_ACTION:
                    // FALLTHROUGH intended
                case META_COMMENT_ACTION:
                    break;

                    // bitmap output methods
                case META_BMP_ACTION:
                    if( !nNumBitmaps && !bNonBitmapActionEncountered )
                    {
                        MetaBmpAction* pAction = (MetaBmpAction*)pAct;

                        rOutBmpEx = BitmapEx( pAction->GetBitmap() );
                        muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
                                                            rPrefMapMode ),
                                        pAction->GetBitmap().GetSizePixel(),
                                        rSizePix,
                                        bNonBitmapActionEncountered );
                        ++nNumBitmaps;
                    }
                    break;

                case META_BMPSCALE_ACTION:
                    if( !nNumBitmaps && !bNonBitmapActionEncountered )
                    {
                        MetaBmpScaleAction* pAction = (MetaBmpScaleAction*)pAct;

                        rOutBmpEx = BitmapEx( pAction->GetBitmap() );
                        muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
                                                            rPrefMapMode ),
                                        pOut->LogicToPixel( pAction->GetSize(),
                                                            rPrefMapMode ),
                                        rSizePix,
                                        bNonBitmapActionEncountered );
                        ++nNumBitmaps;
                    }
                    break;

                case META_BMPSCALEPART_ACTION:
                    if( !nNumBitmaps && !bNonBitmapActionEncountered )
                    {
                        MetaBmpScalePartAction* pAction = (MetaBmpScalePartAction*)pAct;

                        rOutBmpEx = muckWithBitmap( BitmapEx( pAction->GetBitmap() ),
                                                    pAction->GetSrcPoint(),
                                                    pAction->GetSrcSize(),
                                                    pOut->LogicToPixel( pAction->GetDestPoint(),
                                                                        rPrefMapMode ),
                                                    pOut->LogicToPixel( pAction->GetDestSize(),
                                                                        rPrefMapMode ),
                                                    rSizePix,
                                                    bNonBitmapActionEncountered );
                        ++nNumBitmaps;
                    }
                    break;

                case META_BMPEX_ACTION:
                    if( !nNumBitmaps && !bNonBitmapActionEncountered )
                    {
                        MetaBmpExAction* pAction = (MetaBmpExAction*)pAct;

                        rOutBmpEx = pAction->GetBitmapEx();
                        muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
                                                            rPrefMapMode ),
                                        pAction->GetBitmapEx().GetSizePixel(),
                                        rSizePix,
                                        bNonBitmapActionEncountered );
                        ++nNumBitmaps;
                    }
                    break;

                case META_BMPEXSCALE_ACTION:
                    if( !nNumBitmaps && !bNonBitmapActionEncountered )
                    {
                        MetaBmpExScaleAction* pAction = (MetaBmpExScaleAction*)pAct;

                        rOutBmpEx = pAction->GetBitmapEx();
                        muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
                                                            rPrefMapMode ),
                                        pOut->LogicToPixel( pAction->GetSize(),
                                                            rPrefMapMode ),
                                        rSizePix,
                                        bNonBitmapActionEncountered );
                        ++nNumBitmaps;
                    }
                    break;

                case META_BMPEXSCALEPART_ACTION:
                    if( !nNumBitmaps && !bNonBitmapActionEncountered )
                    {
                        MetaBmpExScalePartAction* pAction = (MetaBmpExScalePartAction*)pAct;

                        rOutBmpEx = muckWithBitmap( pAction->GetBitmapEx(),
                                                    pAction->GetSrcPoint(),
                                                    pAction->GetSrcSize(),
                                                    pOut->LogicToPixel( pAction->GetDestPoint(),
                                                                        rPrefMapMode ),
                                                    pOut->LogicToPixel( pAction->GetDestSize(),
                                                                        rPrefMapMode ),
                                                    rSizePix,
                                                    bNonBitmapActionEncountered );
                        ++nNumBitmaps;
                    }
                    break;

                    // these actions actually output something (that's
                    // different from a bitmap)
                case META_RASTEROP_ACTION:
                    if( ((MetaRasterOpAction*)pAct)->GetRasterOp() == ROP_OVERPAINT )
                        break;
                    // FALLTHROUGH intended
                case META_PIXEL_ACTION:
                    // FALLTHROUGH intended
                case META_POINT_ACTION:
                    // FALLTHROUGH intended
                case META_LINE_ACTION:
                    // FALLTHROUGH intended
                case META_RECT_ACTION:
                    // FALLTHROUGH intended
                case META_ROUNDRECT_ACTION:
                    // FALLTHROUGH intended
                case META_ELLIPSE_ACTION:
                    // FALLTHROUGH intended
                case META_ARC_ACTION:
                    // FALLTHROUGH intended
                case META_PIE_ACTION:
                    // FALLTHROUGH intended
                case META_CHORD_ACTION:
                    // FALLTHROUGH intended
                case META_POLYLINE_ACTION:
                    // FALLTHROUGH intended
                case META_POLYGON_ACTION:
                    // FALLTHROUGH intended
                case META_POLYPOLYGON_ACTION:
                    // FALLTHROUGH intended

                case META_TEXT_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTARRAY_ACTION:
                    // FALLTHROUGH intended
                case META_STRETCHTEXT_ACTION:
                    // FALLTHROUGH intended
                case META_TEXTRECT_ACTION:
                    // FALLTHROUGH intended

                case META_MASK_ACTION:
                    // FALLTHROUGH intended
                case META_MASKSCALE_ACTION:
                    // FALLTHROUGH intended
                case META_MASKSCALEPART_ACTION:
                    // FALLTHROUGH intended

                case META_GRADIENT_ACTION:
                    // FALLTHROUGH intended
                case META_HATCH_ACTION:
                    // FALLTHROUGH intended
                case META_WALLPAPER_ACTION:
                    // FALLTHROUGH intended

                case META_TRANSPARENT_ACTION:
                    // FALLTHROUGH intended
                case META_EPS_ACTION:
                    // FALLTHROUGH intended
                case META_FLOATTRANSPARENT_ACTION:
                    // FALLTHROUGH intended
                case META_GRADIENTEX_ACTION:
                    // FALLTHROUGH intended

                    // OutDev state changes that _do_ affect bitmap
                    // output
                case META_CLIPREGION_ACTION:
                    // FALLTHROUGH intended
                case META_ISECTRECTCLIPREGION_ACTION:
                    // FALLTHROUGH intended
                case META_ISECTREGIONCLIPREGION_ACTION:
                    // FALLTHROUGH intended
                case META_MOVECLIPREGION_ACTION:
                    // FALLTHROUGH intended

                case META_MAPMODE_ACTION:
                    // FALLTHROUGH intended
                case META_REFPOINT_ACTION:
                    // FALLTHROUGH intended
                default:
                    bNonBitmapActionEncountered = true;
                    break;
            }
            if ( pModAct )
            {
                rOutMtf.ReplaceAction( pModAct, nCurPos );
                pAct->Delete();
            }
            else
            {
                if( pAct->GetRefCount() > 1 )
                {
                    rOutMtf.ReplaceAction( pModAct = pAct->Clone(), nCurPos );
                    pAct->Delete();
                }
                else
                    pModAct = pAct;
            }
            pModAct->Scale( fScaleX, fScaleY );
        }
        rOutMtf.SetPrefSize( Size( FRound( aNewSize.Width() * fScaleX ),
                                   FRound( aNewSize.Height() * fScaleY ) ) );
    }

    if( nNumBitmaps != 1 || bNonBitmapActionEncountered )
    {
        if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsMirrored() || rAttr.IsRotated() || rAttr.IsTransparent() )
            ImplAdjust( rOutMtf, rAttr, ADJUSTMENT_ALL );

        ImplDraw( pOut, rPt, rSz, rOutMtf, rAttr );
        rOutBmpEx = BitmapEx();
    }

    return sal_True;
}

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

sal_Bool GraphicManager::ImplCreateScaled( const BitmapEx& rBmpEx,
									   long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY,
									   long nStartX, long nEndX, long nStartY, long nEndY,
									   BitmapEx& rOutBmpEx )
{
	Bitmap				aBmp( rBmpEx.GetBitmap() );
	Bitmap				aOutBmp;
	BitmapReadAccess*	pAcc = aBmp.AcquireReadAccess();
	BitmapWriteAccess*	pWAcc;
	BitmapColor			aCol0, aCol1, aColRes;
	const long			nDstW = nEndX - nStartX + 1L;
	const long			nDstH = nEndY - nStartY + 1L;
	long				nX, nY, nTmpX, nTmpY, nTmpFX, nTmpFY;
	long				nXDst, nYDst;
	sal_uInt8				cR0, cG0, cB0, cR1, cG1, cB1;
	sal_Bool				bRet = sal_False;

    DBG_ASSERT( aBmp.GetSizePixel() == rBmpEx.GetSizePixel(),
                "GraphicManager::ImplCreateScaled(): bmp size inconsistent" );

	if( pAcc )
	{
		aOutBmp = Bitmap( Size( nDstW, nDstH ), 24 );
		pWAcc = aOutBmp.AcquireWriteAccess();

		if( pWAcc )
		{
			if( pAcc->HasPalette() )
			{
				if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
				{
					Scanline pLine0, pLine1;

					for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
					{
						nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
						pLine0 = pAcc->GetScanline( nTmpY );
						pLine1 = pAcc->GetScanline( ++nTmpY );

						for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
						{
							nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];

							const BitmapColor& rCol0 = pAcc->GetPaletteColor( pLine0[ nTmpX ] );
							const BitmapColor& rCol2 = pAcc->GetPaletteColor( pLine1[ nTmpX ] );
							const BitmapColor& rCol1 = pAcc->GetPaletteColor( pLine0[ ++nTmpX ] );
							const BitmapColor& rCol3 = pAcc->GetPaletteColor( pLine1[ nTmpX ] );

							cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
							cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
							cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );

							cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
							cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
							cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );

							aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
							aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
							aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
							pWAcc->SetPixel( nYDst, nXDst++, aColRes );
						}
					}
				}
				else
				{
					for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
					{
						nTmpY = pMapIY[ nY ], nTmpFY = pMapFY[ nY ];

						for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
						{
							nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];

							aCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, nTmpX ) );
							aCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, ++nTmpX ) );
							cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
							cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
							cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );

							aCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( ++nTmpY, nTmpX ) );
							aCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY--, --nTmpX ) );
							cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
							cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
							cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );

							aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
							aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
							aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
							pWAcc->SetPixel( nYDst, nXDst++, aColRes );
						}
					}
				}
			}
			else
			{
				if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
				{
					Scanline	pLine0, pLine1, pTmp0, pTmp1;
					long		nOff;

					for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
					{
						nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
						pLine0 = pAcc->GetScanline( nTmpY );
						pLine1 = pAcc->GetScanline( ++nTmpY );

						for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
						{
							nOff = 3L * ( nTmpX = pMapIX[ nX ] );
							nTmpFX = pMapFX[ nX ];

							pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
							cB0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cG0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cR0 = MAP( *pTmp0, *pTmp1, nTmpFX );

							pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
							cB1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cG1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cR1 = MAP( *pTmp0, *pTmp1, nTmpFX );

							aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
							aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
							aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
							pWAcc->SetPixel( nYDst, nXDst++, aColRes );
						}
					}
				}
				else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
				{
					Scanline	pLine0, pLine1, pTmp0, pTmp1;
					long		nOff;

					for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
					{
						nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
						pLine0 = pAcc->GetScanline( nTmpY );
						pLine1 = pAcc->GetScanline( ++nTmpY );

						for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
						{
							nOff = 3L * ( nTmpX = pMapIX[ nX ] );
							nTmpFX = pMapFX[ nX ];

							pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
							cR0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cG0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cB0 = MAP( *pTmp0, *pTmp1, nTmpFX );

							pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
							cR1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cG1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
							cB1 = MAP( *pTmp0, *pTmp1, nTmpFX );

							aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
							aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
							aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
							pWAcc->SetPixel( nYDst, nXDst++, aColRes );
						}
					}
				}
				else
				{
					for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
					{
						nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];

						for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
						{
							nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];

							aCol0 = pAcc->GetPixel( nTmpY, nTmpX );
							aCol1 = pAcc->GetPixel( nTmpY, ++nTmpX );
							cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
							cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
							cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );

							aCol1 = pAcc->GetPixel( ++nTmpY, nTmpX );
							aCol0 = pAcc->GetPixel( nTmpY--, --nTmpX );
							cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
							cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
							cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );

							aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
							aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
							aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
							pWAcc->SetPixel( nYDst, nXDst++, aColRes );
						}
					}
				}
			}

			aOutBmp.ReleaseAccess( pWAcc );
			bRet = sal_True;
		}

		aBmp.ReleaseAccess( pAcc );
	}

	if( bRet && rBmpEx.IsTransparent() )
	{
		bRet = sal_False;

		if( rBmpEx.IsAlpha() )
		{
            DBG_ASSERT( rBmpEx.GetAlpha().GetSizePixel() == rBmpEx.GetSizePixel(),
                        "GraphicManager::ImplCreateScaled(): alpha mask size inconsistent" );

			AlphaMask	aAlpha( rBmpEx.GetAlpha() );
			AlphaMask	aOutAlpha;

			pAcc = aAlpha.AcquireReadAccess();

			if( pAcc )
			{
				aOutAlpha = AlphaMask( Size( nDstW, nDstH ) );
				pWAcc = aOutAlpha.AcquireWriteAccess();

				if( pWAcc )
				{
					if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
						pWAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
					{
						Scanline pLine0, pLine1, pLineW;

						for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
						{
							nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
							pLine0 = pAcc->GetScanline( nTmpY );
							pLine1 = pAcc->GetScanline( ++nTmpY );
							pLineW = pWAcc->GetScanline( nYDst );

							for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++, nXDst++ )
							{
								nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];

								const long	nAlpha0 = pLine0[ nTmpX ];
								const long	nAlpha2 = pLine1[ nTmpX ];
								const long	nAlpha1 = pLine0[ ++nTmpX ];
								const long	nAlpha3 = pLine1[ nTmpX ];
								const long	n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
								const long	n1 = MAP( nAlpha2, nAlpha3, nTmpFX );

								*pLineW++ = MAP( n0, n1, nTmpFY );
							}
						}
					}
					else
					{
						BitmapColor aAlphaValue( 0 );

						for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
						{
							nTmpY = pMapIY[ nY ], nTmpFY = pMapFY[ nY ];

							for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
							{
								nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];

								long		nAlpha0 = pAcc->GetPixel( nTmpY, nTmpX ).GetIndex();
								long		nAlpha1 = pAcc->GetPixel( nTmpY, ++nTmpX ).GetIndex();
								const long	n0 = MAP( nAlpha0, nAlpha1, nTmpFX );

								nAlpha1 = pAcc->GetPixel( ++nTmpY, nTmpX ).GetIndex();
								nAlpha0 = pAcc->GetPixel( nTmpY--, --nTmpX ).GetIndex();
								const long	n1 = MAP( nAlpha0, nAlpha1, nTmpFX );

								aAlphaValue.SetIndex( MAP( n0, n1, nTmpFY ) );
								pWAcc->SetPixel( nYDst, nXDst++, aAlphaValue );
							}
						}
					}

					aOutAlpha.ReleaseAccess( pWAcc );
					bRet = sal_True;
				}

				aAlpha.ReleaseAccess( pAcc );

				if( bRet )
					rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
			}
		}
		else
		{
            DBG_ASSERT( rBmpEx.GetMask().GetSizePixel() == rBmpEx.GetSizePixel(),
                        "GraphicManager::ImplCreateScaled(): mask size inconsistent" );

			Bitmap	aMsk( rBmpEx.GetMask() );
			Bitmap	aOutMsk;

			pAcc = aMsk.AcquireReadAccess();

			if( pAcc )
			{
                // #i40115# Use the same palette for destination
                // bitmap. Otherwise, we'd have to color-map even the
                // case below, when both masks are one bit deep.
                if( pAcc->HasPalette() )
                    aOutMsk = Bitmap( Size( nDstW, nDstH ),
                                      1,
                                      &pAcc->GetPalette() );
                else
                    aOutMsk = Bitmap( Size( nDstW, nDstH ), 1 );

				pWAcc = aOutMsk.AcquireWriteAccess();

				if( pWAcc )
				{
					long* pMapLX = new long[ nDstW ];
					long* pMapLY = new long[ nDstH ];

					// create new horizontal mapping table
					for( nX = 0UL, nTmpX = nStartX; nX < nDstW; nTmpX++ )
						pMapLX[ nX++ ] = FRound( (double) pMapIX[ nTmpX ] + pMapFX[ nTmpX ] / 1048576. );

					// create new vertical mapping table
					for( nY = 0UL, nTmpY = nStartY; nY < nDstH; nTmpY++ )
						pMapLY[ nY++ ] = FRound( (double) pMapIY[ nTmpY ] + pMapFY[ nTmpY ] / 1048576. );

					// do normal scaling
					if( pAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
						pWAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL )
					{
						// optimized
						for( nY = 0; nY < nDstH; nY++ )
						{
							Scanline pSrc = pAcc->GetScanline( pMapLY[ nY ] );
							Scanline pDst = pWAcc->GetScanline( nY );

							for( nX = 0L; nX < nDstW; nX++ )
							{
								const long nSrcX = pMapLX[ nX ];

								if( pSrc[ nSrcX >> 3 ] & ( 1 << ( 7 - ( nSrcX & 7 ) ) ) )
									pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
								else
									pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
							}
						}
					}
					else
					{
						const BitmapColor aB( pAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
						const BitmapColor aWB( pWAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
						const BitmapColor aWW( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );

						if( pAcc->HasPalette() )
						{
							for( nY = 0L; nY < nDstH; nY++ )
							{
								for( nX = 0L; nX < nDstW; nX++ )
								{
									if( pAcc->GetPaletteColor( (sal_uInt8) pAcc->GetPixel( pMapLY[ nY ], pMapLX[ nX ] ) ) == aB )
										pWAcc->SetPixel( nY, nX, aWB );
									else
										pWAcc->SetPixel( nY, nX, aWW );
								}
							}
						}
						else
						{
							for( nY = 0L; nY < nDstH; nY++ )
							{
								for( nX = 0L; nX < nDstW; nX++ )
								{
									if( pAcc->GetPixel( pMapLY[ nY ], pMapLX[ nX ] ) == aB )
										pWAcc->SetPixel( nY, nX, aWB );
									else
										pWAcc->SetPixel( nY, nX, aWW );
								}
							}
						}
					}

					delete[] pMapLX;
					delete[] pMapLY;
					aOutMsk.ReleaseAccess( pWAcc );
					bRet = sal_True;
				}

				aMsk.ReleaseAccess( pAcc );

				if( bRet )
					rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
			}
		}

		if( !bRet )
			rOutBmpEx = aOutBmp;
	}
	else
		rOutBmpEx = aOutBmp;

	return bRet;
}

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

sal_Bool GraphicManager::ImplCreateRotatedScaled( const BitmapEx& rBmpEx,
											  sal_uInt16 nRot10, const Size& /*rOutSzPix*/, const Size& rUnrotatedSzPix,
											  long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY,
											  long nStartX, long nEndX, long nStartY, long nEndY,
											  BitmapEx& rOutBmpEx )
{
	Point				aPt;
	Bitmap				aBmp( rBmpEx.GetBitmap() );
	Bitmap				aOutBmp;
	BitmapReadAccess*	pAcc = aBmp.AcquireReadAccess();
	BitmapWriteAccess*	pWAcc;
	Polygon				aPoly( Rectangle( aPt, rUnrotatedSzPix ) ); aPoly.Rotate( Point(), nRot10 );
	Rectangle			aNewBound( aPoly.GetBoundRect() );
	const double		fCosAngle = cos( nRot10 * F_PI1800 ), fSinAngle = sin( nRot10 * F_PI1800 );
	double				fTmp;
	const long			nDstW = nEndX - nStartX + 1L;
	const long			nDstH = nEndY - nStartY + 1L;
	const long			nUnRotW = rUnrotatedSzPix.Width();
	const long			nUnRotH = rUnrotatedSzPix.Height();
	long*				pCosX = new long[ nDstW ];
	long*				pSinX = new long[ nDstW ];
	long*				pCosY = new long[ nDstH ];
	long*				pSinY = new long[ nDstH ];
	long				nX, nY, nTmpX, nTmpY, nTmpFX, nTmpFY, nUnRotX, nUnRotY, nSinY, nCosY;
	sal_uInt8				cR0, cG0, cB0, cR1, cG1, cB1;
	sal_Bool				bRet = sal_False;

	// create horizontal mapping table
	for( nX = 0L, nTmpX = aNewBound.Left() + nStartX; nX < nDstW; nX++ )
	{
		pCosX[ nX ] = FRound( fCosAngle * ( fTmp = nTmpX++ << 8 ) );
		pSinX[ nX ] = FRound( fSinAngle * fTmp );
	}

	// create vertical mapping table
	for( nY = 0L, nTmpY = aNewBound.Top() + nStartY; nY < nDstH; nY++ )
	{
		pCosY[ nY ] = FRound( fCosAngle * ( fTmp = nTmpY++ << 8 ) );
		pSinY[ nY ] = FRound( fSinAngle * fTmp );
	}

	if( pAcc )
	{
		aOutBmp = Bitmap( Size( nDstW, nDstH ), 24 );
		pWAcc = aOutBmp.AcquireWriteAccess();

		if( pWAcc )
		{
			BitmapColor aColRes;

			if( pAcc->HasPalette() )
			{
				for( nY = 0; nY < nDstH; nY++ )
				{
					nSinY = pSinY[ nY ];
					nCosY = pCosY[ nY ];

					for( nX = 0; nX < nDstW; nX++ )
					{
						nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
						nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;

						if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
							( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
						{
							nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
							nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];

							const BitmapColor& rCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, nTmpX ) );
							const BitmapColor& rCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, ++nTmpX ) );
							cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
							cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
							cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );

							const BitmapColor& rCol3 = pAcc->GetPaletteColor( pAcc->GetPixel( ++nTmpY, nTmpX ) );
							const BitmapColor& rCol2 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, --nTmpX ) );
							cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
							cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
							cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );

							aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
							aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
							aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
							pWAcc->SetPixel( nY, nX, aColRes );
						}
					}
				}
			}
			else
			{
				BitmapColor	aCol0, aCol1;

				for( nY = 0; nY < nDstH; nY++ )
				{
					nSinY = pSinY[ nY ];
					nCosY = pCosY[ nY ];

					for( nX = 0; nX < nDstW; nX++ )
					{
						nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
						nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;

						if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
							( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
						{
							nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
							nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];

							aCol0 = pAcc->GetPixel( nTmpY, nTmpX );
							aCol1 = pAcc->GetPixel( nTmpY, ++nTmpX );
							cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
							cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
							cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );

							aCol1 = pAcc->GetPixel( ++nTmpY, nTmpX );
							aCol0 = pAcc->GetPixel( nTmpY, --nTmpX );
							cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
							cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
							cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );

							aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
							aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
							aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
							pWAcc->SetPixel( nY, nX, aColRes );
						}
					}
				}
			}

			aOutBmp.ReleaseAccess( pWAcc );
			bRet = sal_True;
		}

		aBmp.ReleaseAccess( pAcc );
	}

	// mask processing
	if( bRet && ( rBmpEx.IsTransparent() || ( nRot10 != 900 && nRot10 != 1800 && nRot10 != 2700 ) ) )
	{
		bRet = sal_False;

		if( rBmpEx.IsAlpha() )
		{
			AlphaMask	aAlpha( rBmpEx.GetAlpha() );
			AlphaMask	aOutAlpha;

			pAcc = aAlpha.AcquireReadAccess();

			if( pAcc )
			{
				aOutAlpha = AlphaMask( Size( nDstW, nDstH ) );
				pWAcc = aOutAlpha.AcquireWriteAccess();

				if( pWAcc )
				{
					if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
						pWAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
					{
						Scanline pLine0, pLine1, pLineW;

						for( nY = 0; nY < nDstH; nY++ )
						{
							nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];
							pLineW = pWAcc->GetScanline( nY );

							for( nX = 0; nX < nDstW; nX++ )
							{
								nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
								nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;

								if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
									( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
								{
									nTmpX = pMapIX[ nUnRotX ], nTmpFX = pMapFX[ nUnRotX ];
									nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];

									pLine0 = pAcc->GetScanline( nTmpY++ );
									pLine1 = pAcc->GetScanline( nTmpY );

									const long	nAlpha0 = pLine0[ nTmpX ];
									const long	nAlpha2 = pLine1[ nTmpX++ ];
									const long	nAlpha1 = pLine0[ nTmpX ];
									const long	nAlpha3 = pLine1[ nTmpX ];
									const long	n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
									const long	n1 = MAP( nAlpha2, nAlpha3, nTmpFX );

									*pLineW++ = MAP( n0, n1, nTmpFY );
								}
								else
									*pLineW++ = 255;
							}
						}
					}
					else
					{
						const BitmapColor	aTrans( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
						BitmapColor			aAlphaVal( 0 );

						for( nY = 0; nY < nDstH; nY++ )
						{
							nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];

							for( nX = 0; nX < nDstW; nX++ )
							{
								nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
								nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;

								if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
									( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
								{
									nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
									nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];

									const long	nAlpha0 = pAcc->GetPixel( nTmpY, nTmpX ).GetIndex();
									const long	nAlpha1 = pAcc->GetPixel( nTmpY, ++nTmpX ).GetIndex();
									const long	nAlpha3 = pAcc->GetPixel( ++nTmpY, nTmpX ).GetIndex();
									const long	nAlpha2 = pAcc->GetPixel( nTmpY, --nTmpX ).GetIndex();
									const long 	n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
									const long 	n1 = MAP( nAlpha2, nAlpha3, nTmpFX );

									aAlphaVal.SetIndex( MAP( n0, n1, nTmpFY ) );
									pWAcc->SetPixel( nY, nX, aAlphaVal );
								}
								else
									pWAcc->SetPixel( nY, nX, aTrans );
							}
						}
					}

					aOutAlpha.ReleaseAccess( pWAcc );
					bRet = sal_True;
				}

				aAlpha.ReleaseAccess( pAcc );
			}

			if( bRet )
				rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
		}
		else
		{
			Bitmap aOutMsk( Size( nDstW, nDstH ), 1 );
			pWAcc = aOutMsk.AcquireWriteAccess();

			if( pWAcc )
			{
				Bitmap				aMsk( rBmpEx.GetMask() );
				const BitmapColor	aB( pWAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
				const BitmapColor	aW( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
				BitmapReadAccess*	pMAcc = NULL;

				if( !aMsk || ( ( pMAcc = aMsk.AcquireReadAccess() ) != NULL ) )
				{
					long*		pMapLX = new long[ nUnRotW ];
					long*		pMapLY = new long[ nUnRotH ];
					BitmapColor	aTestB;

					if( pMAcc )
						aTestB = pMAcc->GetBestMatchingColor( Color( COL_BLACK ) );

					// create new horizontal mapping table
					for( nX = 0UL; nX < nUnRotW; nX++ )
						pMapLX[ nX ] = FRound( (double) pMapIX[ nX ] + pMapFX[ nX ] / 1048576. );

					// create new vertical mapping table
					for( nY = 0UL; nY < nUnRotH; nY++ )
						pMapLY[ nY ] = FRound( (double) pMapIY[ nY ] + pMapFY[ nY ] / 1048576. );

					// do mask rotation
					for( nY = 0; nY < nDstH; nY++ )
					{
						nSinY = pSinY[ nY ];
						nCosY = pCosY[ nY ];

						for( nX = 0; nX < nDstW; nX++ )
						{
							nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
							nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;

							if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
								( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
							{
								if( pMAcc )
								{
									if( pMAcc->GetPixel( pMapLY[ nUnRotY ], pMapLX[ nUnRotX ] ) == aTestB )
										pWAcc->SetPixel( nY, nX, aB );
									else
										pWAcc->SetPixel( nY, nX, aW );
								}
								else
									pWAcc->SetPixel( nY, nX, aB );
							}
							else
								pWAcc->SetPixel( nY, nX, aW );
						}
					}

					delete[] pMapLX;
					delete[] pMapLY;

					if( pMAcc )
						aMsk.ReleaseAccess( pMAcc );

					bRet = sal_True;
				}

				aOutMsk.ReleaseAccess( pWAcc );
			}

			if( bRet )
				rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
		}

		if( !bRet )
			rOutBmpEx = aOutBmp;
	}
	else
		rOutBmpEx = aOutBmp;

	delete[] pSinX;
	delete[] pCosX;
	delete[] pSinY;
	delete[] pCosY;

	return bRet;
}

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

void GraphicManager::ImplAdjust( BitmapEx& rBmpEx, const GraphicAttr& rAttr, sal_uLong nAdjustmentFlags )
{
	GraphicAttr aAttr( rAttr );

	if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
	{
		switch( aAttr.GetDrawMode() )
		{
			case( GRAPHICDRAWMODE_MONO ):
				rBmpEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
			break;

			case( GRAPHICDRAWMODE_GREYS ):
				rBmpEx.Convert( BMP_CONVERSION_8BIT_GREYS );
			break;

			case( GRAPHICDRAWMODE_WATERMARK ):
			{
				aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
				aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
			}
			break;

			default:
			break;
		}
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
	{
		rBmpEx.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
					   aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
					   aAttr.GetGamma(), aAttr.IsInvert() );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
	{
		rBmpEx.Mirror( aAttr.GetMirrorFlags() );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
	{
		rBmpEx.Rotate( aAttr.GetRotation(), Color( COL_TRANSPARENT ) );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
	{
		AlphaMask	aAlpha;
		sal_uInt8		cTrans = aAttr.GetTransparency();

		if( !rBmpEx.IsTransparent() )
			aAlpha = AlphaMask( rBmpEx.GetSizePixel(), &cTrans );
		else if( !rBmpEx.IsAlpha() )
		{
			aAlpha = rBmpEx.GetMask();
			aAlpha.Replace( 0, cTrans );
		}
		else
		{
			aAlpha = rBmpEx.GetAlpha();
			BitmapWriteAccess* pA = aAlpha.AcquireWriteAccess();

			if( pA )
			{
				sal_uLong		nTrans = cTrans, nNewTrans;
				const long	nWidth = pA->Width(), nHeight = pA->Height();

				if( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
				{
					for( long nY = 0; nY < nHeight; nY++ )
					{
						Scanline pAScan = pA->GetScanline( nY );

						for( long nX = 0; nX < nWidth; nX++ )
						{
							nNewTrans = nTrans + *pAScan;
							*pAScan++ = (sal_uInt8) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans );
						}
					}
				}
				else
				{
					BitmapColor aAlphaValue( 0 );

					for( long nY = 0; nY < nHeight; nY++ )
					{
						for( long nX = 0; nX < nWidth; nX++ )
						{
							nNewTrans = nTrans + pA->GetPixel( nY, nX ).GetIndex();
							aAlphaValue.SetIndex( (sal_uInt8) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans ) );
							pA->SetPixel( nY, nX, aAlphaValue );
						}
					}
				}

				aAlpha.ReleaseAccess( pA );
			}
		}

		rBmpEx = BitmapEx( rBmpEx.GetBitmap(), aAlpha );
	}
}

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

void GraphicManager::ImplAdjust( GDIMetaFile& rMtf, const GraphicAttr& rAttr, sal_uLong nAdjustmentFlags )
{
	GraphicAttr aAttr( rAttr );

	if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
	{
		switch( aAttr.GetDrawMode() )
		{
			case( GRAPHICDRAWMODE_MONO ):
				rMtf.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
			break;

			case( GRAPHICDRAWMODE_GREYS ):
				rMtf.Convert( MTF_CONVERSION_8BIT_GREYS );
			break;

			case( GRAPHICDRAWMODE_WATERMARK ):
			{
				aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
				aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
			}
			break;

			default:
			break;
		}
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
	{
		rMtf.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
					 aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
					 aAttr.GetGamma(), aAttr.IsInvert() );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
	{
        rMtf.Mirror( aAttr.GetMirrorFlags() );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
	{
		rMtf.Rotate( aAttr.GetRotation() );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
	{
		DBG_WARNING( "Missing implementation: Mtf-Transparency" );
	}
}

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

void GraphicManager::ImplAdjust( Animation& rAnimation, const GraphicAttr& rAttr, sal_uLong nAdjustmentFlags )
{
	GraphicAttr aAttr( rAttr );

	if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
	{
		switch( aAttr.GetDrawMode() )
		{
			case( GRAPHICDRAWMODE_MONO ):
				rAnimation.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
			break;

			case( GRAPHICDRAWMODE_GREYS ):
				rAnimation.Convert( BMP_CONVERSION_8BIT_GREYS );
			break;

			case( GRAPHICDRAWMODE_WATERMARK ):
			{
				aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
				aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
			}
			break;

			default:
			break;
		}
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
	{
		rAnimation.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
						   aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
						   aAttr.GetGamma(), aAttr.IsInvert() );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
    {
		rAnimation.Mirror( aAttr.GetMirrorFlags() );
    }

	if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
	{
		DBG_ERROR( "Missing implementation: Animation-Rotation" );
	}

	if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
	{
		DBG_ERROR( "Missing implementation: Animation-Transparency" );
	}
}

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

void GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
							   const GDIMetaFile& rMtf, const GraphicAttr& rAttr )
{
   	sal_uInt16	nRot10 = rAttr.GetRotation() % 3600;
    Point	aOutPt( rPt );
    Size	aOutSz( rSz );

    if( nRot10 )
    {
		Polygon aPoly( Rectangle( aOutPt, aOutSz ) );

		aPoly.Rotate( aOutPt, nRot10 );
		const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
		aOutPt = aRotBoundRect.TopLeft();
		aOutSz = aRotBoundRect.GetSize();
	}

	pOut->Push( PUSH_CLIPREGION );
	pOut->IntersectClipRegion( Rectangle( aOutPt, aOutSz ) );

	( (GDIMetaFile&) rMtf ).WindStart();
	( (GDIMetaFile&) rMtf ).Play( pOut, aOutPt, aOutSz );
	( (GDIMetaFile&) rMtf ).WindStart();

	pOut->Pop();
}

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

struct ImplTileInfo
{
    ImplTileInfo() : aTileTopLeft(), aNextTileTopLeft(), aTileSizePixel(), nTilesEmptyX(0), nTilesEmptyY(0) {}

    Point aTileTopLeft;   	// top, left position of the rendered tile
    Point aNextTileTopLeft; // top, left position for next recursion
                            // level's tile
    Size  aTileSizePixel;   // size of the generated tile (might
                            // differ from
                            // aNextTileTopLeft-aTileTopLeft, because
                            // this is nExponent*prevTileSize. The
                            // generated tile is always nExponent
                            // times the previous tile, such that it
                            // can be used in the next stage. The
                            // required area coverage is often
                            // less. The extraneous area covered is
                            // later overwritten by the next stage)
    int	  nTilesEmptyX;     // number of original tiles empty right of
                            // this tile. This counts from
                            // aNextTileTopLeft, i.e. the additional
                            // area covered by aTileSizePixel is not
                            // considered here. This is for
                            // unification purposes, as the iterative
                            // calculation of the next level's empty
                            // tiles has to be based on this value.
    int	  nTilesEmptyY;     // as above, for Y
};


bool GraphicObject::ImplRenderTempTile( VirtualDevice& rVDev, int nExponent, 
                                        int nNumTilesX, int nNumTilesY, 
                                        const Size& rTileSizePixel, 
                                        const GraphicAttr* pAttr, sal_uLong nFlags )
{
    if( nExponent <= 1 )
        return false;

    // determine MSB factor
    int nMSBFactor( 1 );
    while( nNumTilesX / nMSBFactor != 0 ||
           nNumTilesY / nMSBFactor != 0 )
    {
        nMSBFactor *= nExponent;
    }

    // one less
    nMSBFactor /= nExponent;

    ImplTileInfo aTileInfo;

    // #105229# Switch off mapping (converting to logic and back to
    // pixel might cause roundoff errors)
    sal_Bool bOldMap( rVDev.IsMapModeEnabled() );
    rVDev.EnableMapMode( sal_False );

    bool bRet( ImplRenderTileRecursive( rVDev, nExponent, nMSBFactor, nNumTilesX, nNumTilesY,
                                        nNumTilesX, nNumTilesY, rTileSizePixel, pAttr, nFlags, aTileInfo ) );

    rVDev.EnableMapMode( bOldMap );

    return bRet;
}

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

// define for debug drawings
//#define DBG_TEST

// see header comment. this works similar to base conversion of a
// number, i.e. if the exponent is 10, then the number for every tile
// size is given by the decimal place of the corresponding decimal
// representation.
bool GraphicObject::ImplRenderTileRecursive( VirtualDevice& rVDev, int nExponent, int nMSBFactor,
                                             int nNumOrigTilesX, int nNumOrigTilesY, 
                                             int nRemainderTilesX, int nRemainderTilesY, 
                                             const Size& rTileSizePixel, const GraphicAttr* pAttr, 
                                             sal_uLong nFlags, ImplTileInfo& rTileInfo )
{
    // gets loaded with our tile bitmap
    GraphicObject aTmpGraphic;

    // stores a flag that renders the zero'th tile position
    // (i.e. (0,0)+rCurrPos) only if we're at the bottom of the
    // recursion stack. All other position already have that tile
    // rendered, because the lower levels painted their generated tile
    // there.
    bool bNoFirstTileDraw( false );

    // what's left when we're done with our tile size
    const int nNewRemainderX( nRemainderTilesX % nMSBFactor );
    const int nNewRemainderY( nRemainderTilesY % nMSBFactor );

    // gets filled out from the recursive call with info of what's
    // been generated
    ImplTileInfo aTileInfo;

    // current output position while drawing
    Point aCurrPos;
    int nX, nY;

    // check for recursion's end condition: LSB place reached?
    if( nMSBFactor == 1 )
    {
        aTmpGraphic = *this;

        // set initial tile size -> orig size
        aTileInfo.aTileSizePixel = rTileSizePixel;
        aTileInfo.nTilesEmptyX = nNumOrigTilesX;
        aTileInfo.nTilesEmptyY = nNumOrigTilesY;
    }
    else if( ImplRenderTileRecursive( rVDev, nExponent, nMSBFactor/nExponent,
                                      nNumOrigTilesX, nNumOrigTilesY,
                                      nNewRemainderX, nNewRemainderY,
                                      rTileSizePixel, pAttr, nFlags, aTileInfo ) )
    {
        // extract generated tile -> see comment on the first loop below
        BitmapEx aTileBitmap( rVDev.GetBitmap( aTileInfo.aTileTopLeft, aTileInfo.aTileSizePixel ) );

        aTmpGraphic = GraphicObject( aTileBitmap );

        // fill stripes left over from upstream levels:
        //
        //  x0000
        //  0
        //  0
        //  0
        //  0
        //
        // where x denotes the place filled by our recursive predecessors

        // check whether we have to fill stripes here. Although not
        // obvious, there is one case where we can skip this step: if
        // the previous recursion level (the one who filled our
        // aTileInfo) had zero area to fill, then there are no white
        // stripes left, naturally. This happens if the digit
        // associated to that level has a zero, and can be checked via
        // aTileTopLeft==aNextTileTopLeft.
        if( aTileInfo.aTileTopLeft != aTileInfo.aNextTileTopLeft )
        {
            // now fill one row from aTileInfo.aNextTileTopLeft.X() all
            // the way to the right
            aCurrPos.X() = aTileInfo.aNextTileTopLeft.X();
            aCurrPos.Y() = aTileInfo.aTileTopLeft.Y();
            for( nX=0; nX < aTileInfo.nTilesEmptyX; nX += nMSBFactor )
            {
                if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
                    return false;

                aCurrPos.X() += aTileInfo.aTileSizePixel.Width();
            }

#ifdef DBG_TEST
//    		rVDev.SetFillColor( COL_WHITE );
            rVDev.SetFillColor();
            rVDev.SetLineColor( Color( 255 * nExponent / nMSBFactor, 255 - 255 * nExponent / nMSBFactor, 128 - 255 * nExponent / nMSBFactor ) );
            rVDev.DrawEllipse( Rectangle(aTileInfo.aNextTileTopLeft.X(), aTileInfo.aTileTopLeft.Y(),
                                         aTileInfo.aNextTileTopLeft.X() - 1 + (aTileInfo.nTilesEmptyX/nMSBFactor)*aTileInfo.aTileSizePixel.Width(),
                                         aTileInfo.aTileTopLeft.Y() + aTileInfo.aTileSizePixel.Height() - 1) );
#endif

            // now fill one column from aTileInfo.aNextTileTopLeft.Y() all
            // the way to the bottom
            aCurrPos.X() = aTileInfo.aTileTopLeft.X();
            aCurrPos.Y() = aTileInfo.aNextTileTopLeft.Y();
            for( nY=0; nY < aTileInfo.nTilesEmptyY; nY += nMSBFactor )
            {
                if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
                    return false;

                aCurrPos.Y() += aTileInfo.aTileSizePixel.Height();
            }

#ifdef DBG_TEST
            rVDev.DrawEllipse( Rectangle(aTileInfo.aTileTopLeft.X(), aTileInfo.aNextTileTopLeft.Y(),
                                         aTileInfo.aTileTopLeft.X() + aTileInfo.aTileSizePixel.Width() - 1,
                                         aTileInfo.aNextTileTopLeft.Y() - 1 + (aTileInfo.nTilesEmptyY/nMSBFactor)*aTileInfo.aTileSizePixel.Height()) );
#endif
        }
        else
        {
            // Thought that aTileInfo.aNextTileTopLeft tile has always
            // been drawn already, but that's wrong: typically,
            // _parts_ of that tile have been drawn, since the
            // previous level generated the tile there. But when
            // aTileInfo.aNextTileTopLeft!=aTileInfo.aTileTopLeft, the
            // difference between these two values is missing in the
            // lower right corner of this first tile. So, can do that
            // only here.
            bNoFirstTileDraw = true;
        }
    }
    else
    {
        return false;
    }

    // calc number of original tiles in our drawing area without
    // remainder
    nRemainderTilesX -= nNewRemainderX;
    nRemainderTilesY -= nNewRemainderY;

    // fill tile info for calling method
    rTileInfo.aTileTopLeft 	   = aTileInfo.aNextTileTopLeft;
    rTileInfo.aNextTileTopLeft = Point( rTileInfo.aTileTopLeft.X() + rTileSizePixel.Width()*nRemainderTilesX,
                                        rTileInfo.aTileTopLeft.Y() + rTileSizePixel.Height()*nRemainderTilesY );
    rTileInfo.aTileSizePixel   = Size( rTileSizePixel.Width()*nMSBFactor*nExponent,
                                       rTileSizePixel.Height()*nMSBFactor*nExponent );
    rTileInfo.nTilesEmptyX	   = aTileInfo.nTilesEmptyX - nRemainderTilesX;
    rTileInfo.nTilesEmptyY	   = aTileInfo.nTilesEmptyY - nRemainderTilesY;

    // init output position
    aCurrPos = aTileInfo.aNextTileTopLeft;

    // fill our drawing area. Fill possibly more, to create the next
    // bigger tile size -> see bitmap extraction above. This does no
    // harm, since everything right or below our actual area is
    // overdrawn by our caller. Just in case we're in the last level,
    // we don't draw beyond the right or bottom border.
    for( nY=0; nY < aTileInfo.nTilesEmptyY && nY < nExponent*nMSBFactor; nY += nMSBFactor )
    {
        aCurrPos.X() = aTileInfo.aNextTileTopLeft.X();

        for( nX=0; nX < aTileInfo.nTilesEmptyX && nX < nExponent*nMSBFactor; nX += nMSBFactor )
        {
            if( bNoFirstTileDraw )
                bNoFirstTileDraw = false; // don't draw first tile position
            else if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
                return false;

            aCurrPos.X() += aTileInfo.aTileSizePixel.Width();
        }

        aCurrPos.Y() += aTileInfo.aTileSizePixel.Height();
    }

#ifdef DBG_TEST
//  rVDev.SetFillColor( COL_WHITE );
    rVDev.SetFillColor();
    rVDev.SetLineColor( Color( 255 * nExponent / nMSBFactor, 255 - 255 * nExponent / nMSBFactor, 128 - 255 * nExponent / nMSBFactor ) );
    rVDev.DrawRect( Rectangle((rTileInfo.aTileTopLeft.X())*rTileSizePixel.Width(),
                              (rTileInfo.aTileTopLeft.Y())*rTileSizePixel.Height(),
                              (rTileInfo.aNextTileTopLeft.X())*rTileSizePixel.Width()-1,
                              (rTileInfo.aNextTileTopLeft.Y())*rTileSizePixel.Height()-1) );
#endif

    return true;
}

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

bool GraphicObject::ImplDrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSizePixel,
                                   const Size& rOffset, const GraphicAttr* pAttr, sal_uLong nFlags, int nTileCacheSize1D )
{
    // how many tiles to generate per recursion step
    enum{ SubdivisionExponent=2 };

    const MapMode 	aOutMapMode( pOut->GetMapMode() );
    const MapMode	aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() );
    bool 			bRet( false );

    // #i42643# Casting to Int64, to avoid integer overflow for
    // huge-DPI output devices
    if( GetGraphic().GetType() == GRAPHIC_BITMAP &&
        static_cast<sal_Int64>(rSizePixel.Width()) * rSizePixel.Height() <
        static_cast<sal_Int64>(nTileCacheSize1D)*nTileCacheSize1D )
    {
        // First combine very small bitmaps into a larger tile
        // ===================================================

        VirtualDevice	aVDev;
        const int		nNumTilesInCacheX( (nTileCacheSize1D + rSizePixel.Width()-1) / rSizePixel.Width() );
        const int		nNumTilesInCacheY( (nTileCacheSize1D + rSizePixel.Height()-1) / rSizePixel.Height() );

        aVDev.SetOutputSizePixel( Size( nNumTilesInCacheX*rSizePixel.Width(),
                                        nNumTilesInCacheY*rSizePixel.Height() ) );
        aVDev.SetMapMode( aMapMode );

        // draw bitmap content
        if( ImplRenderTempTile( aVDev, SubdivisionExponent, nNumTilesInCacheX,
                                nNumTilesInCacheY, rSizePixel, pAttr, nFlags ) )
        {
            BitmapEx aTileBitmap( aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ) );

            // draw alpha content, if any
            if( IsTransparent() )
            {
                GraphicObject aAlphaGraphic;

                if( GetGraphic().IsAlpha() )
                    aAlphaGraphic.SetGraphic( GetGraphic().GetBitmapEx().GetAlpha().GetBitmap() );
                else
                    aAlphaGraphic.SetGraphic( GetGraphic().GetBitmapEx().GetMask() );

                if( aAlphaGraphic.ImplRenderTempTile( aVDev, SubdivisionExponent, nNumTilesInCacheX,
                                                      nNumTilesInCacheY, rSizePixel, pAttr, nFlags ) )
                {
                    // Combine bitmap and alpha/mask
                    if( GetGraphic().IsAlpha() )
                        aTileBitmap = BitmapEx( aTileBitmap.GetBitmap(),
                                                AlphaMask( aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ) ) );
                    else
                        aTileBitmap = BitmapEx( aTileBitmap.GetBitmap(),
                                                aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ).CreateMask( Color(COL_WHITE) ) );
                }
            }

            // paint generated tile
            GraphicObject aTmpGraphic( aTileBitmap );
            bRet = aTmpGraphic.ImplDrawTiled( pOut, rArea,
                                              aTileBitmap.GetSizePixel(),
                                              rOffset, pAttr, nFlags, nTileCacheSize1D );
        }
    }
    else
    {
        const Size		aOutOffset( pOut->LogicToPixel( rOffset, aOutMapMode ) );
        const Rectangle	aOutArea( pOut->LogicToPixel( rArea, aOutMapMode ) );

        // number of invisible (because out-of-area) tiles
        int nInvisibleTilesX;
        int nInvisibleTilesY;

        // round towards -infty for negative offset
        if( aOutOffset.Width() < 0 )
            nInvisibleTilesX = (aOutOffset.Width() - rSizePixel.Width() + 1) / rSizePixel.Width();
        else
            nInvisibleTilesX = aOutOffset.Width() / rSizePixel.Width();

        // round towards -infty for negative offset
        if( aOutOffset.Height() < 0 )
            nInvisibleTilesY = (aOutOffset.Height() - rSizePixel.Height() + 1) / rSizePixel.Height();
        else
            nInvisibleTilesY = aOutOffset.Height() / rSizePixel.Height();

        // origin from where to 'virtually' start drawing in pixel
        const Point aOutOrigin( pOut->LogicToPixel( Point( rArea.Left() - rOffset.Width(),
                                                           rArea.Top() - rOffset.Height() ) ) );
        // position in pixel from where to really start output
        const Point aOutStart( aOutOrigin.X() + nInvisibleTilesX*rSizePixel.Width(),
                               aOutOrigin.Y() + nInvisibleTilesY*rSizePixel.Height() );

        pOut->Push( PUSH_CLIPREGION );
        pOut->IntersectClipRegion( rArea );

        // Paint all tiles
        // ===============

        bRet = ImplDrawTiled( *pOut, aOutStart,
                              (aOutArea.GetWidth() + aOutArea.Left() - aOutStart.X() + rSizePixel.Width() - 1) / rSizePixel.Width(),
                              (aOutArea.GetHeight() + aOutArea.Top() - aOutStart.Y() + rSizePixel.Height() - 1) / rSizePixel.Height(),
                              rSizePixel, pAttr, nFlags );

        pOut->Pop();
    }

    return bRet;
}

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

bool GraphicObject::ImplDrawTiled( OutputDevice& rOut, const Point& rPosPixel, 
                                   int nNumTilesX, int nNumTilesY, 
                                   const Size& rTileSizePixel, const GraphicAttr* pAttr, sal_uLong nFlags )
{
    Point 	aCurrPos( rPosPixel );
    Size	aTileSizeLogic( rOut.PixelToLogic( rTileSizePixel ) );
    int 	nX, nY;

    // #107607# Use logical coordinates for metafile playing, too
    bool	bDrawInPixel( rOut.GetConnectMetaFile() == NULL && GRAPHIC_BITMAP == GetType() );
    sal_Bool	bRet( sal_False );

    // #105229# Switch off mapping (converting to logic and back to
    // pixel might cause roundoff errors)
    sal_Bool bOldMap( rOut.IsMapModeEnabled() );

    if( bDrawInPixel )
        rOut.EnableMapMode( sal_False );

    for( nY=0; nY < nNumTilesY; ++nY )
    {
        aCurrPos.X() = rPosPixel.X();

        for( nX=0; nX < nNumTilesX; ++nX )
        {
            // #105229# work with pixel coordinates here, mapping is disabled!
            // #104004# don't disable mapping for metafile recordings
            // #108412# don't quit the loop if one draw fails

            // update return value. This method should return true, if
            // at least one of the looped Draws succeeded.
            bRet |= Draw( &rOut,
                          bDrawInPixel ? aCurrPos : rOut.PixelToLogic( aCurrPos ),
                          bDrawInPixel ? rTileSizePixel : aTileSizeLogic,
                          pAttr, nFlags );

            aCurrPos.X() += rTileSizePixel.Width();
        }

        aCurrPos.Y() += rTileSizePixel.Height();
    }

    if( bDrawInPixel )
        rOut.EnableMapMode( bOldMap );

    return bRet;
}

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

void GraphicObject::ImplTransformBitmap( BitmapEx& 			rBmpEx,
                                         const GraphicAttr& rAttr,
                                         const Size&		rCropLeftTop,
                                         const Size&		rCropRightBottom,
                                         const Rectangle&	rCropRect,
                                         const Size& 		rDstSize,
                                         sal_Bool				bEnlarge ) const
{
    // #107947# Extracted from svdograf.cxx

    // #104115# Crop the bitmap
    if( rAttr.IsCropped() )
    {
        rBmpEx.Crop( rCropRect );

        // #104115# Negative crop sizes mean: enlarge bitmap and pad
        if( bEnlarge && (
            rCropLeftTop.Width() < 0 ||
            rCropLeftTop.Height() < 0 ||
            rCropRightBottom.Width() < 0 ||
            rCropRightBottom.Height() < 0 ) )
        {
            Size aBmpSize( rBmpEx.GetSizePixel() );
            sal_Int32 nPadLeft( rCropLeftTop.Width() < 0 ? -rCropLeftTop.Width() : 0 );
            sal_Int32 nPadTop( rCropLeftTop.Height() < 0 ? -rCropLeftTop.Height() : 0 );
            sal_Int32 nPadTotalWidth( aBmpSize.Width() + nPadLeft + (rCropRightBottom.Width() < 0 ? -rCropRightBottom.Width() : 0) );
            sal_Int32 nPadTotalHeight( aBmpSize.Height() + nPadTop + (rCropRightBottom.Height() < 0 ? -rCropRightBottom.Height() : 0) );

            BitmapEx aBmpEx2;

            if( rBmpEx.IsTransparent() )
            {
                if( rBmpEx.IsAlpha() )
                    aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), rBmpEx.GetAlpha() );
                else
                    aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), rBmpEx.GetMask() );
            }
            else
            {
                // #104115# Generate mask bitmap and init to zero
                Bitmap aMask( aBmpSize, 1 );
                aMask.Erase( Color(0,0,0) );

                // #104115# Always generate transparent bitmap, we need the border transparent
                aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), aMask );

                // #104115# Add opaque mask to source bitmap, otherwise the destination remains transparent
                rBmpEx = aBmpEx2;
            }

            aBmpEx2.SetSizePixel( Size(nPadTotalWidth, nPadTotalHeight) );
            aBmpEx2.Erase( Color(0xFF,0,0,0) );
            aBmpEx2.CopyPixel( Rectangle( Point(nPadLeft, nPadTop), aBmpSize ), Rectangle( Point(0, 0), aBmpSize ), &rBmpEx );
            rBmpEx = aBmpEx2;
        }
    }

    const Size 	aSizePixel( rBmpEx.GetSizePixel() );

    if( rAttr.GetRotation() != 0 && !IsAnimated() )
    {
        if( aSizePixel.Width() && aSizePixel.Height() && rDstSize.Width() && rDstSize.Height() )
        {
            double fSrcWH = (double) aSizePixel.Width() / aSizePixel.Height();
            double fDstWH = (double) rDstSize.Width() / rDstSize.Height();
            double fScaleX = 1.0, fScaleY = 1.0;

            // always choose scaling to shrink bitmap
            if( fSrcWH < fDstWH )
                fScaleY = aSizePixel.Width() / ( fDstWH * aSizePixel.Height() );
            else
                fScaleX = fDstWH * aSizePixel.Height() / aSizePixel.Width();

            rBmpEx.Scale( fScaleX, fScaleY );
        }
    }
}
