/**************************************************************
 * 
 * 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 "winmtf.hxx"
#include <vcl/metaact.hxx>
#include <vcl/metric.hxx>
#include <rtl/tencinfo.h>
#include <vcl/svapp.hxx>
#include <vcl/virdev.hxx>
#include <vos/mutex.hxx>

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

#define WIN_MTF_MAX_CLIP_DEPTH 16

void WinMtfClipPath::ImpUpdateType()
{
	if ( !aPolyPoly.Count() )
		eType = EMPTY;
	else if ( aPolyPoly.IsRect() )
		eType = RECTANGLE;
	else
		eType = COMPLEX;

	bNeedsUpdate = sal_True;
}

void WinMtfClipPath::IntersectClipRect( const Rectangle& rRect )
{
	if ( !aPolyPoly.Count() )
		aPolyPoly = Polygon( rRect );
	else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH )
	{
		Polygon aPolygon( rRect );
		PolyPolygon aIntersection;
		PolyPolygon aPolyPolyRect( aPolygon );
		aPolyPoly.GetIntersection( aPolyPolyRect, aIntersection );
		aPolyPoly = aIntersection;
		nDepth++;
	}
	ImpUpdateType();
}

void WinMtfClipPath::ExcludeClipRect( const Rectangle& rRect )
{
	if ( aPolyPoly.Count() && ( nDepth < WIN_MTF_MAX_CLIP_DEPTH ) )
	{
		Polygon aPolygon( rRect );
		PolyPolygon aPolyPolyRect( aPolygon );
		PolyPolygon aDifference;
		aPolyPoly.GetDifference( aPolyPolyRect, aDifference );
		aPolyPoly = aDifference;
		nDepth++;
	}
	ImpUpdateType();
}

void WinMtfClipPath::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
{
	PolyPolygon aSimplePoly;
	if ( rPolyPolygon.Count() && rPolyPolygon[ 0 ].HasFlags() )
		rPolyPolygon.AdaptiveSubdivide( aSimplePoly, 100 );
	if ( !aSimplePoly.Count() )
        aPolyPoly = aSimplePoly;
	else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH )
	{
		nDepth++;

		PolyPolygon aNewClipPath;

        // #115345# Watch out for empty aPolyPoly here - conceptually,
        // an empty clip path is a rectangle of infinite size, but it
        // is represented by an empty aPolyPoly. When intersecting
        // rPolyPolygon with this _empty_ aPolyPoly, set algebra
        // guarantees wrong results.
		switch ( nClippingMode )
		{
			case RGN_OR :
                // #115345# clip stays empty, when ORing an arbitrary
                // rPolyPolygon. Thus, we can save us the unnecessary
                // clipper call.
                if( aPolyPoly.Count() )
                    aPolyPoly.GetUnion( aSimplePoly, aNewClipPath );
			break;
			case RGN_XOR :
                // TODO:
                // #115345# Cannot handle this case, for the time being
				aPolyPoly.GetXOR( aSimplePoly, aNewClipPath );
			break;
			case RGN_DIFF :
                // TODO:
                // #115345# Cannot handle this case, for the time being
				aPolyPoly.GetDifference( aSimplePoly, aNewClipPath );
			break;
			case RGN_AND :
                // #115345# Clip becomes rPolyPolygon, when ANDing
                // with an arbitrary rPolyPolygon
                if( aPolyPoly.Count() )
                    aPolyPoly.GetIntersection( aSimplePoly, aNewClipPath );
                else
                    aNewClipPath = aSimplePoly;
			break;
			case RGN_COPY :
				aNewClipPath = aSimplePoly;
			break;
		}
		aPolyPoly = aNewClipPath;
	}
	ImpUpdateType();
}

void WinMtfClipPath::MoveClipRegion( const Size& rSize )
{
	aPolyPoly.Move( rSize.Width(), rSize.Height() );
	bNeedsUpdate = sal_True;
}

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

void WinMtfPathObj::AddPoint( const Point& rPoint )
{
	if ( bClosed )
		Insert( Polygon(), POLYPOLY_APPEND );
	Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
	rPoly.Insert( rPoly.GetSize(), rPoint, POLY_NORMAL );
	bClosed = sal_False;
}

void WinMtfPathObj::AddPolyLine( const Polygon& rPolyLine )
{
	if ( bClosed )
		Insert( Polygon(), POLYPOLY_APPEND );
	Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
	rPoly.Insert( rPoly.GetSize(), rPolyLine );
	bClosed = sal_False;
}

void WinMtfPathObj::AddPolygon( const Polygon& rPoly )
{
	Insert( rPoly, POLYPOLY_APPEND );
	bClosed = sal_True;
}

void WinMtfPathObj::AddPolyPolygon( const PolyPolygon& rPolyPoly )
{
	sal_uInt16 i, nCount = rPolyPoly.Count();
	for ( i = 0; i < nCount; i++ )
		Insert( rPolyPoly[ i ], POLYPOLY_APPEND );
	bClosed = sal_True;
}

void WinMtfPathObj::ClosePath()
{
	if ( Count() )
	{
		Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
		if ( rPoly.GetSize() > 2 )
		{
			Point aFirst( rPoly[ 0 ] );
			if ( aFirst != rPoly[ rPoly.GetSize() - 1 ] )
				rPoly.Insert( rPoly.GetSize(), aFirst, POLY_NORMAL );
		}
	}
	bClosed = sal_True;
}

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

WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont )
{
	CharSet eCharSet;
	if ( ( rFont.lfCharSet == OEM_CHARSET ) || ( rFont.lfCharSet == DEFAULT_CHARSET ) )
		eCharSet = gsl_getSystemTextEncoding();
	else
		eCharSet = rtl_getTextEncodingFromWindowsCharset( rFont.lfCharSet );
	if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
		eCharSet = gsl_getSystemTextEncoding();
	aFont.SetCharSet( eCharSet );
	aFont.SetName( rFont.alfFaceName );
	FontFamily eFamily;
	switch ( rFont.lfPitchAndFamily & 0xf0 )
	{
		case FF_ROMAN:
			eFamily = FAMILY_ROMAN;
		break;

		case FF_SWISS:
			eFamily = FAMILY_SWISS;
		break;

		case FF_MODERN:
			eFamily = FAMILY_MODERN;
		break;

		case FF_SCRIPT:
			eFamily = FAMILY_SCRIPT;
		break;

		case FF_DECORATIVE:
			 eFamily = FAMILY_DECORATIVE;
		break;

		default:
			eFamily = FAMILY_DONTKNOW;
		break;
	}
	aFont.SetFamily( eFamily );

	FontPitch ePitch;
	switch ( rFont.lfPitchAndFamily & 0x0f )
	{
		case FIXED_PITCH:
			ePitch = PITCH_FIXED;
		break;

		case DEFAULT_PITCH:
		case VARIABLE_PITCH:
		default:
			ePitch = PITCH_VARIABLE;
		break;
	}
	aFont.SetPitch( ePitch );

	FontWeight eWeight;
	if( rFont.lfWeight <= FW_THIN )
		eWeight = WEIGHT_THIN;
	else if( rFont.lfWeight <= FW_ULTRALIGHT )
		eWeight = WEIGHT_ULTRALIGHT;
	else if( rFont.lfWeight <= FW_LIGHT )
		eWeight = WEIGHT_LIGHT;
	else if( rFont.lfWeight <  FW_MEDIUM )
		eWeight = WEIGHT_NORMAL;
	else if( rFont.lfWeight == FW_MEDIUM )
		eWeight = WEIGHT_MEDIUM;
	else if( rFont.lfWeight <= FW_SEMIBOLD )
		eWeight = WEIGHT_SEMIBOLD;
	else if( rFont.lfWeight <= FW_BOLD )
		eWeight = WEIGHT_BOLD;
	else if( rFont.lfWeight <= FW_ULTRABOLD )
		eWeight = WEIGHT_ULTRABOLD;
	else
		eWeight = WEIGHT_BLACK;
	aFont.SetWeight( eWeight );

	if( rFont.lfItalic )
		aFont.SetItalic( ITALIC_NORMAL );

	if( rFont.lfUnderline )
		aFont.SetUnderline( UNDERLINE_SINGLE );

	if( rFont.lfStrikeOut )
		aFont.SetStrikeout( STRIKEOUT_SINGLE );

	if ( rFont.lfOrientation )
		aFont.SetOrientation( (short)rFont.lfOrientation );
	else
		aFont.SetOrientation( (short)rFont.lfEscapement );

	Size  aFontSize( Size( rFont.lfWidth, rFont.lfHeight ) );
	if ( rFont.lfHeight > 0 )
	{
        // #117968# VirtualDevice is not thread safe, but filter is used in multithreading
        vos::OGuard aGuard( Application::GetSolarMutex() );
		VirtualDevice aVDev;

        // converting the cell height into a font height
		aFont.SetSize( aFontSize );
		aVDev.SetFont( aFont );
		FontMetric aMetric( aVDev.GetFontMetric() );
		long nHeight = aMetric.GetAscent() + aMetric.GetDescent();
		if ( nHeight )
		{
			double fHeight = ((double)aFontSize.Height() * rFont.lfHeight ) / nHeight;
			aFontSize.Height() = (sal_Int32)( fHeight + 0.5 );
		}
	}
	else if ( aFontSize.Height() < 0 )
		aFontSize.Height() *= -1;
	
	if ( !rFont.lfWidth )
	{
        // #117968# VirtualDevice is not thread safe, but filter is used in multithreading
        vos::OGuard aGuard( Application::GetSolarMutex() );
		VirtualDevice aVDev;
	
        aFont.SetSize( aFontSize );
		aVDev.SetFont( aFont );
		FontMetric aMetric( aVDev.GetFontMetric() );
		aFontSize.Width() = aMetric.GetWidth();
	}

	aFont.SetSize( aFontSize );
};

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

#ifdef WIN_MTF_ASSERT
void WinMtfAssertHandler( const sal_Char* pAction, sal_uInt32 nFlags )
{
    static sal_Bool     bOnlyOnce;
    static sal_Int32    nAssertCount;

    if ( nFlags & WIN_MTF_ASSERT_INIT )
        nAssertCount = 0;
    if ( nFlags & WIN_MTF_ASSERT_ONCE )
       bOnlyOnce = sal_True;
    if ( nFlags & WIN_MTF_ASSERT_MIFE )
    {
        if ( ( nAssertCount == 0 ) || ( bOnlyOnce == sal_False ) )
        {   
            ByteString aText( "WMF/EMF Import: " );
            if ( pAction )
            {
                ByteString aAction( pAction );
                aText.Append( aAction );
            }
            aText.Append( " needs to be implemented (SJ)" );
	        DBG_ASSERT( 0, aText.GetBuffer() );
        }
        nAssertCount++;
    }
}
#endif

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

WinMtf::WinMtf( WinMtfOutput* pWinMtfOutput, SvStream& rStreamWMF, FilterConfigItem* pConfigItem ) :
	pOut				( pWinMtfOutput ),
	pWMF				( &rStreamWMF ),
	pFilterConfigItem	( pConfigItem )
{
#ifdef WIN_MTF_ASSERT
    // we want to assert not implemented features, but we do this 
    // only once, so that nobody is handicaped by getting too much assertions
    // I hope this will bring more testdocuments, without support of these
    // testdocuments the implementation of missing features won't be possible. (SJ)
    WinMtfAssertHandler( NULL, WIN_MTF_ASSERT_INIT | WIN_MTF_ASSERT_ONCE );
#endif 

	SvLockBytes *pLB = pWMF->GetLockBytes();
	if ( pLB )
		pLB->SetSynchronMode( sal_True );

	nStartPos = pWMF->Tell();

	pOut->SetDevOrg( Point() );
	if ( pFilterConfigItem )
	{
		xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
		if ( xStatusIndicator.is() )
		{
			rtl::OUString aMsg;
			xStatusIndicator->start( aMsg, 100 );
		}
	}
}

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

WinMtf::~WinMtf()
{
	delete pOut;

	if ( xStatusIndicator.is() )
		xStatusIndicator->end();
}

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

void WinMtf::Callback( sal_uInt16 nPercent )
{
	if ( xStatusIndicator.is() )
		xStatusIndicator->setValue( nPercent );
}

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

Color WinMtf::ReadColor()
{
	sal_uInt32 nColor;
	*pWMF >> nColor;
	return Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
};

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

Point WinMtfOutput::ImplMap( const Point& rPt )
{
	if ( mnWinExtX && mnWinExtY )
	{
		double fX2, fX = rPt.X();
		double fY2, fY = rPt.Y();

		fX2 = fX * maXForm.eM11 + fY * maXForm.eM21 + maXForm.eDx;
		fY2 = fX * maXForm.eM12 + fY * maXForm.eM22 + maXForm.eDy;

		if ( mnGfxMode == GM_COMPATIBLE )
		{
			switch( mnMapMode )
			{
				case MM_LOENGLISH :
				{
					fX2 -= mnWinOrgX;
					fY2  = mnWinOrgY-fY2;
					fX2 *= 25.40;
					fY2 *= 25.40;
					fX2 += mnDevOrgX;
					fY2 += mnDevOrgY;
				}
				break;
				case MM_HIENGLISH :
				{
					fX2 -= mnWinOrgX;
					fY2  = mnWinOrgY-fY2;
					fX2 *= 2.540;
					fY2 *= 2.540;
					fX2 += mnDevOrgX;
					fY2 += mnDevOrgY;
				}
				break;
				case MM_LOMETRIC :
				{
					fX2 -= mnWinOrgX;
					fY2  = mnWinOrgY-fY2;
					fX2 *= 10;
					fY2 *= 10;
					fX2 += mnDevOrgX;
					fY2 += mnDevOrgY;
				}
				break;
				case MM_HIMETRIC :
				{
					fX2 -= mnWinOrgX;
					fY2  = mnWinOrgY-fY2;
					fX2 += mnDevOrgX;
					fY2 += mnDevOrgY;
				}
				break;
				default :
				{
					fX2 -= mnWinOrgX;
					fY2 -= mnWinOrgY;
					fX2 /= mnWinExtX;
					fY2 /= mnWinExtY;
					fX2 *= mnDevWidth;
					fY2 *= mnDevHeight;
					fX2 += mnDevOrgX;
					fY2 += mnDevOrgY;	// fX2, fY2 now in device units
					fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
					fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
				}
				break;
			}
			fX2 -= mrclFrame.Left();
			fY2 -= mrclFrame.Top();
		}
		return Point( FRound( fX2 ), FRound( fY2 ) );
	}
	else
		return Point();
};

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

Size WinMtfOutput::ImplMap( const Size& rSz )
{
	if ( mnWinExtX && mnWinExtY )
	{
        // #121382# apply the whole WorldTransform, else a rotation will be misinterpreted
		double fWidth = rSz.Width() * maXForm.eM11 + rSz.Height() * maXForm.eM21;
		double fHeight = rSz.Width() * maXForm.eM12 + rSz.Height() * maXForm.eM22;

		if ( mnGfxMode == GM_COMPATIBLE )
		{
			switch( mnMapMode )
			{
				case MM_LOENGLISH :
				{
					fWidth *= 25.40;
					fHeight*=-25.40;
				}
				break;
				case MM_HIENGLISH :
				{
					fWidth *= 2.540;
					fHeight*=-2.540;
				}
				break;
				case MM_LOMETRIC :
				{
					fWidth *= 10;
					fHeight*=-10;
				}
				break;
				case MM_HIMETRIC :
				{
					fHeight *= -1;
				}
				break;
				default :
				{
					fWidth /= mnWinExtX;
					fHeight /= mnWinExtY;
					fWidth *= mnDevWidth;
					fHeight *= mnDevHeight;
					fWidth *= (double)mnMillX * 100 / (double)mnPixX;
					fHeight *= (double)mnMillY * 100 / (double)mnPixY;
				}
				break;
			}
		}
		return Size( FRound( fWidth ), FRound( fHeight ) );
	}
	else
		return Size();
}

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

Rectangle WinMtfOutput::ImplMap( const Rectangle& rRect )
{
	return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) );
}

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

void WinMtfOutput::ImplMap( Font& rFont )
{
	// !!! HACK: Wir setzen die Breite jetzt immer auf Null,
	// da OS die Breite unterschiedlich interpretieren;
	// muss spaeter in SV portabel gemacht werden ( KA 08.02.96 )
	Size  aFontSize = ImplMap ( rFont.GetSize() );

	if( aFontSize.Height() < 0 )
		aFontSize.Height() *= -1;

	rFont.SetSize( aFontSize );

	if( ( mnWinExtX * mnWinExtY ) < 0 )
		rFont.SetOrientation( 3600 - rFont.GetOrientation() );
}

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

Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
{
	sal_uInt16 nPoints = rPolygon.GetSize();
	for ( sal_uInt16 i = 0; i < nPoints; i++ )
	{
		rPolygon[ i ] = ImplMap( rPolygon[ i ] );
	}
	return rPolygon;
}

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

PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
{
	sal_uInt16 nPolys = rPolyPolygon.Count();
	for ( sal_uInt16 i = 0; i < nPolys; ImplMap( rPolyPolygon[ i++ ] ) ) ;
	return rPolyPolygon;
}

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

void WinMtfOutput::SelectObject( sal_Int32 nIndex )
{
	GDIObj* pGDIObj = NULL;

	if ( nIndex & ENHMETA_STOCK_OBJECT )
		pGDIObj = new GDIObj();
	else
	{
		nIndex &= 0xffff;		// zur Sicherheit: mehr als 65535 nicht zulassen

		if ( (sal_uInt32)nIndex < vGDIObj.size() )
			pGDIObj = vGDIObj[ nIndex ];
	}

	if( pGDIObj == NULL )
		return;

	if ( nIndex & ENHMETA_STOCK_OBJECT )
	{
		sal_uInt16 nStockId = (sal_uInt8)nIndex;
		switch( nStockId )
		{
			case WHITE_BRUSH :
			{
				pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ) ) );
			}
			break;
			case LTGRAY_BRUSH :
			{
				pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_LIGHTGRAY ) ) );
			}
			break;
			case GRAY_BRUSH :
			case DKGRAY_BRUSH :
			{
				pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_GRAY ) ) );
			}
			break;
			case BLACK_BRUSH :
			{
				pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_BLACK ) ) );
			}
			break;
			case NULL_BRUSH :
			{
				pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True ) );
			}
			break;
			case WHITE_PEN :
			{
				pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_WHITE ) ) );
			}
			break;
			case BLACK_PEN :
			{
				pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_BLACK ) ) );
			}
			break;
			case NULL_PEN :
			{
				pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True ) );
			}
			break;
			default:
			break;
		}
	}
	if ( pGDIObj->pStyle )
	{
		switch( pGDIObj->eType )
		{
			case GDI_PEN :
				maLineStyle = (WinMtfLineStyle*)pGDIObj->pStyle;
			break;
			case GDI_BRUSH :
			{
				maFillStyle = (WinMtfFillStyle*)pGDIObj->pStyle;
				mbFillStyleSelected = sal_True;
			}
			break;
			case GDI_FONT :
				maFont = ((WinMtfFontStyle*)pGDIObj->pStyle)->aFont;
			break;
			default:
			break;  //  -Wall many options not handled.
		}
	}
	if ( nIndex & ENHMETA_STOCK_OBJECT )
		delete pGDIObj;
}

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

void WinMtfOutput::SetFont( const Font& rFont )
{
	maFont = rFont;
}

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

const Font& WinMtfOutput::GetFont() const
{
	return maFont;
}

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

void WinMtfOutput::SetTextLayoutMode( const sal_uInt32 nTextLayoutMode )
{
	mnTextLayoutMode = nTextLayoutMode;
}

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

sal_uInt32 WinMtfOutput::GetTextLayoutMode() const
{
	return mnTextLayoutMode;
}

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

void WinMtfOutput::SetBkMode( sal_uInt32 nMode )
{
	mnBkMode = nMode;
}

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

void WinMtfOutput::SetBkColor( const Color& rColor )
{
	maBkColor = rColor;
}

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

void WinMtfOutput::SetTextColor( const Color& rColor )
{
	maTextColor = rColor;
}

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

void WinMtfOutput::SetTextAlign( sal_uInt32 nAlign )
{
	mnTextAlign = nAlign;
}

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

void WinMtfOutput::ImplResizeObjectArry( sal_uInt32 nNewEntrys )
{
	sal_uInt32 i = vGDIObj.size();
	vGDIObj.resize( nNewEntrys );
	for ( ; i < nNewEntrys ; i++ )
		vGDIObj[ i ] = NULL;
}

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

void WinMtfOutput::ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly )
{
	if ( rPolyPoly.Count() )
	{
		ImplSetNonPersistentLineColorTransparenz();
		if ( rPolyPoly.Count() == 1 )
		{
			if ( rPolyPoly.IsRect() )
				mpGDIMetaFile->AddAction( new MetaRectAction( rPolyPoly.GetBoundRect() ) );
			else
			{
				Polygon	aPoly( rPolyPoly[ 0 ] );
				sal_uInt16 nCount = aPoly.GetSize();
				if ( nCount )
				{
					if ( aPoly[ nCount - 1 ] != aPoly[ 0 ] )
					{
						Point aPoint( aPoly[ 0 ] );
						aPoly.Insert( nCount, aPoint );
					}
					mpGDIMetaFile->AddAction( new MetaPolygonAction( aPoly ) );
				}
			}
		}
		else
			mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
	}
}


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

void WinMtfOutput::CreateObject( GDIObjectType eType, void* pStyle )
{
	if ( pStyle )
	{
		if ( eType == GDI_FONT )
		{
			ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
			if (!((WinMtfFontStyle*)pStyle)->aFont.GetHeight() )
				((WinMtfFontStyle*)pStyle)->aFont.SetHeight( 423 );		// defaulting to 12pt
		}
		else if ( eType == GDI_PEN )
		{
			Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
			((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
			if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
			{
				aSize.Width() += 1;
				long nDotLen = ImplMap( aSize ).Width();
				((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
				((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
				((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
			}
		}
	}
	sal_uInt32 nIndex;
	for ( nIndex = 0; nIndex < vGDIObj.size(); nIndex++ )
	{
		if ( vGDIObj[ nIndex ] == NULL )
			break;
	}
	if ( nIndex == vGDIObj.size() )
		ImplResizeObjectArry( vGDIObj.size() + 16 );

	vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
}

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

void WinMtfOutput::CreateObject( sal_Int32 nIndex, GDIObjectType eType, void* pStyle )
{
	if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
	{
		nIndex &= 0xffff;		// zur Sicherheit: mehr als 65535 nicht zulassen
		if ( pStyle )
		{
			if ( eType == GDI_FONT )
				ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
			else if ( eType == GDI_PEN )
			{
				Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
				((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
				if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
				{
					aSize.Width() += 1;
					long nDotLen = ImplMap( aSize ).Width();
					((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
					((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
					((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
				}
			}
		}
		if ( (sal_uInt32)nIndex >= vGDIObj.size() )
			ImplResizeObjectArry( nIndex + 16 );

		if ( vGDIObj[ nIndex ] != NULL )
			delete vGDIObj[ nIndex ];

		vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
	}
	else
    {
        switch ( eType )
        {
            case GDI_PEN :
                delete (WinMtfLineStyle*)pStyle;
            break;
            case GDI_BRUSH :
                delete (WinMtfFillStyle*)pStyle;
            break;
            case GDI_FONT :
                delete (WinMtfFontStyle*)pStyle;
            break;

            default:
                DBG_ERROR( "unsupported style not deleted" );
                break;
        }
    }
}

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

void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
{
	if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
	{
        if ( (sal_uInt32)nIndex < vGDIObj.size() )
        {
		    delete vGDIObj[ nIndex ];
            vGDIObj[ nIndex ] = NULL;
        }
	}
}

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

void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
{
	aClipPath.IntersectClipRect( ImplMap( rRect ) );
}

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

void WinMtfOutput::ExcludeClipRect( const Rectangle& rRect )
{
	aClipPath.ExcludeClipRect( ImplMap( rRect ) );
}

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

void WinMtfOutput::MoveClipRegion( const Size& rSize )
{
	aClipPath.MoveClipRegion( ImplMap( rSize ) );
}

void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, sal_Bool bIsMapped )
{
	if ( bIsMapped )
		aClipPath.SetClipPath( rPolyPolygon, nClippingMode );
	else
	{
		PolyPolygon aPP( rPolyPolygon );
		aClipPath.SetClipPath( ImplMap( aPP ), nClippingMode );
	}
}

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

WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
    mnLatestTextAlign   ( 0 ),
	mnTextAlign		    ( TA_LEFT | TA_TOP | TA_NOUPDATECP ),
	maLatestBkColor     ( 0x12345678 ),
	maBkColor			( COL_WHITE ),
	mnLatestTextLayoutMode( TEXT_LAYOUT_DEFAULT ),
	mnTextLayoutMode	( TEXT_LAYOUT_DEFAULT ),
    mnLatestBkMode      ( 0 ),
	mnBkMode			( OPAQUE ),
    meLatestRasterOp    ( ROP_INVERT ),
	meRasterOp			( ROP_OVERPAINT ),
	maActPos			( Point() ),
	mbNopMode			( sal_False ),
	mbFillStyleSelected	( sal_False ),
	mnGfxMode			( GM_COMPATIBLE ),
    mnMapMode           ( MM_TEXT ),
	mnDevOrgX			( 0 ),
	mnDevOrgY			( 0 ),
	mnDevWidth			( 1 ),
	mnDevHeight			( 1 ),
	mnWinOrgX			( 0 ),
	mnWinOrgY			( 0 ),
	mnWinExtX			( 1 ),
	mnWinExtY			( 1 ),
	mnPixX				( 100 ),
	mnPixY				( 100 ),
	mnMillX				( 1 ),
	mnMillY				( 1 ),
	mpGDIMetaFile       ( &rGDIMetaFile )
{
	mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) );		// The original clipregion has to be on top
																			// of the stack so it can always be restored
																			// this is necessary to be able to support
																			// SetClipRgn( NULL ) and similar ClipRgn actions (SJ)

	maFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Arial" )) );	// sj: #i57205#, we do have some scaling problems if using
	maFont.SetCharSet( gsl_getSystemTextEncoding() );						// the default font then most times a x11 font is used, we
	maFont.SetHeight( 423 );												// will prevent this defining a font

	maLatestLineStyle.aLineColor = Color( 0x12, 0x34, 0x56 );
	maLatestFillStyle.aFillColor = Color( 0x12, 0x34, 0x56 );

	mnRop = R2_BLACK + 1;
	SetRasterOp( R2_BLACK );
};

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

WinMtfOutput::~WinMtfOutput()
{
	mpGDIMetaFile->AddAction( new MetaPopAction() );
	mpGDIMetaFile->SetPrefMapMode( MAP_100TH_MM );
	if ( mrclFrame.IsEmpty() )
		mpGDIMetaFile->SetPrefSize( Size( mnDevWidth, mnDevHeight ) );
	else
		mpGDIMetaFile->SetPrefSize( mrclFrame.GetSize() );

	for ( sal_uInt32 i = 0; i < vGDIObj.size(); i++ )
		delete vGDIObj[ i ];
};

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

void WinMtfOutput::UpdateClipRegion()
{
	if ( aClipPath.bNeedsUpdate )
	{
		aClipPath.bNeedsUpdate = sal_False;

		mpGDIMetaFile->AddAction( new MetaPopAction() );                    // taking the orignal clipregion
		mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) );  // 

		switch ( aClipPath.GetType() )
		{
			case RECTANGLE :
			case COMPLEX :
			{
//				we will not generate a RegionClipRegion Action, because this action
//				cannot be saved to the wmf format - saving to wmf always happens
//				if the placeholder graphic for ole objects is generated. (SJ)

//				Region aClipRegion( aClipPath.GetClipPath() );
//				mpGDIMetaFile->AddAction( new MetaISectRegionClipRegionAction( aClipRegion ) );

				Rectangle aClipRect( aClipPath.GetClipPath().GetBoundRect() );
				mpGDIMetaFile->AddAction( new MetaISectRectClipRegionAction( aClipRect ) );
			}
			break;
			case EMPTY:
			break;  // -Wall not handled.
		}
	}
}

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

void WinMtfOutput::ImplSetNonPersistentLineColorTransparenz()
{
	Color aColor(  COL_TRANSPARENT);
	WinMtfLineStyle aTransparentLine( aColor, sal_True );
	if ( ! ( maLatestLineStyle == aTransparentLine ) )
	{
		maLatestLineStyle = aTransparentLine;
		mpGDIMetaFile->AddAction( new MetaLineColorAction( aTransparentLine.aLineColor, !aTransparentLine.bTransparent ) );
	}
}

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

void WinMtfOutput::UpdateLineStyle()
{
	if (!( maLatestLineStyle == maLineStyle ) )
	{
		maLatestLineStyle = maLineStyle;
		mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
	}
}

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

void WinMtfOutput::UpdateFillStyle()
{
	if ( !mbFillStyleSelected )		// SJ: #i57205# taking care of bkcolor if no brush is selected
		maFillStyle = WinMtfFillStyle( maBkColor, mnBkMode == TRANSPARENT );
	if (!( maLatestFillStyle == maFillStyle ) )
	{
		maLatestFillStyle = maFillStyle;
		mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
	}
}

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

sal_uInt32 WinMtfOutput::SetRasterOp( sal_uInt32 nRasterOp )
{
	sal_uInt32 nRetROP = mnRop;
	if ( nRasterOp != mnRop )
	{
		mnRop = nRasterOp;
		static WinMtfFillStyle aNopFillStyle;
		static WinMtfLineStyle aNopLineStyle;

		if ( mbNopMode && ( nRasterOp != R2_NOP ) )
		{	// beim uebergang von R2_NOP auf anderen Modus
			// gesetzten Pen und Brush aktivieren
			maFillStyle = aNopFillStyle;
			maLineStyle = aNopLineStyle;
			mbNopMode = sal_False;
		}
		switch( nRasterOp )
		{
			case R2_NOT:
				meRasterOp = ROP_INVERT;
			break;

			case R2_XORPEN:
				meRasterOp = ROP_XOR;
			break;

			case R2_NOP:
			{
				meRasterOp = ROP_OVERPAINT;
				if( mbNopMode == sal_False )
				{
					aNopFillStyle = maFillStyle;
					aNopLineStyle = maLineStyle;
					maFillStyle = WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True );
					maLineStyle = WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True );
					mbNopMode = sal_True;
				}
			}
			break;

			default:
				meRasterOp = ROP_OVERPAINT;
			break;
		}
	}
	if ( nRetROP != nRasterOp )
		mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
	return nRetROP;
};

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

void WinMtfOutput::StrokeAndFillPath( sal_Bool bStroke, sal_Bool bFill )
{
	if ( aPathObj.Count() )
	{
		UpdateClipRegion();
		UpdateLineStyle();
		UpdateFillStyle();
		if ( bFill )
		{
			if ( !bStroke )
			{
				mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
				mpGDIMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
			}
			if ( aPathObj.Count() == 1 )
				mpGDIMetaFile->AddAction( new MetaPolygonAction( aPathObj.GetObject( 0 ) ) );
			else
				mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( aPathObj ) );

			if ( !bStroke )
				mpGDIMetaFile->AddAction( new MetaPopAction() );
		}
		else
		{
			sal_uInt16 i, nCount = aPathObj.Count();
			for ( i = 0; i < nCount; i++ )
				mpGDIMetaFile->AddAction( new MetaPolyLineAction( aPathObj[ i ], maLineStyle.aLineInfo ) );
		}
		ClearPath();
	}
}

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

void WinMtfOutput::DrawPixel( const Point& rSource, const Color& rColor )
{
	mpGDIMetaFile->AddAction( new MetaPixelAction( ImplMap( rSource), rColor ) );
}

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

void WinMtfOutput::MoveTo( const Point& rPoint, sal_Bool bRecordPath )
{
    Point aDest( ImplMap( rPoint ) );
    if ( bRecordPath )
        aPathObj.AddPoint( aDest );
    maActPos = aDest;
}

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

void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
{
	UpdateClipRegion();

	Point aDest( ImplMap( rPoint ) );
	if ( bRecordPath )
		aPathObj.AddPoint( aDest );
	else
	{
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaLineAction( maActPos, aDest, maLineStyle.aLineInfo ) );
	}
	maActPos = aDest;
}

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

void WinMtfOutput::DrawLine( const Point& rSource, const Point& rDest )
{
	UpdateClipRegion();
	UpdateLineStyle();
	mpGDIMetaFile->AddAction( new MetaLineAction( ImplMap( rSource), ImplMap( rDest ), maLineStyle.aLineInfo ) );
}

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

void WinMtfOutput::DrawRect( const Rectangle& rRect, sal_Bool bEdge )
{
	UpdateClipRegion();
	UpdateFillStyle();

	if ( aClipPath.GetType() == COMPLEX )
	{
		Polygon aPoly( ImplMap( rRect ) );
		PolyPolygon aPolyPolyRect( aPoly );
		PolyPolygon aDest;
		aClipPath.GetClipPath().GetIntersection( aPolyPolyRect, aDest );
		ImplDrawClippedPolyPolygon( aDest );
	}
	else
	{
		if ( bEdge )
		{
			if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
			{
				ImplSetNonPersistentLineColorTransparenz();
				mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
				UpdateLineStyle();
				mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect ) ),maLineStyle.aLineInfo ) );
			}
			else
			{
				UpdateLineStyle();
				mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
			}
		}
		else
		{
			ImplSetNonPersistentLineColorTransparenz();
			mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
		}
	}
}

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

void WinMtfOutput::DrawRoundRect( const Rectangle& rRect, const Size& rSize )
{
	UpdateClipRegion();
	UpdateLineStyle();
	UpdateFillStyle();
	mpGDIMetaFile->AddAction( new MetaRoundRectAction( ImplMap( rRect ), labs( ImplMap( rSize ).Width() ), labs( ImplMap( rSize ).Height() ) ) );
}

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

void WinMtfOutput::DrawEllipse( const Rectangle& rRect )
{
	UpdateClipRegion();
	UpdateFillStyle();

	if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
	{
		Point aCenter( ImplMap( rRect.Center() ) );
		Size  aRad( ImplMap( Size( rRect.GetWidth() / 2, rRect.GetHeight() / 2 ) ) );

		ImplSetNonPersistentLineColorTransparenz();
		mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
	}
	else
	{
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
	}
}

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

void WinMtfOutput::DrawArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, sal_Bool bTo )
{
	UpdateClipRegion();
	UpdateLineStyle();
	UpdateFillStyle();

	Rectangle	aRect( ImplMap( rRect ) );
	Point		aStart( ImplMap( rStart ) );
	Point		aEnd( ImplMap( rEnd ) );

	if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
	{
		if ( aStart == aEnd )
		{	// SJ: #i53768# if start & end is identical, then we have to draw a full ellipse
			Point aCenter( aRect.Center() );
			Size  aRad( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );

			mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
		}
		else
			mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_ARC ), maLineStyle.aLineInfo ) );
	}
	else
		mpGDIMetaFile->AddAction( new MetaArcAction( aRect, aStart, aEnd ) );

	if ( bTo )
		maActPos = aEnd;
}

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

void WinMtfOutput::DrawPie( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
{
	UpdateClipRegion();
	UpdateFillStyle();

	Rectangle	aRect( ImplMap( rRect ) );
	Point		aStart( ImplMap( rStart ) );
	Point		aEnd( ImplMap( rEnd ) );

	if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
	{
		ImplSetNonPersistentLineColorTransparenz();
		mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_PIE ), maLineStyle.aLineInfo ) );
	}
	else
	{
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
	}
}

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

void WinMtfOutput::DrawChord( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
{
	UpdateClipRegion();
	UpdateFillStyle();

	Rectangle	aRect( ImplMap( rRect ) );
	Point		aStart( ImplMap( rStart ) );
	Point		aEnd( ImplMap( rEnd ) );

	if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
	{
		ImplSetNonPersistentLineColorTransparenz();
		mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_CHORD ), maLineStyle.aLineInfo ) );
	}
	else
	{
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
	}
}

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

void WinMtfOutput::DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath )
{
	UpdateClipRegion();
	ImplMap( rPolygon );
	if ( bRecordPath )
		aPathObj.AddPolygon( rPolygon );
	else
	{
		UpdateFillStyle();

		if ( aClipPath.GetType() == COMPLEX )
		{
			PolyPolygon aPolyPoly( rPolygon );
			PolyPolygon aDest;
			aClipPath.GetClipPath().GetIntersection( aPolyPoly, aDest );
			ImplDrawClippedPolyPolygon( aDest );
		}
		else
		{
			if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
			{
				sal_uInt16 nCount = rPolygon.GetSize();
				if ( nCount )
				{
					if ( rPolygon[ nCount - 1 ] != rPolygon[ 0 ] )
					{
						Point aPoint( rPolygon[ 0 ] );
						rPolygon.Insert( nCount, aPoint );
					}
				}
				ImplSetNonPersistentLineColorTransparenz();
				mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
				UpdateLineStyle();
				mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
			}
			else
			{
				UpdateLineStyle();
				mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
			}
		}
	}
}

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

void WinMtfOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool bRecordPath )
{
	UpdateClipRegion();

	ImplMap( rPolyPolygon );

	if ( bRecordPath )
		aPathObj.AddPolyPolygon( rPolyPolygon );
	else
	{
		UpdateFillStyle();

		if ( aClipPath.GetType() == COMPLEX )
		{
			PolyPolygon aDest;
			aClipPath.GetClipPath().GetIntersection( rPolyPolygon, aDest );	
			ImplDrawClippedPolyPolygon( aDest );
		}
		else
		{
			UpdateLineStyle();
			mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPolygon ) );
		}
	}
}

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

void WinMtfOutput::DrawPolyLine( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
{
	UpdateClipRegion();

	ImplMap( rPolygon );
	if ( bTo )
	{
		rPolygon[ 0 ] = maActPos;
		maActPos = rPolygon[ rPolygon.GetSize() - 1 ];
	}
	if ( bRecordPath )
		aPathObj.AddPolyLine( rPolygon );
	else
	{
		UpdateLineStyle();
		mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
	}
}

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

void WinMtfOutput::DrawPolyBezier( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
{
	UpdateClipRegion();

	sal_uInt16 nPoints = rPolygon.GetSize();
	if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) )
	{
		ImplMap( rPolygon );
		if ( bTo )
		{
			rPolygon[ 0 ] = maActPos;
			maActPos = rPolygon[ nPoints - 1 ];
		}
		sal_uInt16 i;
		for ( i = 0; ( i + 2 ) < nPoints; )
		{
			rPolygon.SetFlags( i++, POLY_NORMAL );
			rPolygon.SetFlags( i++, POLY_CONTROL );
			rPolygon.SetFlags( i++, POLY_CONTROL );
		}
		if ( bRecordPath )
			aPathObj.AddPolyLine( rPolygon );
		else
		{
			UpdateLineStyle();
			mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
		}
	}
}

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

void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry, sal_Bool bRecordPath, sal_Int32 nGfxMode )
{
    UpdateClipRegion();
	rPosition = ImplMap( rPosition );
	sal_Int32 nOldGfxMode = GetGfxMode();
	SetGfxMode( GM_COMPATIBLE );

    if ( pDXArry )
	{
		sal_Int32 i, nSum, nLen = rText.Len();

		for( i = 0, nSum = 0; i < nLen; i++ )
		{
            // #121382# Map DXArray using WorldTransform
            const Size aSize(ImplMap(Size( pDXArry[i], 0)));
            const basegfx::B2DVector aVector(aSize.Width(), aSize.Height());
            const sal_Int32 nTemp(basegfx::fround(aVector.getLength()));
			nSum += nTemp;
			pDXArry[ i ] = nSum;
		}
	}
	if ( mnLatestTextLayoutMode != mnTextLayoutMode )
	{
		mnLatestTextLayoutMode = mnTextLayoutMode;
		mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
	}
	SetGfxMode( nGfxMode );
    sal_Bool bChangeFont = sal_False;
    if ( mnLatestTextAlign != mnTextAlign )
    {
        bChangeFont = sal_True;
        mnLatestTextAlign = mnTextAlign;
        TextAlign eTextAlign;
		if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
			eTextAlign = ALIGN_BASELINE;
		else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
			eTextAlign = ALIGN_BOTTOM;
		else
			eTextAlign = ALIGN_TOP;
		mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
    }
    if ( maLatestTextColor != maTextColor )
    {
        bChangeFont = sal_True;
        maLatestTextColor = maTextColor;
		mpGDIMetaFile->AddAction( new MetaTextColorAction( maTextColor ) );
    }
    sal_Bool bChangeFillColor = sal_False;
    if ( maLatestBkColor != maBkColor )
    {
        bChangeFillColor = sal_True;
        maLatestBkColor = maBkColor;
    }
    if ( mnLatestBkMode != mnBkMode )
    {
        bChangeFillColor = sal_True;
        mnLatestBkMode = mnBkMode;
    }
    if ( bChangeFillColor )
    {
        bChangeFont = sal_True;
		mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
    }
    Font aTmp( maFont );
    aTmp.SetColor( maTextColor );
    aTmp.SetFillColor( maBkColor );

    if( mnBkMode == TRANSPARENT )
		aTmp.SetTransparent( sal_True );
	else
		aTmp.SetTransparent( sal_False );

	if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
		aTmp.SetAlign( ALIGN_BASELINE );
	else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
		aTmp.SetAlign( ALIGN_BOTTOM );
	else
		aTmp.SetAlign( ALIGN_TOP );

	if ( nGfxMode == GM_ADVANCED )
	{
		// check whether there is a font rotation applied via transformation
		Point aP1( ImplMap( Point() ) );
		Point aP2( ImplMap( Point( 0, 100 ) ) );
		aP2.X() -= aP1.X();
		aP2.Y() -= aP1.Y();
		double fX = aP2.X();
		double fY = aP2.Y();
		if ( fX )
		{
			double fOrientation = acos( fX / sqrt( fX * fX + fY * fY ) ) * 57.29577951308;
			if ( fY > 0 )
				fOrientation = 360 - fOrientation;
			fOrientation += 90;
			fOrientation *= 10;
			fOrientation += aTmp.GetOrientation();
			aTmp.SetOrientation( sal_Int16( fOrientation ) );
		}
	}

	if( mnTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) )
	{
        // #117968# VirtualDevice is not thread safe, but filter is used in multithreading
        vos::OGuard aGuard( Application::GetSolarMutex() );
	    VirtualDevice aVDev;
		sal_Int32 nTextWidth;
		
        aVDev.SetMapMode( MapMode( MAP_100TH_MM ) );
		aVDev.SetFont( maFont );
		
        if( pDXArry )
		{
			sal_uInt32 nLen = rText.Len();
			nTextWidth = aVDev.GetTextWidth( rText.GetChar( (sal_uInt16)( nLen - 1 ) ) );
			if( nLen > 1 )
				nTextWidth += pDXArry[ nLen - 2 ];
		}
		else
			nTextWidth = aVDev.GetTextWidth( rText );

		if( mnTextAlign & TA_UPDATECP )
			rPosition = maActPos;
	
		if ( mnTextAlign & TA_RIGHT_CENTER )
		{
			double fLenght = ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1;
			rPosition.X() -= (sal_Int32)( fLenght * cos( maFont.GetOrientation() * F_PI1800 ) );
			rPosition.Y() -= (sal_Int32)(-( fLenght * sin( maFont.GetOrientation() * F_PI1800 ) ) );
		}

		if( mnTextAlign & TA_UPDATECP )
			maActPos.X() = rPosition.X() + nTextWidth;
	}   
	if ( bChangeFont || ( maLatestFont != aTmp ) )
    {
		maLatestFont = aTmp;
        mpGDIMetaFile->AddAction( new MetaFontAction( aTmp ) );
        mpGDIMetaFile->AddAction( new MetaTextAlignAction( aTmp.GetAlign() ) );
        mpGDIMetaFile->AddAction( new MetaTextColorAction( aTmp.GetColor() ) );
        mpGDIMetaFile->AddAction( new MetaTextFillColorAction( aTmp.GetFillColor(), !aTmp.IsTransparent() ) );
    }
	if ( bRecordPath )
	{
		// ToDo
	}
	else
	{
		/* because text without dx array is badly scaled, we
		   will create such an array if necessary */
		sal_Int32* pDX = pDXArry;		
		if ( !pDXArry )
		{
            // #117968# VirtualDevice is not thread safe, but filter is used in multithreading
            vos::OGuard aGuard( Application::GetSolarMutex() );
	        VirtualDevice aVDev;
			
            pDX = new sal_Int32[ rText.Len() ];
			aVDev.SetMapMode( MAP_100TH_MM );
			aVDev.SetFont( maLatestFont );
			aVDev.GetTextArray( rText, pDX, 0, STRING_LEN );
		}
		mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDX, 0, STRING_LEN ) );
		if ( !pDXArry )		// this means we have created our own array
			delete[] pDX;	// which must be deleted
	}
	SetGfxMode( nOldGfxMode );
}

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

void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap )
{
	BitmapEx aBmpEx( rBitmap );
	if ( aClipPath.GetType() == COMPLEX )
	{
        VirtualDevice aVDev;
		MapMode aMapMode( MAP_100TH_MM );
		aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) );
		const Size aOutputSizePixel( aVDev.LogicToPixel( rSize, aMapMode ) );
		const Size aSizePixel( rBitmap.GetSizePixel() );
		if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() )
		{
			aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) );
			aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) );
		}
		aVDev.SetMapMode( aMapMode );
		aVDev.SetOutputSizePixel( aSizePixel );
		aVDev.SetFillColor( Color( COL_BLACK ) );
		const PolyPolygon aClip( aClipPath.GetClipPath() );
		aVDev.DrawPolyPolygon( aClip );
        const Point aEmptyPoint;

        // #i50672# Extract whole VDev content (to match size of rBitmap)
        aVDev.EnableMapMode( sal_False );
		Bitmap aMask( aVDev.GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) );

		if ( aBmpEx.IsTransparent() )
		{
			if ( rBitmap.GetTransparentColor() == Color( COL_WHITE ) )
				aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_OR );
			else
				aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_AND );
			aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
		}
		else
			aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
	}
	if ( aBmpEx.IsTransparent() )
		mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( rPos, rSize, aBmpEx ) );
	else
		mpGDIMetaFile->AddAction( new MetaBmpScaleAction( rPos, rSize, aBmpEx.GetBitmap() ) );
}

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

void WinMtfOutput::ResolveBitmapActions( List& rSaveList )
{
	UpdateClipRegion();

	sal_uInt32 nObjects		= rSaveList.Count();
	sal_uInt32 nObjectsLeft	= nObjects;

	while ( nObjectsLeft )
	{
		sal_uInt32		i, nObjectsOfSameSize = 0;
		sal_uInt32		nObjectStartIndex = nObjects - nObjectsLeft;

		BSaveStruct*	pSave = (BSaveStruct*)rSaveList.GetObject( nObjectStartIndex );
		Rectangle		aRect( pSave->aOutRect );

		for ( i = nObjectStartIndex; i < nObjects; )
		{
			nObjectsOfSameSize++;
			if ( ++i < nObjects )
			{
				pSave = (BSaveStruct*)rSaveList.GetObject( i );
				if ( pSave->aOutRect != aRect )
					break;
			}
		}
		Point	aPos( ImplMap( aRect.TopLeft() ) );
		Size	aSize( ImplMap( aRect.GetSize() ) );

		for ( i = nObjectStartIndex; i < ( nObjectStartIndex + nObjectsOfSameSize ); i++ )
		{
			pSave = (BSaveStruct*)rSaveList.GetObject( i );

			sal_uInt32	nWinRop = pSave->nWinRop;
			sal_uInt8	nRasterOperation = (sal_uInt8)( nWinRop >> 16 );

			sal_uInt32	nUsed =  0;
			if ( ( nRasterOperation & 0xf )  != ( nRasterOperation >> 4 ) )
				nUsed |= 1;		// pattern is used
			if ( ( nRasterOperation & 0x33 ) != ( ( nRasterOperation & 0xcc ) >> 2 ) )
				nUsed |= 2;		// source is used
			if ( ( nRasterOperation & 0xaa ) != ( ( nRasterOperation & 0x55 ) << 1 ) )
				nUsed |= 4;		// destination is used

			if ( (nUsed & 1) && (( nUsed & 2 ) == 0) )
			{	// patterns aren't well supported yet
				sal_uInt32 nOldRop = SetRasterOp( ROP_OVERPAINT );	// in this case nRasterOperation is either 0 or 0xff
				UpdateFillStyle();
				DrawRect( aRect, sal_False );
				SetRasterOp( nOldRop );
			}
			else
			{
				sal_Bool bDrawn = sal_False;

				if ( i == nObjectStartIndex )	// optimizing, sometimes it is possible to create just one transparent bitmap
				{
					if ( nObjectsOfSameSize == 2 )
					{
						BSaveStruct* pSave2 = (BSaveStruct*)rSaveList.GetObject( i + 1 ); 
                        if ( ( pSave->aBmp.GetPrefSize() == pSave2->aBmp.GetPrefSize() ) &&
                             ( pSave->aBmp.GetPrefMapMode() == pSave2->aBmp.GetPrefMapMode() ) )
                        {
                            // TODO: Strictly speaking, we should
                            // check whether mask is monochrome, and
                            // whether image is black (upper branch)
                            // or white (lower branch). Otherwise, the
                            // effect is not the same as a masked
                            // bitmap.
                            if ( ( nWinRop == SRCPAINT ) && ( pSave2->nWinRop == SRCAND ) )
                            {
								Bitmap aMask( pSave->aBmp ); aMask.Invert();
								BitmapEx aBmpEx( pSave2->aBmp, aMask );
								ImplDrawBitmap( aPos, aSize, aBmpEx );
								bDrawn = sal_True;
								i++;
							}
                            // #i20085# This is just the other way
                            // around as above. Only difference: mask
                            // is inverted
                            else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCPAINT ) )
                            {
								Bitmap aMask( pSave->aBmp );
								BitmapEx aBmpEx( pSave2->aBmp, aMask );
								ImplDrawBitmap( aPos, aSize, aBmpEx );
								bDrawn = sal_True;
								i++;
                            }
                        }
					}
				}

				if ( !bDrawn )
				{
					Push();
					sal_uInt32	nOldRop = SetRasterOp( R2_COPYPEN );
					Bitmap		aBitmap( pSave->aBmp );
					sal_uInt32	nOperation = ( nRasterOperation & 0xf );
					switch( nOperation )
					{
						case 0x1 :
						case 0xe :
						{						
							SetRasterOp( R2_XORPEN );
							ImplDrawBitmap( aPos, aSize, aBitmap );
							SetRasterOp( R2_COPYPEN );
							Bitmap	aMask( aBitmap );
							aMask.Invert();
							BitmapEx aBmpEx( aBitmap, aMask );
							ImplDrawBitmap( aPos, aSize, aBmpEx );
							if ( nOperation == 0x1 )
							{
								SetRasterOp( R2_NOT );
								DrawRect( aRect, sal_False );
							}
						}
						break;
						case 0x7 :
						case 0x8 :
						{
							Bitmap	aMask( aBitmap );
							if ( ( nUsed & 1 ) && ( nRasterOperation & 0xb0 ) == 0xb0 )		// pattern used
							{
								aBitmap.Convert( BMP_CONVERSION_24BIT );
								aBitmap.Erase( maFillStyle.aFillColor );
							}
							BitmapEx aBmpEx( aBitmap, aMask );
							ImplDrawBitmap( aPos, aSize, aBmpEx );
							if ( nOperation == 0x7 )
							{
								SetRasterOp( R2_NOT );
								DrawRect( aRect, sal_False );
							}
						}
						break;

						case 0x4 :
						case 0xb :
						{
							SetRasterOp( R2_NOT );
							DrawRect( aRect, sal_False );
							SetRasterOp( R2_COPYPEN );
							Bitmap	aMask( aBitmap );
							aBitmap.Invert();
							BitmapEx aBmpEx( aBitmap, aMask );
							ImplDrawBitmap( aPos, aSize, aBmpEx );
							SetRasterOp( R2_XORPEN );
							ImplDrawBitmap( aPos, aSize, aBitmap );
							if ( nOperation == 0xb )
							{
								SetRasterOp( R2_NOT );
								DrawRect( aRect, sal_False );
							}
						}
						break;

						case 0x2 :
						case 0xd :
						{
							Bitmap	aMask( aBitmap );
							aMask.Invert();
							BitmapEx aBmpEx( aBitmap, aMask );
							ImplDrawBitmap( aPos, aSize, aBmpEx );
							SetRasterOp( R2_XORPEN );
							ImplDrawBitmap( aPos, aSize, aBitmap );
							if ( nOperation == 0xd )
							{
								SetRasterOp( R2_NOT );
								DrawRect( aRect, sal_False );
							}
						}
						break;
						case 0x6 :
						case 0x9 :
						{
							SetRasterOp( R2_XORPEN );
							ImplDrawBitmap( aPos, aSize, aBitmap );
							if ( nOperation == 0x9 )
							{
								SetRasterOp( R2_NOT );
								DrawRect( aRect, sal_False );
							}
						}
						break;

						case 0x0 :	// WHITENESS
						case 0xf :	// BLACKNESS
						{													// in this case nRasterOperation is either 0 or 0xff
							maFillStyle = WinMtfFillStyle( Color( nRasterOperation, nRasterOperation, nRasterOperation ) );
							UpdateFillStyle();
							DrawRect( aRect, sal_False );
						}
						break;

						case 0x3 :	// only source is used
						case 0xc :
						{
							if ( nRasterOperation == 0x33 )
								aBitmap.Invert();
							ImplDrawBitmap( aPos, aSize, aBitmap );
						}
						break;

						case 0x5 :	// only destination is used
						{
							SetRasterOp( R2_NOT );
							DrawRect( aRect, sal_False );
						}
						case 0xa :	// no operation
						break;
					}
					SetRasterOp( nOldRop );
					Pop();
				}
			}
		}
		nObjectsLeft -= nObjectsOfSameSize;
	}

	void* pPtr;
	for ( pPtr = rSaveList.First(); pPtr; pPtr = rSaveList.Next() )
		delete (BSaveStruct*)pPtr;
	rSaveList.Clear();
}

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

void WinMtfOutput::SetDevOrg( const Point& rPoint )
{
	mnDevOrgX = rPoint.X();
	mnDevOrgY = rPoint.Y();
}

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

void WinMtfOutput::SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
{
	mnDevOrgX += nXAdd;
	mnDevOrgY += nYAdd;
}

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

void WinMtfOutput::SetDevExt( const Size& rSize )
{
	if ( rSize.Width() && rSize.Height() )
	{
		switch( mnMapMode )
		{
			case MM_ISOTROPIC :
			case MM_ANISOTROPIC	:
			{
				mnDevWidth = rSize.Width();
				mnDevHeight = rSize.Height();
			}
		}
	}
}

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

void WinMtfOutput::ScaleDevExt( double fX, double fY )
{
	mnDevWidth = FRound( mnDevWidth * fX );
	mnDevHeight = FRound( mnDevHeight * fY );
}

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

void WinMtfOutput::SetWinOrg( const Point& rPoint )
{
	mnWinOrgX = rPoint.X();
	mnWinOrgY = rPoint.Y();
}

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

void WinMtfOutput::SetWinOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
{
	mnWinOrgX += nXAdd;
	mnWinOrgY += nYAdd;
}

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

void WinMtfOutput::SetWinExt( const Size& rSize )
{

	if( rSize.Width() && rSize.Height() )
	{
		switch( mnMapMode )
		{
			case MM_ISOTROPIC :
			case MM_ANISOTROPIC	:
			{
				mnWinExtX = rSize.Width();
				mnWinExtY = rSize.Height();
			}
		}
	}
}

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

void WinMtfOutput::ScaleWinExt( double fX, double fY )
{
	mnWinExtX = FRound( mnWinExtX * fX );
	mnWinExtY = FRound( mnWinExtY * fY );
}

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

void WinMtfOutput::SetrclBounds( const Rectangle& rRect )
{
	mrclBounds = rRect;
}

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

void WinMtfOutput::SetrclFrame( const Rectangle& rRect )
{
	mrclFrame = rRect;
}

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

void WinMtfOutput::SetRefPix( const Size& rSize )
{
	mnPixX = rSize.Width();
	mnPixY = rSize.Height();
}

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

void WinMtfOutput::SetRefMill( const Size& rSize )
{
	mnMillX = rSize.Width();
	mnMillY = rSize.Height();
}

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

void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
{
    mnMapMode = nMapMode;
	if ( nMapMode == MM_TEXT )
	{
		mnWinExtX = mnDevWidth;
		mnWinExtY = mnDevHeight;
	}
	else if ( mnMapMode == MM_HIMETRIC )
	{
		mnWinExtX = mnMillX * 100;
		mnWinExtY = mnMillY * 100;
	}
}

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

void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
{
	maXForm.eM11 = rXForm.eM11;
	maXForm.eM12 = rXForm.eM12;
	maXForm.eM21 = rXForm.eM21;
	maXForm.eM22 = rXForm.eM22;
	maXForm.eDx = rXForm.eDx;
	maXForm.eDy = rXForm.eDy;
}

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

void WinMtfOutput::ModifyWorldTransform( const XForm& rXForm, sal_uInt32 nMode )
{
	switch( nMode )
	{
		case MWT_IDENTITY :
		{
            maXForm.eM11 = maXForm.eM22 = 1.0f;
            maXForm.eM12 = maXForm.eM21 = maXForm.eDx = maXForm.eDy = 0.0f;
            break;
		}

		case MWT_RIGHTMULTIPLY :
		case MWT_LEFTMULTIPLY :
        {                
            const XForm* pLeft;
            const XForm* pRight;

            if ( nMode == MWT_LEFTMULTIPLY )
            {
                pLeft = &rXForm;
                pRight = &maXForm;
            }
            else
            {
                pLeft = &maXForm;
                pRight = &rXForm;
            }

            float aF[3][3];
            float bF[3][3];
            float cF[3][3];

            aF[0][0] = pLeft->eM11;
            aF[0][1] = pLeft->eM12;
            aF[0][2] = 0;
            aF[1][0] = pLeft->eM21;
            aF[1][1] = pLeft->eM22;
            aF[1][2] = 0;
            aF[2][0] = pLeft->eDx;
            aF[2][1] = pLeft->eDy;
            aF[2][2] = 1;

            bF[0][0] = pRight->eM11;
            bF[0][1] = pRight->eM12;
            bF[0][2] = 0;
            bF[1][0] = pRight->eM21;
            bF[1][1] = pRight->eM22;
            bF[1][2] = 0;
            bF[2][0] = pRight->eDx;
            bF[2][1] = pRight->eDy;
            bF[2][2] = 1;

            int i, j, k;
            for ( i = 0; i < 3; i++ )
            {
              for ( j = 0; j < 3; j++ )
              {
                 cF[i][j] = 0;
                 for ( k = 0; k < 3; k++ )
                    cF[i][j] += aF[i][k] * bF[k][j];
              }
            }
            maXForm.eM11 = cF[0][0];
            maXForm.eM12 = cF[0][1];
            maXForm.eM21 = cF[1][0];
            maXForm.eM22 = cF[1][1];
            maXForm.eDx = cF[2][0];
            maXForm.eDy = cF[2][1];
            break;
        }
        case MWT_SET:
        {
            SetWorldTransform(rXForm);
            break;
        }
	}
 }

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

void WinMtfOutput::Push()						// !! to be able to access the original ClipRegion it
{                                               // is not allowed to use the MetaPushAction()
	UpdateClipRegion();                         // (the original clip region is on top of the stack) (SJ)
	SaveStructPtr pSave( new SaveStruct );

	pSave->aLineStyle = maLineStyle;
	pSave->aFillStyle = maFillStyle;

	pSave->aFont = maFont;
	pSave->aTextColor = maTextColor;
    pSave->nTextAlign = mnTextAlign;
	pSave->nTextLayoutMode = mnTextLayoutMode;
	pSave->nMapMode = mnMapMode;
	pSave->nGfxMode = mnGfxMode;
	pSave->nBkMode = mnBkMode;
	pSave->aBkColor = maBkColor;
	pSave->bFillStyleSelected = mbFillStyleSelected;

	pSave->aActPos = maActPos;
    pSave->aXForm = maXForm;
    pSave->eRasterOp = meRasterOp;

	pSave->nWinOrgX = mnWinOrgX;
	pSave->nWinOrgY = mnWinOrgY;
	pSave->nWinExtX = mnWinExtX;
	pSave->nWinExtY = mnWinExtY;
	pSave->nDevOrgX = mnDevOrgX;
	pSave->nDevOrgY = mnDevOrgY;
	pSave->nDevWidth = mnDevWidth;
	pSave->nDevHeight = mnDevHeight;

	pSave->aPathObj = aPathObj;
	pSave->aClipPath = aClipPath;

	vSaveStack.push_back( pSave );
}

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

void WinMtfOutput::Pop()
{
	// Die aktuellen Daten vom Stack holen
	if( vSaveStack.size() )
	{
		// Die aktuelle Daten auf dem Stack sichern
		SaveStructPtr pSave( vSaveStack.back() );

		maLineStyle = pSave->aLineStyle;
		maFillStyle = pSave->aFillStyle;

		maFont = pSave->aFont;
		maTextColor = pSave->aTextColor;
        mnTextAlign = pSave->nTextAlign;
		mnTextLayoutMode = pSave->nTextLayoutMode;
		mnBkMode = pSave->nBkMode;
		mnGfxMode = pSave->nGfxMode;
		mnMapMode = pSave->nMapMode;
		maBkColor = pSave->aBkColor;
		mbFillStyleSelected = pSave->bFillStyleSelected;

		maActPos = pSave->aActPos;
        maXForm = pSave->aXForm;
        meRasterOp = pSave->eRasterOp;

		mnWinOrgX = pSave->nWinOrgX;
		mnWinOrgY = pSave->nWinOrgY;
		mnWinExtX = pSave->nWinExtX;
		mnWinExtY = pSave->nWinExtY;
		mnDevOrgX = pSave->nDevOrgX;
		mnDevOrgY = pSave->nDevOrgY;
		mnDevWidth = pSave->nDevWidth;
		mnDevHeight = pSave->nDevHeight;

		aPathObj = pSave->aPathObj;
        if ( ! ( aClipPath == pSave->aClipPath ) )
        {
            aClipPath = pSave->aClipPath;
		    aClipPath.bNeedsUpdate = sal_True;
        }
        if ( meLatestRasterOp != meRasterOp )
	    	mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
		vSaveStack.pop_back();
	}
}

void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
{
   rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
}
