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

#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
#include <basegfx/color/bcolor.hxx>
#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
#include <vcl/lineinfo.hxx>
#include <drawinglayer/attribute/lineattribute.hxx>
#include <drawinglayer/attribute/strokeattribute.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <vcl/metaact.hxx>
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
#include <vcl/salbtype.hxx>
#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
#include <vcl/svapp.hxx>
#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
#include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <drawinglayer/primitive2d/invertprimitive2d.hxx>
#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/wallpaperprimitive2d.hxx>
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
#include <i18npool/mslangid.hxx>
#include <drawinglayer/primitive2d/textlineprimitive2d.hxx>
#include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx>
#include <drawinglayer/primitive2d/epsprimitive2d.hxx>
#include <numeric>

//////////////////////////////////////////////////////////////////////////////

using namespace com::sun::star;

//////////////////////////////////////////////////////////////////////////////

namespace
{
	/** helper class for graphic context

		This class allows to hold a complete status of classic
		VCL OutputDevice stati. This data is needed for correct
		interpretation of the MetaFile action flow.
	*/
    class PropertyHolder
    {
    private:
		/// current transformation (aka MapMode)
		basegfx::B2DHomMatrix	maTransformation;
		MapUnit					maMapUnit;

		/// current colors
        basegfx::BColor			maLineColor;
        basegfx::BColor			maFillColor;
        basegfx::BColor			maTextColor;
        basegfx::BColor			maTextFillColor;
        basegfx::BColor			maTextLineColor;
        basegfx::BColor			maOverlineColor;

		/// clipping
        basegfx::B2DPolyPolygon maClipPolyPoygon;

        /// font, etc.
    	Font                    maFont;
    	RasterOp                maRasterOp;
        sal_uInt32              mnLayoutMode;
        LanguageType            maLanguageType;
        sal_uInt16              mnPushFlags;

        /// bitfield
		/// contains all active markers
        bool					mbLineColor : 1;
        bool					mbFillColor : 1;
        bool					mbTextColor : 1;
        bool					mbTextFillColor : 1;
        bool					mbTextLineColor : 1;
        bool					mbOverlineColor : 1;
        bool					mbClipPolyPolygonActive : 1;

    public:
        PropertyHolder()
        :   maTransformation(),
			maMapUnit(MAP_100TH_MM),
			maLineColor(),
            maFillColor(),
            maTextColor(COL_BLACK),
            maTextFillColor(),
            maTextLineColor(),
            maOverlineColor(),
            maClipPolyPoygon(),
            maFont(),
            maRasterOp(ROP_OVERPAINT),
            mnLayoutMode(0),
            maLanguageType(0),
            mnPushFlags(0),
            mbLineColor(false),
            mbFillColor(false),
            mbTextColor(true),
            mbTextFillColor(false),
            mbTextLineColor(false),
            mbOverlineColor(false),
            mbClipPolyPolygonActive(false)
        {
        }

        ~PropertyHolder()
        {
        }

		/// read/write accesses
		const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; }
		void setTransformation(const basegfx::B2DHomMatrix& rNew) { if(rNew != maTransformation) maTransformation = rNew; }

		MapUnit getMapUnit() const { return maMapUnit; }
		void setMapUnit(MapUnit eNew) { if(eNew != maMapUnit) maMapUnit = eNew; }

		const basegfx::BColor& getLineColor() const { return maLineColor; }
        void setLineColor(const basegfx::BColor& rNew) { if(rNew != maLineColor) maLineColor = rNew; }
        bool getLineColorActive() const { return mbLineColor; }
        void setLineColorActive(bool bNew) { if(bNew != mbLineColor) mbLineColor = bNew; }

        const basegfx::BColor& getFillColor() const { return maFillColor; }
        void setFillColor(const basegfx::BColor& rNew) { if(rNew != maFillColor) maFillColor = rNew; }
        bool getFillColorActive() const { return mbFillColor; }
        void setFillColorActive(bool bNew) { if(bNew != mbFillColor) mbFillColor = bNew; }

        const basegfx::BColor& getTextColor() const { return maTextColor; }
        void setTextColor(const basegfx::BColor& rNew) { if(rNew != maTextColor) maTextColor = rNew; }
        bool getTextColorActive() const { return mbTextColor; }
        void setTextColorActive(bool bNew) { if(bNew != mbTextColor) mbTextColor = bNew; }

        const basegfx::BColor& getTextFillColor() const { return maTextFillColor; }
        void setTextFillColor(const basegfx::BColor& rNew) { if(rNew != maTextFillColor) maTextFillColor = rNew; }
        bool getTextFillColorActive() const { return mbTextFillColor; }
        void setTextFillColorActive(bool bNew) { if(bNew != mbTextFillColor) mbTextFillColor = bNew; }

        const basegfx::BColor& getTextLineColor() const { return maTextLineColor; }
        void setTextLineColor(const basegfx::BColor& rNew) { if(rNew != maTextLineColor) maTextLineColor = rNew; }
        bool getTextLineColorActive() const { return mbTextLineColor; }
        void setTextLineColorActive(bool bNew) { if(bNew != mbTextLineColor) mbTextLineColor = bNew; }

        const basegfx::BColor& getOverlineColor() const { return maOverlineColor; }
        void setOverlineColor(const basegfx::BColor& rNew) { if(rNew != maOverlineColor) maOverlineColor = rNew; }
        bool getOverlineColorActive() const { return mbOverlineColor; }
        void setOverlineColorActive(bool bNew) { if(bNew != mbOverlineColor) mbOverlineColor = bNew; }

        const basegfx::B2DPolyPolygon& getClipPolyPolygon() const { return maClipPolyPoygon; }
        void setClipPolyPolygon(const basegfx::B2DPolyPolygon& rNew) { if(rNew != maClipPolyPoygon) maClipPolyPoygon = rNew; }
        bool getClipPolyPolygonActive() const { return mbClipPolyPolygonActive; }
        void setClipPolyPolygonActive(bool bNew) { if(bNew != mbClipPolyPolygonActive) mbClipPolyPolygonActive = bNew; }

        const Font& getFont() const { return maFont; }
        void setFont(const Font& rFont) { if(rFont != maFont) maFont = rFont; }

        const RasterOp& getRasterOp() const { return maRasterOp; }
        void setRasterOp(const RasterOp& rRasterOp) { if(rRasterOp != maRasterOp) maRasterOp = rRasterOp; }
        bool isRasterOpInvert() const { return (ROP_XOR == maRasterOp || ROP_INVERT == maRasterOp); }
        bool isRasterOpForceBlack() const { return ROP_0 == maRasterOp; }
        bool isRasterOpActive() const { return isRasterOpInvert() || isRasterOpForceBlack(); }

        sal_uInt32 getLayoutMode() const { return mnLayoutMode; }
        void setLayoutMode(sal_uInt32 nNew) { if(nNew != mnLayoutMode) mnLayoutMode = nNew; }

        LanguageType getLanguageType() const { return maLanguageType; }
        void setLanguageType(LanguageType aNew) { if(aNew != maLanguageType) maLanguageType = aNew; }

        sal_uInt16 getPushFlags() const { return mnPushFlags; }
        void setPushFlags(sal_uInt16 nNew) { if(nNew != mnPushFlags) mnPushFlags = nNew; }

        bool getLineOrFillActive() const { return (mbLineColor || mbFillColor); }
    };
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////

namespace
{
	/** stack for properites

		This class builds a stack based on the PropertyHolder
		class. It encapsulates the pointer/new/delete usage to
		make it safe and implements the push/pop as needed by a
		VCL Metafile interpreter. The critical part here are the
		flag values VCL OutputDevice uses here; not all stuff is
		pushed and thus needs to be copied at pop.
	*/
    class PropertyHolders
    {
    private:
        std::vector< PropertyHolder* >          maPropertyHolders;

    public:
        PropertyHolders()
        {
            maPropertyHolders.push_back(new PropertyHolder());
        }

        sal_uInt32 size()
        {
            return maPropertyHolders.size();
        }

		void PushDefault()
		{
            PropertyHolder* pNew = new PropertyHolder();
            maPropertyHolders.push_back(pNew);
		}

        void Push(sal_uInt16 nPushFlags)
        {
            if(nPushFlags)
            {
                OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: PUSH with no property holders (!)");
				if ( !maPropertyHolders.empty() )
				{
					PropertyHolder* pNew = new PropertyHolder(*maPropertyHolders.back());
					pNew->setPushFlags(nPushFlags);
					maPropertyHolders.push_back(pNew);
				}
            }
        }

        void Pop()
        {
            OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: POP with no property holders (!)");
            const sal_uInt32 nSize(maPropertyHolders.size());

            if(nSize)
            {
                const PropertyHolder* pTip = maPropertyHolders.back();
                const sal_uInt16 nPushFlags(pTip->getPushFlags());

                if(nPushFlags)
                {
                    if(nSize > 1)
                    {
                        // copy back content for all non-set flags
                        PropertyHolder* pLast = maPropertyHolders[nSize - 2];

                        if(PUSH_ALL != nPushFlags)
                        {
                            if(!(nPushFlags & PUSH_LINECOLOR      ))
                            {
                                pLast->setLineColor(pTip->getLineColor());
                                pLast->setLineColorActive(pTip->getLineColorActive());
                            }
                            if(!(nPushFlags & PUSH_FILLCOLOR      ))
                            {
                                pLast->setFillColor(pTip->getFillColor());
                                pLast->setFillColorActive(pTip->getFillColorActive());
                            }
                            if(!(nPushFlags & PUSH_FONT           ))
                            {
                                pLast->setFont(pTip->getFont());
                            }
                            if(!(nPushFlags & PUSH_TEXTCOLOR      ))
                            {
                                pLast->setTextColor(pTip->getTextColor());
                                pLast->setTextColorActive(pTip->getTextColorActive());
                            }
                            if(!(nPushFlags & PUSH_MAPMODE        ))
                            {
                                pLast->setTransformation(pTip->getTransformation());
                                pLast->setMapUnit(pTip->getMapUnit());
                            }
                            if(!(nPushFlags & PUSH_CLIPREGION     ))
                            {
                                pLast->setClipPolyPolygon(pTip->getClipPolyPolygon());
                                pLast->setClipPolyPolygonActive(pTip->getClipPolyPolygonActive());
                            }
                            if(!(nPushFlags & PUSH_RASTEROP       ))
                            {
                                pLast->setRasterOp(pTip->getRasterOp());
                            }
                            if(!(nPushFlags & PUSH_TEXTFILLCOLOR  ))
                            {
                                pLast->setTextFillColor(pTip->getTextFillColor());
                                pLast->setTextFillColorActive(pTip->getTextFillColorActive());
                            }
                            if(!(nPushFlags & PUSH_TEXTALIGN      ))
                            {
                                if(pLast->getFont().GetAlign() != pTip->getFont().GetAlign())
                                {
                                    Font aFont(pLast->getFont());
                                    aFont.SetAlign(pTip->getFont().GetAlign());
                                    pLast->setFont(aFont);
                                }
                            }
                            if(!(nPushFlags & PUSH_REFPOINT       ))
                            {
                                // not supported
                            }
                            if(!(nPushFlags & PUSH_TEXTLINECOLOR  ))
                            {
                                pLast->setTextLineColor(pTip->getTextLineColor());
                                pLast->setTextLineColorActive(pTip->getTextLineColorActive());
                            }
                            if(!(nPushFlags & PUSH_TEXTLAYOUTMODE ))
                            {
                                pLast->setLayoutMode(pTip->getLayoutMode());
                            }
                            if(!(nPushFlags & PUSH_TEXTLANGUAGE   ))
                            {
                                pLast->setLanguageType(pTip->getLanguageType());
                            }
                            if(!(nPushFlags & PUSH_OVERLINECOLOR  ))
                            {
                                pLast->setOverlineColor(pTip->getOverlineColor());
                                pLast->setOverlineColorActive(pTip->getOverlineColorActive());
                            }
                        }
                    }
                }

                // execute the pop
                delete maPropertyHolders.back();
                maPropertyHolders.pop_back();
            }
        }

        PropertyHolder& Current()
        {
			static PropertyHolder aDummy;
            OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: CURRENT with no property holders (!)");
			return maPropertyHolders.empty() ? aDummy : *maPropertyHolders.back();
        }

        ~PropertyHolders()
        {
            while(maPropertyHolders.size())
            {
                delete maPropertyHolders.back();
                maPropertyHolders.pop_back();
            }
        }
    };
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////

namespace
{
	/** helper to convert a Region to a B2DPolyPolygon
		when it does not yet contain one. In the future
		this may be expanded to merge the polygons created
		from rectangles or use a special algo to directly turn
		the spans of regions to a single, already merged
		PolyPolygon.
	 */
    basegfx::B2DPolyPolygon getB2DPolyPolygonFromRegion(const Region& rRegion)
    {
        basegfx::B2DPolyPolygon aRetval;

        if(!rRegion.IsEmpty())
        {
            Region aRegion(rRegion);

            aRetval = aRegion.GetAsB2DPolyPolygon();
        }

        return aRetval;
    }
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////

namespace
{
	/**	Helper class to buffer and hold a Primive target vector. It
		encapsulates the new/delete functionality and aloows to work
		on pointers of the implementation classes. All data will
		be converted to uno sequences of uno references when accessing the
		data.
	*/
    class TargetHolder
    {
    private:
        std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aTargets;

    public:
        TargetHolder()
        :   aTargets()
        {
        }

        ~TargetHolder()
        {
            const sal_uInt32 nCount(aTargets.size());

            for(sal_uInt32 a(0); a < nCount; a++)
            {
                delete aTargets[a];
            }
        }

        sal_uInt32 size()
        {
            return aTargets.size();
        }

        void append(drawinglayer::primitive2d::BasePrimitive2D* pCandidate)
        {
            if(pCandidate)
            {
                aTargets.push_back(pCandidate);
            }
        }

        drawinglayer::primitive2d::Primitive2DSequence getPrimitive2DSequence(const PropertyHolder& rPropertyHolder)
        {
            const sal_uInt32 nCount(aTargets.size());
            drawinglayer::primitive2d::Primitive2DSequence xRetval(nCount);

            for(sal_uInt32 a(0); a < nCount; a++)
            {
                xRetval[a] = aTargets[a];
            }

            // All Targets were pointers, but do not need to be deleted since they
            // were converted to UNO API references now, so they stay as long as
            // referenced. Do NOT delete the C++ implementation classes here, but clear
            // the buffer to not delete them in the destructor.
            aTargets.clear();

            if(xRetval.hasElements() && rPropertyHolder.getClipPolyPolygonActive())
            {
                const basegfx::B2DPolyPolygon& rClipPolyPolygon = rPropertyHolder.getClipPolyPolygon();

                if(rClipPolyPolygon.count())
                {
		            const drawinglayer::primitive2d::Primitive2DReference xMask(
			            new drawinglayer::primitive2d::MaskPrimitive2D(
				            rClipPolyPolygon,
				            xRetval));

                    xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1);
                }
            }

            return xRetval;
        }
    };
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////

namespace
{
	/** Helper class which builds a stack on the TargetHolder class	*/
    class TargetHolders
    {
    private:
        std::vector< TargetHolder* >          maTargetHolders;

    public:
        TargetHolders()
        {
            maTargetHolders.push_back(new TargetHolder());
        }

        sal_uInt32 size()
        {
            return maTargetHolders.size();
        }

        void Push()
        {
            maTargetHolders.push_back(new TargetHolder());
        }

        void Pop()
        {
            OSL_ENSURE(maTargetHolders.size(), "TargetHolders: POP with no property holders (!)");
            if(maTargetHolders.size())
            {
                delete maTargetHolders.back();
                maTargetHolders.pop_back();
            }
        }

        TargetHolder& Current()
        {
            OSL_ENSURE(maTargetHolders.size(), "TargetHolders: CURRENT with no property holders (!)");
            return *maTargetHolders.back();
        }

        ~TargetHolders()
        {
            while(maTargetHolders.size())
            {
                delete maTargetHolders.back();
                maTargetHolders.pop_back();
            }
        }
    };
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
	namespace primitive2d
	{
        /** NonOverlappingFillGradientPrimitive2D class

            This is a special version of the FillGradientPrimitive2D which decomposes
            to a non-overlapping geometry version of the gradient. This needs to be
            used to support the old XOR paint-'trick'.

            It does not need an own identifier since a renderer who wants to interpret
            it itself may do so. It just overloads the decomposition of the C++
            implementation class to do an alternative decomposition.
         */
        class NonOverlappingFillGradientPrimitive2D : public FillGradientPrimitive2D
        {
		protected:
            /// local decomposition.
			virtual Primitive2DSequence create2DDecomposition(
                const geometry::ViewInformation2D& rViewInformation) const;

		public:
            /// constructor
			NonOverlappingFillGradientPrimitive2D(
				const basegfx::B2DRange& rObjectRange,
				const attribute::FillGradientAttribute& rFillGradient)
            :   FillGradientPrimitive2D(rObjectRange, rFillGradient)
            {
            }
        };

        Primitive2DSequence NonOverlappingFillGradientPrimitive2D::create2DDecomposition(
            const geometry::ViewInformation2D& /*rViewInformation*/) const
        {
            if(!getFillGradient().isDefault())
            {
        		return createFill(false);
            }
            else
            {
                return Primitive2DSequence();
            }
        }
	} // end of namespace primitive2d
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////

namespace
{
	/** helper to convert a MapMode to a transformation */
    basegfx::B2DHomMatrix getTransformFromMapMode(const MapMode& rMapMode)
	{
		basegfx::B2DHomMatrix aMapping;
		const Fraction aNoScale(1, 1);
		const Point& rOrigin(rMapMode.GetOrigin());

		if(0 != rOrigin.X() || 0 != rOrigin.Y())
		{
			aMapping.translate(rOrigin.X(), rOrigin.Y());
		}

		if(rMapMode.GetScaleX() != aNoScale || rMapMode.GetScaleY() != aNoScale)
		{
			aMapping.scale(
				double(rMapMode.GetScaleX()),
				double(rMapMode.GetScaleY()));
		}

		return aMapping;
	}

	/** helper to create a PointArrayPrimitive2D based on current context */
    void createPointArrayPrimitive(
        const std::vector< basegfx::B2DPoint >& rPositions,
        TargetHolder& rTarget,
		PropertyHolder& rProperties,
        basegfx::BColor aBColor)
    {
		if(rPositions.size())
		{
			if(rProperties.getTransformation().isIdentity())
			{
				rTarget.append(
					new drawinglayer::primitive2d::PointArrayPrimitive2D(
						rPositions,
						aBColor));
			}
			else
			{
		        std::vector< basegfx::B2DPoint > aPositions(rPositions);

				for(sal_uInt32 a(0); a < aPositions.size(); a++)
				{
					aPositions[a] = rProperties.getTransformation() * aPositions[a];
				}

				rTarget.append(
					new drawinglayer::primitive2d::PointArrayPrimitive2D(
						aPositions,
						aBColor));
			}
		}
    }

	/** helper to create a PolygonHairlinePrimitive2D based on current context */
	void createHairlinePrimitive(
        const basegfx::B2DPolygon& rLinePolygon,
        TargetHolder& rTarget,
        PropertyHolder& rProperties)
	{
		if(rLinePolygon.count())
		{
	        basegfx::B2DPolygon aLinePolygon(rLinePolygon);
			aLinePolygon.transform(rProperties.getTransformation());
			rTarget.append(
				new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
					aLinePolygon,
					rProperties.getLineColor()));
		}
	}

	/** helper to create a PolyPolygonColorPrimitive2D based on current context */
	void createFillPrimitive(
        const basegfx::B2DPolyPolygon& rFillPolyPolygon,
        TargetHolder& rTarget,
        PropertyHolder& rProperties)
	{
		if(rFillPolyPolygon.count())
		{
	        basegfx::B2DPolyPolygon aFillPolyPolygon(rFillPolyPolygon);
			aFillPolyPolygon.transform(rProperties.getTransformation());
			rTarget.append(
				new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
					aFillPolyPolygon,
					rProperties.getFillColor()));
		}
	}

	/** helper to create a PolygonStrokePrimitive2D based on current context */
    void createLinePrimitive(
        const basegfx::B2DPolygon& rLinePolygon,
        const LineInfo& rLineInfo,
        TargetHolder& rTarget,
        PropertyHolder& rProperties)
    {
		if(rLinePolygon.count())
		{
			const bool bDashDotUsed(LINE_DASH == rLineInfo.GetStyle());
			const bool bWidthUsed(rLineInfo.GetWidth() > 1);

			if(bDashDotUsed || bWidthUsed)
			{
		        basegfx::B2DPolygon aLinePolygon(rLinePolygon);
				aLinePolygon.transform(rProperties.getTransformation());
				const drawinglayer::attribute::LineAttribute aLineAttribute(
					rProperties.getLineColor(),
					bWidthUsed ? rLineInfo.GetWidth() : 0.0,
					rLineInfo.GetLineJoin(),
                    rLineInfo.GetLineCap());

				if(bDashDotUsed)
				{
					::std::vector< double > fDotDashArray;
					const double fDashLen(rLineInfo.GetDashLen());
					const double fDotLen(rLineInfo.GetDotLen());
					const double fDistance(rLineInfo.GetDistance());

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

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

					const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
					const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(
						fDotDashArray,
						fAccumulated);

					rTarget.append(
						new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
							aLinePolygon,
							aLineAttribute,
							aStrokeAttribute));
				}
				else
				{
					rTarget.append(
						new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
							aLinePolygon,
							aLineAttribute));
				}
			}
			else
			{
				createHairlinePrimitive(rLinePolygon, rTarget, rProperties);
			}
		}
    }

	/** helper to create needed line and fill primitives based on current context */
	void createHairlineAndFillPrimitive(
        const basegfx::B2DPolygon& rPolygon,
        TargetHolder& rTarget,
        PropertyHolder& rProperties)
	{
		if(rProperties.getFillColorActive())
		{
			createFillPrimitive(basegfx::B2DPolyPolygon(rPolygon), rTarget, rProperties);
		}

		if(rProperties.getLineColorActive())
		{
			createHairlinePrimitive(rPolygon, rTarget, rProperties);
		}
	}

	/** helper to create needed line and fill primitives based on current context */
	void createHairlineAndFillPrimitive(
        const basegfx::B2DPolyPolygon& rPolyPolygon,
        TargetHolder& rTarget,
        PropertyHolder& rProperties)
	{
		if(rProperties.getFillColorActive())
		{
			createFillPrimitive(rPolyPolygon, rTarget, rProperties);
		}

		if(rProperties.getLineColorActive())
		{
			for(sal_uInt32 a(0); a < rPolyPolygon.count(); a++)
			{
				createHairlinePrimitive(rPolyPolygon.getB2DPolygon(a), rTarget, rProperties);
			}
		}
	}

	/** helper to create DiscreteBitmapPrimitive2D based on current context.
		The DiscreteBitmapPrimitive2D is especially created for this usage
		since no other usage defines a bitmap visualisation based on top-left
		position and size in pixels. At the end it will create a view-dependent
		transformed embedding of a BitmapPrimitive2D.
	*/
	void createBitmapExPrimitive(
		const BitmapEx& rBitmapEx,
		const Point& rPoint,
        TargetHolder& rTarget,
        PropertyHolder& rProperties)
	{
		if(!rBitmapEx.IsEmpty())
		{
			basegfx::B2DPoint aPoint(rPoint.X(), rPoint.Y());
			aPoint = rProperties.getTransformation() * aPoint;

			rTarget.append(
				new drawinglayer::primitive2d::DiscreteBitmapPrimitive2D(
					rBitmapEx,
					aPoint));
		}
	}

	/** helper to create BitmapPrimitive2D based on current context */
	void createBitmapExPrimitive(
		const BitmapEx& rBitmapEx,
		const Point& rPoint,
		const Size& rSize,
        TargetHolder& rTarget,
        PropertyHolder& rProperties)
	{
		if(!rBitmapEx.IsEmpty())
		{
			basegfx::B2DHomMatrix aObjectTransform;

			aObjectTransform.set(0, 0, rSize.Width());
			aObjectTransform.set(1, 1, rSize.Height());
			aObjectTransform.set(0, 2, rPoint.X());
			aObjectTransform.set(1, 2, rPoint.Y());

			aObjectTransform = rProperties.getTransformation() * aObjectTransform;

			rTarget.append(
				new drawinglayer::primitive2d::BitmapPrimitive2D(
					rBitmapEx,
					aObjectTransform));
		}
	}

	/** helper to create a regular BotmapEx from a MaskAction (definitions
		which use a bitmap without transparence but define one of the colors as
		transparent)
	 */
    BitmapEx createMaskBmpEx(const Bitmap& rBitmap, const Color& rMaskColor)
    {
        const Color aWhite(COL_WHITE);
        BitmapPalette aBiLevelPalette(2);

		aBiLevelPalette[0] = aWhite;
        aBiLevelPalette[1] = rMaskColor;

        Bitmap aMask(rBitmap.CreateMask(aWhite));
        Bitmap aSolid(rBitmap.GetSizePixel(), 1, &aBiLevelPalette);

		aSolid.Erase(rMaskColor);

        return BitmapEx(aSolid, aMask);
    }

	/** helper to convert from a VCL Gradient definition to the corresponding
		data for primitive representation
	 */
	drawinglayer::attribute::FillGradientAttribute createFillGradientAttribute(const Gradient& rGradient)
	{
		const Color aStartColor(rGradient.GetStartColor());
		const sal_uInt16 nStartIntens(rGradient.GetStartIntensity());
		basegfx::BColor aStart(aStartColor.getBColor());

		if(nStartIntens != 100)
		{
			const basegfx::BColor aBlack;
			aStart = interpolate(aBlack, aStart, (double)nStartIntens * 0.01);
		}

		const Color aEndColor(rGradient.GetEndColor());
		const sal_uInt16 nEndIntens(rGradient.GetEndIntensity());
		basegfx::BColor aEnd(aEndColor.getBColor());

		if(nEndIntens != 100)
		{
			const basegfx::BColor aBlack;
			aEnd = interpolate(aBlack, aEnd, (double)nEndIntens * 0.01);
		}

		drawinglayer::attribute::GradientStyle aGradientStyle(drawinglayer::attribute::GRADIENTSTYLE_RECT);

		switch(rGradient.GetStyle())
		{
			case GRADIENT_LINEAR :
			{
				aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_LINEAR;
				break;
			}
			case GRADIENT_AXIAL :
			{
				aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_AXIAL;
				break;
			}
			case GRADIENT_RADIAL :
			{
				aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_RADIAL;
				break;
			}
			case GRADIENT_ELLIPTICAL :
			{
				aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_ELLIPTICAL;
				break;
			}
			case GRADIENT_SQUARE :
			{
				aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_SQUARE;
				break;
			}
			default : // GRADIENT_RECT
			{
				aGradientStyle = drawinglayer::attribute::GRADIENTSTYLE_RECT;
				break;
			}
		}

		return drawinglayer::attribute::FillGradientAttribute(
			aGradientStyle,
			(double)rGradient.GetBorder() * 0.01,
			(double)rGradient.GetOfsX() * 0.01,
			(double)rGradient.GetOfsY() * 0.01,
			(double)rGradient.GetAngle() * F_PI1800,
			aStart,
			aEnd,
			rGradient.GetSteps());
	}

	/** helper to convert from a VCL Hatch definition to the corresponding
		data for primitive representation
	 */
	drawinglayer::attribute::FillHatchAttribute createFillHatchAttribute(const Hatch& rHatch)
	{
		drawinglayer::attribute::HatchStyle aHatchStyle(drawinglayer::attribute::HATCHSTYLE_SINGLE);

		switch(rHatch.GetStyle())
		{
            default : // case HATCH_SINGLE :
			{
				aHatchStyle = drawinglayer::attribute::HATCHSTYLE_SINGLE;
                break;
			}
			case HATCH_DOUBLE :
			{
				aHatchStyle = drawinglayer::attribute::HATCHSTYLE_DOUBLE;
                break;
			}
            case HATCH_TRIPLE :
			{
				aHatchStyle = drawinglayer::attribute::HATCHSTYLE_TRIPLE;
                break;
			}
		}

        return drawinglayer::attribute::FillHatchAttribute(
            aHatchStyle,
            (double)rHatch.GetDistance(),
            (double)rHatch.GetAngle() * F_PI1800,
            rHatch.GetColor().getBColor(),
            3, // same default as VCL, a minimum of three discrete units (pixels) offset
            false);
	}

	/** helper to take needed action on ClipRegion change. This method needs to be called
		on any Region change, e.g. at the obvious actions doing this, but also at pop-calls
		whcih change the Region of the current context. It takes care of creating the
		current embeddec context, set the new Region at the context and eventually prepare
		a new target for embracing new geometry to the current region
	 */
    void HandleNewClipRegion(
        const basegfx::B2DPolyPolygon& rClipPolyPolygon,
        TargetHolders& rTargetHolders,
        PropertyHolders& rPropertyHolders)
    {
        const bool bNewActive(rClipPolyPolygon.count());

		// #i108636# The handlig of new ClipPolyPolygons was not done as good as possible
		// in the first version of this interpreter; e.g. when a ClipPolyPolygon was set
		// initially and then using a lot of push/pop actions, the pop always leads
		// to setting a 'new' ClipPolyPolygon which indeed is the return to the ClipPolyPolygon
		// of the properties next on the stack.
        //
		// This ClipPolyPolygon is identical to the current one, so there is no need to
		// create a MaskPrimitive2D containing the up-to-now created primitives, but
		// this was done before. While this does not lead to wrong primitive
		// representations of the metafile data, it creates unneccesarily expensive
		// representations. Just detecting when no really 'new' ClipPolyPolygon gets set
		// solves the problem.

		if(!rPropertyHolders.Current().getClipPolyPolygonActive() && !bNewActive)
		{
			// no active ClipPolyPolygon exchanged by no new one, done
			return;
		}

		if(rPropertyHolders.Current().getClipPolyPolygonActive() && bNewActive)
		{
			// active ClipPolyPolygon and new active ClipPolyPolygon
			if(rPropertyHolders.Current().getClipPolyPolygon() == rClipPolyPolygon)
			{
				// new is the same as old, done
				return;
			}
		}

		// Here the old and the new are definitively different, maybe
		// old one and/or new one is not active.

		// Handle deletion of old ClipPolyPolygon. The process evtl. created primitives which
		// belong to this active ClipPolyPolygon. These need to be embedded to a
		// MaskPrimitive2D accordingly.
        if(rPropertyHolders.Current().getClipPolyPolygonActive() && rTargetHolders.size() > 1)
        {
            drawinglayer::primitive2d::Primitive2DSequence aSubContent;

            if(rPropertyHolders.Current().getClipPolyPolygon().count()
                && rTargetHolders.Current().size())
            {
                aSubContent = rTargetHolders.Current().getPrimitive2DSequence(
                    rPropertyHolders.Current());
            }

            rTargetHolders.Pop();

            if(aSubContent.hasElements())
            {
                rTargetHolders.Current().append(
			        new drawinglayer::primitive2d::GroupPrimitive2D(
				        aSubContent));
            }
        }

        // apply new settings to current properties by setting
		// the new region now
        rPropertyHolders.Current().setClipPolyPolygonActive(bNewActive);

        if(bNewActive)
        {
            rPropertyHolders.Current().setClipPolyPolygon(rClipPolyPolygon);

            // prepare new content holder for new active region
            rTargetHolders.Push();
        }
    }

	/** helper to handle the change of RasterOp. It takes care of encapsulating all current
		geometry to the current RasterOp (if changed) and needs to be called on any RasterOp
		change. It will also start a new geometry target to embrace to the new RasterOp if
		a changuing RasterOp is used. Currently, ROP_XOR and ROP_INVERT are supported using
		InvertPrimitive2D, and ROP_0 by using a ModifiedColorPrimitive2D to force to black paint
	 */
    void HandleNewRasterOp(
        RasterOp aRasterOp,
        TargetHolders& rTargetHolders,
        PropertyHolders& rPropertyHolders)
    {
        // check if currently active
        if(rPropertyHolders.Current().isRasterOpActive() && rTargetHolders.size() > 1)
        {
            drawinglayer::primitive2d::Primitive2DSequence aSubContent;

            if(rTargetHolders.Current().size())
            {
                aSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current());
            }

            rTargetHolders.Pop();

            if(aSubContent.hasElements())
            {
                if(rPropertyHolders.Current().isRasterOpForceBlack())
                {
                    // force content to black
                    rTargetHolders.Current().append(
                        new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
                            aSubContent,
                            basegfx::BColorModifierSharedPtr(
                                new basegfx::BColorModifier_replace(
                                    basegfx::BColor(0.0, 0.0, 0.0)))));
                }
                else // if(rPropertyHolders.Current().isRasterOpInvert())
                {
                    // invert content
                    rTargetHolders.Current().append(
                        new drawinglayer::primitive2d::InvertPrimitive2D(
                            aSubContent));
                }
            }
        }

        // apply new settings
        rPropertyHolders.Current().setRasterOp(aRasterOp);

        // check if now active
        if(rPropertyHolders.Current().isRasterOpActive())
        {
            // prepare new content holder for new invert
            rTargetHolders.Push();
        }
    }

	/** helper to create needed data to emulate the VCL Wallpaper Metafile action.
		It is a quite mighty action. This helper is for simple color filled background.
	 */
    drawinglayer::primitive2d::BasePrimitive2D* CreateColorWallpaper(
        const basegfx::B2DRange& rRange,
        const basegfx::BColor& rColor,
        PropertyHolder& rPropertyHolder)
    {
        basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(rRange));
		aOutline.transform(rPropertyHolder.getTransformation());

        return new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
		    basegfx::B2DPolyPolygon(aOutline),
		    rColor);
    }

	/** helper to create needed data to emulate the VCL Wallpaper Metafile action.
		It is a quite mighty action. This helper is for gradient filled background.
	 */
    drawinglayer::primitive2d::BasePrimitive2D* CreateGradientWallpaper(
        const basegfx::B2DRange& rRange,
        const Gradient& rGradient,
        PropertyHolder& rPropertyHolder)
    {
    	const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient));

		if(aAttribute.getStartColor() == aAttribute.getEndColor())
		{
			// not really a gradient. Create filled rectangle
            return CreateColorWallpaper(rRange, aAttribute.getStartColor(), rPropertyHolder);
		}
		else
		{
			// really a gradient
		    drawinglayer::primitive2d::BasePrimitive2D* pRetval =
				new drawinglayer::primitive2d::FillGradientPrimitive2D(
					rRange,
				    aAttribute);

			if(!rPropertyHolder.getTransformation().isIdentity())
            {
                const drawinglayer::primitive2d::Primitive2DReference xPrim(pRetval);
                const drawinglayer::primitive2d::Primitive2DSequence xSeq(&xPrim, 1);

			    pRetval = new drawinglayer::primitive2d::TransformPrimitive2D(
			        rPropertyHolder.getTransformation(),
			        xSeq);
            }

			return pRetval;
		}
    }

	/** helper to create needed data to emulate the VCL Wallpaper Metafile action.
		It is a quite mighty action. This helper decides if color and/or gradient
		background is needed for the wnated bitmap fill and then creates the needed
		WallpaperBitmapPrimitive2D. This primitive was created for this purpose and
		takes over all needed logic of orientations and tiling.
	 */
    void CreateAndAppendBitmapWallpaper(
        basegfx::B2DRange aWallpaperRange,
		const Wallpaper& rWallpaper,
		TargetHolder& rTarget,
		PropertyHolder& rProperty)
	{
	    const BitmapEx aBitmapEx(rWallpaper.GetBitmap());
		const WallpaperStyle eWallpaperStyle(rWallpaper.GetStyle());

        // if bitmap visualisation is transparent, maybe background
        // needs to be filled. Create background
        if(aBitmapEx.IsTransparent()
            || (WALLPAPER_TILE != eWallpaperStyle && WALLPAPER_SCALE != eWallpaperStyle))
        {
            if(rWallpaper.IsGradient())
            {
                rTarget.append(
	                CreateGradientWallpaper(
		                aWallpaperRange,
                        rWallpaper.GetGradient(),
                        rProperty));
            }
            else if(!rWallpaper.GetColor().GetTransparency())
            {
                rTarget.append(
	                CreateColorWallpaper(
		                aWallpaperRange,
                        rWallpaper.GetColor().getBColor(),
                        rProperty));
            }
        }

        // use wallpaper rect if set
        if(rWallpaper.IsRect() && !rWallpaper.GetRect().IsEmpty())
        {
            aWallpaperRange = basegfx::B2DRange(
                rWallpaper.GetRect().Left(), rWallpaper.GetRect().Top(),
                rWallpaper.GetRect().Right(), rWallpaper.GetRect().Bottom());
        }

		drawinglayer::primitive2d::BasePrimitive2D* pBitmapWallpaperFill =
	        new drawinglayer::primitive2d::WallpaperBitmapPrimitive2D(
		        aWallpaperRange,
				aBitmapEx,
				eWallpaperStyle);

		if(rProperty.getTransformation().isIdentity())
        {
			// add directly
            rTarget.append(pBitmapWallpaperFill);
        }
        else
        {
			// when a transformation is set, embed to it
            const drawinglayer::primitive2d::Primitive2DReference xPrim(pBitmapWallpaperFill);

	        rTarget.append(
		        new drawinglayer::primitive2d::TransformPrimitive2D(
			        rProperty.getTransformation(),
			        drawinglayer::primitive2d::Primitive2DSequence(&xPrim, 1)));
        }
	}

	/** helper to decide UnderlineAbove for text primitives */
	bool isUnderlineAbove(const Font& rFont)
	{
		if(!rFont.IsVertical())
		{
			return false;
		}

		if((LANGUAGE_JAPANESE == rFont.GetLanguage()) || (LANGUAGE_JAPANESE == rFont.GetCJKContextLanguage()))
		{
			// the underline is right for Japanese only
			return true;
		}

		return false;
	}

	void createFontAttributeTransformAndAlignment(
		drawinglayer::attribute::FontAttribute& rFontAttribute,
		basegfx::B2DHomMatrix& rTextTransform,
		basegfx::B2DVector& rAlignmentOffset,
		PropertyHolder& rProperty)
	{
		const Font& rFont = rProperty.getFont();
		basegfx::B2DVector aFontScaling;

		rFontAttribute = drawinglayer::attribute::FontAttribute(
			drawinglayer::primitive2d::getFontAttributeFromVclFont(
				aFontScaling,
				rFont,
				0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_RTL),
				0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_STRONG)));

		// add FontScaling
		rTextTransform.scale(aFontScaling.getX(), aFontScaling.getY());

        // take text align into account
        if(ALIGN_BASELINE != rFont.GetAlign())
        {
            drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
            aTextLayouterDevice.setFont(rFont);

            if(ALIGN_TOP == rFont.GetAlign())
            {
                rAlignmentOffset.setY(aTextLayouterDevice.getFontAscent());
            }
            else // ALIGN_BOTTOM
            {
                rAlignmentOffset.setY(-aTextLayouterDevice.getFontDescent());
            }

            rTextTransform.translate(rAlignmentOffset.getX(), rAlignmentOffset.getY());
        }

		// add FontRotation (if used)
		if(rFont.GetOrientation())
		{
			rTextTransform.rotate(-rFont.GetOrientation() * F_PI1800);
		}
	}

	/** helper which takes complete care for creating the needed text primitives. It
		takes care of decorated stuff and all the geometry adaptions needed
	 */
	void proccessMetaTextAction(
		const Point& rTextStartPosition,
		const XubString& rText,
		sal_uInt16 nTextStart,
		sal_uInt16 nTextLength,
		const ::std::vector< double >& rDXArray,
		TargetHolder& rTarget,
		PropertyHolder& rProperty)
	{
		drawinglayer::primitive2d::BasePrimitive2D* pResult = 0;
		const Font& rFont = rProperty.getFont();
        basegfx::B2DVector aAlignmentOffset(0.0, 0.0);

		if(nTextLength)
		{
			drawinglayer::attribute::FontAttribute aFontAttribute;
			basegfx::B2DHomMatrix aTextTransform;

			// fill parameters derived from current font
			createFontAttributeTransformAndAlignment(
				aFontAttribute,
				aTextTransform,
				aAlignmentOffset,
				rProperty);

			// add TextStartPosition
			aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y());

			// prepare FontColor and Locale
			const basegfx::BColor aFontColor(rProperty.getTextColor());
		    const com::sun::star::lang::Locale aLocale(MsLangId::convertLanguageToLocale(rProperty.getLanguageType()));
			const bool bWordLineMode(rFont.IsWordLineMode());

			const bool bDecoratedIsNeeded(
				   UNDERLINE_NONE != rFont.GetOverline()
				|| UNDERLINE_NONE != rFont.GetUnderline()
				|| STRIKEOUT_NONE != rFont.GetStrikeout()
				|| EMPHASISMARK_NONE != (rFont.GetEmphasisMark() & EMPHASISMARK_STYLE)
				|| RELIEF_NONE != rFont.GetRelief()
				|| rFont.IsShadow()
                || bWordLineMode);

			if(bDecoratedIsNeeded)
			{
                // prepare overline, underline and srikeout data
                const drawinglayer::primitive2d::TextLine eFontOverline(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rFont.GetOverline()));
                const drawinglayer::primitive2d::TextLine eFontUnderline(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rFont.GetUnderline()));
				const drawinglayer::primitive2d::TextStrikeout eTextStrikeout(drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rFont.GetStrikeout()));

                // check UndelineAbove
				const bool bUnderlineAbove(drawinglayer::primitive2d::TEXT_LINE_NONE != eFontUnderline && isUnderlineAbove(rFont));

				// prepare emphasis mark data
				drawinglayer::primitive2d::TextEmphasisMark eTextEmphasisMark(drawinglayer::primitive2d::TEXT_EMPHASISMARK_NONE);

				switch(rFont.GetEmphasisMark() & EMPHASISMARK_STYLE)
				{
					case EMPHASISMARK_DOT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DOT; break;
					case EMPHASISMARK_CIRCLE : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_CIRCLE; break;
					case EMPHASISMARK_DISC : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DISC; break;
					case EMPHASISMARK_ACCENT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_ACCENT; break;
				}

				const bool bEmphasisMarkAbove(rFont.GetEmphasisMark() & EMPHASISMARK_POS_ABOVE);
				const bool bEmphasisMarkBelow(rFont.GetEmphasisMark() & EMPHASISMARK_POS_BELOW);

				// prepare font relief data
				drawinglayer::primitive2d::TextRelief eTextRelief(drawinglayer::primitive2d::TEXT_RELIEF_NONE);

				switch(rFont.GetRelief())
				{
					case RELIEF_EMBOSSED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_EMBOSSED; break;
					case RELIEF_ENGRAVED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_ENGRAVED; break;
					default : break; // RELIEF_NONE, FontRelief_FORCE_EQUAL_SIZE
				}

				// prepare shadow/outline data
				const bool bShadow(rFont.IsShadow());

				// TextDecoratedPortionPrimitive2D is needed, create one
                pResult = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D(

					// attributes for TextSimplePortionPrimitive2D
					aTextTransform,
					rText,
					nTextStart,
					nTextLength,
					rDXArray,
					aFontAttribute,
					aLocale,
					aFontColor,

					// attributes for TextDecoratedPortionPrimitive2D
					rProperty.getOverlineColorActive() ? rProperty.getOverlineColor() : aFontColor,
					rProperty.getTextLineColorActive() ? rProperty.getTextLineColor() : aFontColor,
                    eFontOverline,
                    eFontUnderline,
					bUnderlineAbove,
					eTextStrikeout,
					bWordLineMode,
					eTextEmphasisMark,
					bEmphasisMarkAbove,
					bEmphasisMarkBelow,
					eTextRelief,
					bShadow);
			}
			else
			{
				// TextSimplePortionPrimitive2D is enough
				pResult = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
					aTextTransform,
					rText,
					nTextStart,
					nTextLength,
					rDXArray,
					aFontAttribute,
					aLocale,
					aFontColor);
			}
		}

        if(pResult && rProperty.getTextFillColorActive())
        {
            // text background is requested, add and encapsulate both to new primitive
            drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
            aTextLayouterDevice.setFont(rFont);

			// get text width
			double fTextWidth(0.0);

			if(rDXArray.empty())
			{
				fTextWidth = aTextLayouterDevice.getTextWidth(rText, nTextStart, nTextLength);
			}
			else
			{
				fTextWidth = rDXArray.back();
			}

            if(basegfx::fTools::more(fTextWidth, 0.0))
            {
                // build text range
                const basegfx::B2DRange aTextRange(
                    0.0, -aTextLayouterDevice.getFontAscent(),
                    fTextWidth, aTextLayouterDevice.getFontDescent());

                // create Transform
			    basegfx::B2DHomMatrix aTextTransform;

                aTextTransform.translate(aAlignmentOffset.getX(), aAlignmentOffset.getY());

                if(rFont.GetOrientation())
			    {
				    aTextTransform.rotate(-rFont.GetOrientation() * F_PI1800);
			    }

                aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y());

                // prepare Primitive2DSequence, put text in foreground
                drawinglayer::primitive2d::Primitive2DSequence aSequence(2);
                aSequence[1] = drawinglayer::primitive2d::Primitive2DReference(pResult);

                // prepare filled polygon
                basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aTextRange));
		        aOutline.transform(aTextTransform);

                aSequence[0] = drawinglayer::primitive2d::Primitive2DReference(
				    new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
                        basegfx::B2DPolyPolygon(aOutline),
                        rProperty.getTextFillColor()));

                // set as group at pResult
			    pResult = new drawinglayer::primitive2d::GroupPrimitive2D(aSequence);
            }
        }

		if(pResult)
		{
			// add created text primitive to target
			if(rProperty.getTransformation().isIdentity())
			{
		        rTarget.append(pResult);
			}
			else
			{
				// when a transformation is set, embed to it
	            const drawinglayer::primitive2d::Primitive2DReference aReference(pResult);

				rTarget.append(
					new drawinglayer::primitive2d::TransformPrimitive2D(
						rProperty.getTransformation(),
						drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1)));
			}
		}
	}

	/** helper which takes complete care for creating the needed textLine primitives */
	void proccessMetaTextLineAction(
		const MetaTextLineAction& rAction,
		TargetHolder& rTarget,
		PropertyHolder& rProperty)
	{
		const double fLineWidth(fabs((double)rAction.GetWidth()));

		if(fLineWidth > 0.0)
		{
		    const drawinglayer::primitive2d::TextLine aOverlineMode(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rAction.GetOverline()));
		    const drawinglayer::primitive2d::TextLine aUnderlineMode(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rAction.GetUnderline()));
			const drawinglayer::primitive2d::TextStrikeout aTextStrikeout(drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rAction.GetStrikeout()));

			const bool bOverlineUsed(drawinglayer::primitive2d::TEXT_LINE_NONE != aOverlineMode);
			const bool bUnderlineUsed(drawinglayer::primitive2d::TEXT_LINE_NONE != aUnderlineMode);
			const bool bStrikeoutUsed(drawinglayer::primitive2d::TEXT_STRIKEOUT_NONE != aTextStrikeout);

			if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed)
			{
				std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aTargetVector;
				basegfx::B2DVector aAlignmentOffset(0.0, 0.0);
				drawinglayer::attribute::FontAttribute aFontAttribute;
				basegfx::B2DHomMatrix aTextTransform;

				// fill parameters derived from current font
				createFontAttributeTransformAndAlignment(
					aFontAttribute,
					aTextTransform,
					aAlignmentOffset,
					rProperty);

				// add TextStartPosition
				aTextTransform.translate(rAction.GetStartPoint().X(), rAction.GetStartPoint().Y());

				// prepare TextLayouter (used in most cases)
				drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
				aTextLayouter.setFont(rProperty.getFont());

				if(bOverlineUsed)
				{
					// create primitive geometry for overline
					aTargetVector.push_back(
						new drawinglayer::primitive2d::TextLinePrimitive2D(
							aTextTransform,
							fLineWidth,
							aTextLayouter.getOverlineOffset(),
							aTextLayouter.getOverlineHeight(),
							aOverlineMode,
							rProperty.getOverlineColor()));
				}

				if(bUnderlineUsed)
				{
					// create primitive geometry for underline
					aTargetVector.push_back(
						new drawinglayer::primitive2d::TextLinePrimitive2D(
							aTextTransform,
							fLineWidth,
							aTextLayouter.getUnderlineOffset(),
							aTextLayouter.getUnderlineHeight(),
							aUnderlineMode,
							rProperty.getTextLineColor()));
				}

				if(bStrikeoutUsed)
				{
					// create primitive geometry for strikeout
					if(drawinglayer::primitive2d::TEXT_STRIKEOUT_SLASH == aTextStrikeout
						|| drawinglayer::primitive2d::TEXT_STRIKEOUT_X == aTextStrikeout)
					{
						// strikeout with character
						const sal_Unicode aStrikeoutChar(
							drawinglayer::primitive2d::TEXT_STRIKEOUT_SLASH == aTextStrikeout ? '/' : 'X');
					    const com::sun::star::lang::Locale aLocale(MsLangId::convertLanguageToLocale(
							rProperty.getLanguageType()));

						aTargetVector.push_back(
							new drawinglayer::primitive2d::TextCharacterStrikeoutPrimitive2D(
								aTextTransform,
								fLineWidth,
								rProperty.getTextColor(),
								aStrikeoutChar,
								aFontAttribute,
								aLocale));
					}
					else
					{
						// strikeout with geometry
						aTargetVector.push_back(
							new drawinglayer::primitive2d::TextGeometryStrikeoutPrimitive2D(
								aTextTransform,
								fLineWidth,
								rProperty.getTextColor(),
								aTextLayouter.getUnderlineHeight(),
								aTextLayouter.getStrikeoutOffset(),
								aTextStrikeout));
					}
				}

				if(aTargetVector.size())
				{
					// add created text primitive to target
					if(rProperty.getTransformation().isIdentity())
					{
						for(sal_uInt32 a(0); a < aTargetVector.size(); a++)
						{
							rTarget.append(aTargetVector[a]);
						}
					}
					else
					{
						// when a transformation is set, embed to it
						drawinglayer::primitive2d::Primitive2DSequence xTargets(aTargetVector.size());

						for(sal_uInt32 a(0); a < aTargetVector.size(); a++)
						{
							xTargets[a] = drawinglayer::primitive2d::Primitive2DReference(aTargetVector[a]);
						}

						rTarget.append(
							new drawinglayer::primitive2d::TransformPrimitive2D(
								rProperty.getTransformation(),
								xTargets));
					}
				}
			}
		}

	}

	/** This is the main interpreter method. It is designed to handle the given Metafile
		completely inside the given context and target. It may use and modify the context and
		target. This design allows to call itself recursively wich adapted contexts and
		targets as e.g. needed for the META_FLOATTRANSPARENT_ACTION where the content is expressed
		as a metafile as sub-content.

		This interpreter is as free of VCL functionality as possible. It uses VCL data classes
		(else reading the data would not be possible), but e.g. does NOT use a local OutputDevice
		as most other MetaFile interpreters/exporters do to hold and work with the current context.
		This is necessary to be able to get away from the strong internal VCL-binding.

		It tries to combine e.g. pixel and/or point actions and to stitch together single line primitives
		where possible (which is not trivial with the possible line geometry definitions).

		It tries to handle clipping no longer as Regions and spans of Rectangles, but as PolyPolygon
		ClipRegions with (where possible) high precision by using the best possible data quality
		from the Region. The Region is unavoidable as data container, but nowadays allows the transport
		of Polygon-based clip regions. Where this is not used, a Polygon is constructed from the
		Region ranges. All primitive clipping uses the MaskPrimitive2D with Polygon-based clipping.

		I have marked the single MetaActions with:

		SIMPLE, DONE:
		Simple, e.g nothing to do or value setting in the context

		CHECKED, WORKS WELL:
		Thoroughly tested with extra written test code which created a replacement
		Metafile just to test this action in various combinations

		NEEDS IMPLEMENTATION:
		Not implemented and asserted, but also no usage found, neither in own Metafile
		creations, nor in EMF/WMF imports (checked with a whole bunch of critical EMF/WMF
		bugdocs)

		For more commens, see the single action implementations.
	*/
    void interpretMetafile(
        const GDIMetaFile& rMetaFile,
        TargetHolders& rTargetHolders,
        PropertyHolders& rPropertyHolders,
		const drawinglayer::geometry::ViewInformation2D& rViewInformation)
    {
        const sal_uInt32 nCount(rMetaFile.GetActionCount());

        for(sal_uInt32 nAction(0); nAction < nCount; nAction++)
        {
            MetaAction* pAction = rMetaFile.GetAction(nAction);

            switch(pAction->GetType())
            {
                case META_NULL_ACTION :
                {
					/** SIMPLE, DONE */
                    break;
                }
                case META_PIXEL_ACTION :
                {
					/** CHECKED, WORKS WELL */
    			    std::vector< basegfx::B2DPoint > aPositions;
                    Color aLastColor(COL_BLACK);

                    while(META_PIXEL_ACTION == pAction->GetType() && nAction < nCount)
                    {
                        const MetaPixelAction* pA = (const MetaPixelAction*)pAction;

                        if(pA->GetColor() != aLastColor)
                        {
                            if(aPositions.size())
                            {
                                createPointArrayPrimitive(aPositions, rTargetHolders.Current(), rPropertyHolders.Current(), aLastColor.getBColor());
                                aPositions.clear();
                            }

                            aLastColor = pA->GetColor();
                        }

                        const Point& rPoint = pA->GetPoint();
                        aPositions.push_back(basegfx::B2DPoint(rPoint.X(), rPoint.Y()));
						nAction++; if(nAction < nCount) pAction = rMetaFile.GetAction(nAction);
                    }

                    nAction--;

                    if(aPositions.size())
                    {
                        createPointArrayPrimitive(aPositions, rTargetHolders.Current(), rPropertyHolders.Current(), aLastColor.getBColor());
                    }

                    break;
                }
                case META_POINT_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    if(rPropertyHolders.Current().getLineColorActive())
                    {
        			    std::vector< basegfx::B2DPoint > aPositions;

                        while(META_POINT_ACTION == pAction->GetType() && nAction < nCount)
                        {
                            const MetaPointAction* pA = (const MetaPointAction*)pAction;
                            const Point& rPoint = pA->GetPoint();
                            aPositions.push_back(basegfx::B2DPoint(rPoint.X(), rPoint.Y()));
							nAction++; if(nAction < nCount) pAction = rMetaFile.GetAction(nAction);
                        }

                        nAction--;

                        if(aPositions.size())
                        {
                            createPointArrayPrimitive(aPositions, rTargetHolders.Current(), rPropertyHolders.Current(), rPropertyHolders.Current().getLineColor());
                        }
                    }

                    break;
                }
                case META_LINE_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    if(rPropertyHolders.Current().getLineColorActive())
                    {
                        basegfx::B2DPolygon aLinePolygon;
                        LineInfo aLineInfo;

                        while(META_LINE_ACTION == pAction->GetType() && nAction < nCount)
                        {
                            const MetaLineAction* pA = (const MetaLineAction*)pAction;
                            const Point& rStartPoint = pA->GetStartPoint();
                            const Point& rEndPoint = pA->GetEndPoint();
                            const basegfx::B2DPoint aStart(rStartPoint.X(), rStartPoint.Y());
                            const basegfx::B2DPoint aEnd(rEndPoint.X(), rEndPoint.Y());

                            if(aLinePolygon.count())
                            {
                                if(pA->GetLineInfo() == aLineInfo
                                    && aStart == aLinePolygon.getB2DPoint(aLinePolygon.count() - 1))
                                {
                                    aLinePolygon.append(aEnd);
                                }
                                else
                                {
									aLineInfo.SetLineJoin(basegfx::B2DLINEJOIN_NONE); // It were lines; force to NONE
                                    createLinePrimitive(aLinePolygon, aLineInfo, rTargetHolders.Current(), rPropertyHolders.Current());
                                    aLinePolygon.clear();
	                                aLineInfo = pA->GetLineInfo();
									aLinePolygon.append(aStart);
									aLinePolygon.append(aEnd);
                                }
                            }
                            else
                            {
                                aLineInfo = pA->GetLineInfo();
                                aLinePolygon.append(aStart);
                                aLinePolygon.append(aEnd);
                            }

							nAction++; if(nAction < nCount) pAction = rMetaFile.GetAction(nAction);
                        }

                        nAction--;

                        if(aLinePolygon.count())
                        {
							aLineInfo.SetLineJoin(basegfx::B2DLINEJOIN_NONE); // It were lines; force to NONE
                            createLinePrimitive(aLinePolygon, aLineInfo, rTargetHolders.Current(), rPropertyHolders.Current());
                        }
                    }

                    break;
                }
                case META_RECT_ACTION :
                {
					/** CHECKED, WORKS WELL */
					if(rPropertyHolders.Current().getLineOrFillActive())
					{
                        const MetaRectAction* pA = (const MetaRectAction*)pAction;
						const Rectangle& rRectangle = pA->GetRect();

						if(!rRectangle.IsEmpty())
						{
							const basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom());

							if(!aRange.isEmpty())
							{
								const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
								createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
							}
						}
					}

                    break;
                }
                case META_ROUNDRECT_ACTION :
                {
					/** CHECKED, WORKS WELL */
					/**	The original OutputDevice::DrawRect paints nothing when nHor or nVer is zero; but just
						because the tools::Polygon operator creating the rounding does produce nonsense. I assume
						this an error and create an unrounded rectangle in that case (implicit in
						createPolygonFromRect)
					 */
					if(rPropertyHolders.Current().getLineOrFillActive())
					{
                        const MetaRoundRectAction* pA = (const MetaRoundRectAction*)pAction;
						const Rectangle& rRectangle = pA->GetRect();

						if(!rRectangle.IsEmpty())
						{
							const basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom());

							if(!aRange.isEmpty())
							{
								const sal_uInt32 nHor(pA->GetHorzRound());
								const sal_uInt32 nVer(pA->GetVertRound());
								basegfx::B2DPolygon aOutline;

								if(nHor || nVer)
								{
									double fRadiusX((nHor * 2.0) / (aRange.getWidth() > 0.0 ? aRange.getWidth() : 1.0));
									double fRadiusY((nVer * 2.0) / (aRange.getHeight() > 0.0 ? aRange.getHeight() : 1.0));
									fRadiusX = std::max(0.0, std::min(1.0, fRadiusX));
									fRadiusY = std::max(0.0, std::min(1.0, fRadiusY));

									aOutline = basegfx::tools::createPolygonFromRect(aRange, fRadiusX, fRadiusY);
								}
								else
								{
									aOutline = basegfx::tools::createPolygonFromRect(aRange);
								}

								createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
							}
						}
					}

                    break;
                }
                case META_ELLIPSE_ACTION :
                {
					/** CHECKED, WORKS WELL */
					if(rPropertyHolders.Current().getLineOrFillActive())
					{
                        const MetaEllipseAction* pA = (const MetaEllipseAction*)pAction;
						const Rectangle& rRectangle = pA->GetRect();

						if(!rRectangle.IsEmpty())
						{
							const basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom());

							if(!aRange.isEmpty())
							{
								const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromEllipse(
									aRange.getCenter(), aRange.getWidth() * 0.5, aRange.getHeight() * 0.5));

								createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
							}
						}
					}

                    break;
                }
                case META_ARC_ACTION :
                {
					/** CHECKED, WORKS WELL */
					if(rPropertyHolders.Current().getLineColorActive())
					{
                        const MetaArcAction* pA = (const MetaArcAction*)pAction;
                        const Polygon aToolsPoly(pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC);
						const basegfx::B2DPolygon aOutline(aToolsPoly.getB2DPolygon());

						createHairlinePrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_PIE_ACTION :
                {
					/** CHECKED, WORKS WELL */
					if(rPropertyHolders.Current().getLineOrFillActive())
					{
                        const MetaPieAction* pA = (const MetaPieAction*)pAction;
                        const Polygon aToolsPoly(pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE);
						const basegfx::B2DPolygon aOutline(aToolsPoly.getB2DPolygon());

						createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_CHORD_ACTION :
                {
					/** CHECKED, WORKS WELL */
					if(rPropertyHolders.Current().getLineOrFillActive())
					{
                        const MetaChordAction* pA = (const MetaChordAction*)pAction;
                        const Polygon aToolsPoly(pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD);
						const basegfx::B2DPolygon aOutline(aToolsPoly.getB2DPolygon());

						createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_POLYLINE_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    if(rPropertyHolders.Current().getLineColorActive())
                    {
                        const MetaPolyLineAction* pA = (const MetaPolyLineAction*)pAction;
                        createLinePrimitive(pA->GetPolygon().getB2DPolygon(), pA->GetLineInfo(), rTargetHolders.Current(), rPropertyHolders.Current());
                    }

                    break;
                }
                case META_POLYGON_ACTION :
                {
					/** CHECKED, WORKS WELL */
					if(rPropertyHolders.Current().getLineOrFillActive())
					{
                        const MetaPolygonAction* pA = (const MetaPolygonAction*)pAction;
						basegfx::B2DPolygon aOutline(pA->GetPolygon().getB2DPolygon());

						// the metafile play interprets the polygons from MetaPolygonAction
						// always as closed and always paints an edge from last to first point,
						// so force to closed here to emulate that
						if(aOutline.count() > 1 && !aOutline.isClosed())
						{
							aOutline.setClosed(true);
						}

						createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_POLYPOLYGON_ACTION :
                {
					/** CHECKED, WORKS WELL */
					if(rPropertyHolders.Current().getLineOrFillActive())
					{
                        const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*)pAction;
						basegfx::B2DPolyPolygon aPolyPolygonOutline(pA->GetPolyPolygon().getB2DPolyPolygon());

						// the metafile play interprets the single polygons from MetaPolyPolygonAction
						// always as closed and always paints an edge from last to first point,
						// so force to closed here to emulate that
						for(sal_uInt32 b(0); b < aPolyPolygonOutline.count(); b++)
						{
							basegfx::B2DPolygon aPolygonOutline(aPolyPolygonOutline.getB2DPolygon(b));

							if(aPolygonOutline.count() > 1 && !aPolygonOutline.isClosed())
							{
								aPolygonOutline.setClosed(true);
								aPolyPolygonOutline.setB2DPolygon(b, aPolygonOutline);
							}
						}

						createHairlineAndFillPrimitive(aPolyPolygonOutline, rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_TEXT_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaTextAction* pA = (const MetaTextAction*)pAction;
					sal_uInt32 nTextLength(pA->GetLen());
					const sal_uInt32 nTextIndex(pA->GetIndex());
					const sal_uInt32 nStringLength(pA->GetText().Len());

					if(nTextLength + nTextIndex > nStringLength)
					{
						nTextLength = nStringLength - nTextIndex;
					}

					if(nTextLength && rPropertyHolders.Current().getTextColorActive())
					{
						const std::vector< double > aDXArray;
						proccessMetaTextAction(
							pA->GetPoint(),
							pA->GetText(),
							nTextIndex,
							nTextLength,
							aDXArray,
							rTargetHolders.Current(),
							rPropertyHolders.Current());
					}

                    break;
                }
                case META_TEXTARRAY_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaTextArrayAction* pA = (const MetaTextArrayAction*)pAction;
					sal_uInt32 nTextLength(pA->GetLen());
					const sal_uInt32 nTextIndex(pA->GetIndex());
					const sal_uInt32 nStringLength(pA->GetText().Len());

					if(nTextLength + nTextIndex > nStringLength)
					{
						nTextLength = nTextIndex > nStringLength ? 0 : nStringLength - nTextIndex;
					}

					if(nTextLength && rPropertyHolders.Current().getTextColorActive())
					{
						// preapare DXArray (if used)
						std::vector< double > aDXArray;
						sal_Int32* pDXArray = pA->GetDXArray();

						if(pDXArray)
						{
							aDXArray.reserve(nTextLength);

							for(sal_uInt32 a(0); a < nTextLength; a++)
							{
								aDXArray.push_back((double)(*(pDXArray + a)));
							}
						}

						proccessMetaTextAction(
							pA->GetPoint(),
							pA->GetText(),
							nTextIndex,
							nTextLength,
							aDXArray,
							rTargetHolders.Current(),
							rPropertyHolders.Current());
					}

					break;
                }
                case META_STRETCHTEXT_ACTION :
                {
                    // #i108440# StarMath uses MetaStretchTextAction, thus support is needed.
                    // It looks as if it pretty never really uses a width different from
                    // the default text-layout width, but it's not possible to be sure.
                    // Implemented getting the DXArray and checking for scale at all. If
                    // scale is more than 3.5% different, scale the DXArray before usage.
                    // New status:

                    /** CHECKED, WORKS WELL */
                    const MetaStretchTextAction* pA = (const MetaStretchTextAction*)pAction;
					sal_uInt32 nTextLength(pA->GetLen());
					const sal_uInt32 nTextIndex(pA->GetIndex());
					const sal_uInt32 nStringLength(pA->GetText().Len());

					if(nTextLength + nTextIndex > nStringLength)
					{
						nTextLength = nStringLength - nTextIndex;
					}

					if(nTextLength && rPropertyHolders.Current().getTextColorActive())
					{
						drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
						aTextLayouterDevice.setFont(rPropertyHolders.Current().getFont());

						::std::vector< double > aTextArray(
							aTextLayouterDevice.getTextArray(
								pA->GetText(),
								nTextIndex,
								nTextLength));

                        if(!aTextArray.empty())
                        {
    						const double fTextLength(aTextArray.back());

                            if(0.0 != fTextLength && pA->GetWidth())
                            {
                                const double fRelative(pA->GetWidth() / fTextLength);

                                if(fabs(fRelative - 1.0) >= 0.035)
                                {
                                    // when derivation is more than 3,5% from default text size,
                                    // scale the DXArray
                                    for(sal_uInt32 a(0); a < aTextArray.size(); a++)
                                    {
                                        aTextArray[a] *= fRelative;
                                    }
                                }
                            }
                        }

						proccessMetaTextAction(
							pA->GetPoint(),
							pA->GetText(),
							nTextIndex,
							nTextLength,
							aTextArray,
							rTargetHolders.Current(),
							rPropertyHolders.Current());
					}

					break;
                }
                case META_TEXTRECT_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    // OSL_ENSURE(false, "META_TEXTRECT_ACTION requested (!)");
                    const MetaTextRectAction* pA = (const MetaTextRectAction*)pAction;
					const Rectangle& rRectangle = pA->GetRect();
					const sal_uInt32 nStringLength(pA->GetText().Len());

					if(!rRectangle.IsEmpty() && 0 != nStringLength)
					{
						// The problem with this action is that it describes unlayouted text
						// and the layout capabilities are in EditEngine/Outliner in SVX. The
						// same problem is true for VCL which internally has implementations
						// to layout text in this case. There exists even a call
						// OutputDevice::AddTextRectActions(...) to create the needed actions
						// as 'sub-content' of a Metafile. Unfortunately i do not have an
						// OutputDevice here since this interpreter tries to work without
						// VCL AFAP.
						// Since AddTextRectActions is the only way as long as we do not have
						// a simple text layouter available, i will try to add it to the
						// TextLayouterDevice isloation.
						drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
						aTextLayouterDevice.setFont(rPropertyHolders.Current().getFont());
						GDIMetaFile aGDIMetaFile;

						aTextLayouterDevice.addTextRectActions(
							rRectangle, pA->GetText(), pA->GetStyle(), aGDIMetaFile);

						if(aGDIMetaFile.GetActionCount())
						{
							// cerate sub-content
							drawinglayer::primitive2d::Primitive2DSequence xSubContent;
							{
                                rTargetHolders.Push();
								// #i# for sub-Mteafile contents, do start with new, default render state
								rPropertyHolders.PushDefault();
								interpretMetafile(aGDIMetaFile, rTargetHolders, rPropertyHolders, rViewInformation);
								xSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current());
								rPropertyHolders.Pop();
                                rTargetHolders.Pop();
							}

							if(xSubContent.hasElements())
							{
								// add with transformation
								rTargetHolders.Current().append(
									new drawinglayer::primitive2d::TransformPrimitive2D(
										rPropertyHolders.Current().getTransformation(),
										xSubContent));
							}
						}
					}

					break;
                }
                case META_BMP_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaBmpAction* pA = (const MetaBmpAction*)pAction;
					const BitmapEx aBitmapEx(pA->GetBitmap());

					createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), rTargetHolders.Current(), rPropertyHolders.Current());

                    break;
                }
                case META_BMPSCALE_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*)pAction;
					const Bitmap aBitmapEx(pA->GetBitmap());

					createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), pA->GetSize(), rTargetHolders.Current(), rPropertyHolders.Current());

                    break;
                }
                case META_BMPSCALEPART_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*)pAction;
					const Bitmap& rBitmap = pA->GetBitmap();

					if(!rBitmap.IsEmpty())
					{
						Bitmap aCroppedBitmap(rBitmap);
						const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize());

						if(!aCropRectangle.IsEmpty())
						{
							aCroppedBitmap.Crop(aCropRectangle);
						}

						const BitmapEx aCroppedBitmapEx(aCroppedBitmap);
						createBitmapExPrimitive(aCroppedBitmapEx, pA->GetDestPoint(), pA->GetDestSize(), rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_BMPEX_ACTION :
                {
					/** CHECKED, WORKS WELL: Simply same as META_BMP_ACTION */
                    const MetaBmpExAction* pA = (const MetaBmpExAction*)pAction;
					const BitmapEx& rBitmapEx = pA->GetBitmapEx();

					createBitmapExPrimitive(rBitmapEx, pA->GetPoint(), rTargetHolders.Current(), rPropertyHolders.Current());

                    break;
                }
                case META_BMPEXSCALE_ACTION :
                {
					/** CHECKED, WORKS WELL: Simply same as META_BMPSCALE_ACTION */
                    const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*)pAction;
					const BitmapEx& rBitmapEx = pA->GetBitmapEx();

					createBitmapExPrimitive(rBitmapEx, pA->GetPoint(), pA->GetSize(), rTargetHolders.Current(), rPropertyHolders.Current());

                    break;
                }
                case META_BMPEXSCALEPART_ACTION :
                {
					/** CHECKED, WORKS WELL: Simply same as META_BMPSCALEPART_ACTION */
                    const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*)pAction;
					const BitmapEx& rBitmapEx = pA->GetBitmapEx();

					if(!rBitmapEx.IsEmpty())
					{
						BitmapEx aCroppedBitmapEx(rBitmapEx);
						const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize());

						if(!aCropRectangle.IsEmpty())
						{
							aCroppedBitmapEx.Crop(aCropRectangle);
						}

						createBitmapExPrimitive(aCroppedBitmapEx, pA->GetDestPoint(), pA->GetDestSize(), rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_MASK_ACTION :
                {
					/** CHECKED, WORKS WELL: Simply same as META_BMP_ACTION */
                    const MetaMaskAction* pA = (const MetaMaskAction*)pAction;
					const BitmapEx aBitmapEx(createMaskBmpEx(pA->GetBitmap(), pA->GetColor()));

					createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), rTargetHolders.Current(), rPropertyHolders.Current());

                    break;
                }
                case META_MASKSCALE_ACTION :
                {
					/** CHECKED, WORKS WELL: Simply same as META_BMPSCALE_ACTION */
                    const MetaMaskScaleAction* pA = (const MetaMaskScaleAction*)pAction;
					const BitmapEx aBitmapEx(createMaskBmpEx(pA->GetBitmap(), pA->GetColor()));

					createBitmapExPrimitive(aBitmapEx, pA->GetPoint(), pA->GetSize(), rTargetHolders.Current(), rPropertyHolders.Current());

                    break;
                }
                case META_MASKSCALEPART_ACTION :
                {
					/** CHECKED, WORKS WELL: Simply same as META_BMPSCALEPART_ACTION */
                    const MetaMaskScalePartAction* pA = (const MetaMaskScalePartAction*)pAction;
					const Bitmap& rBitmap = pA->GetBitmap();

					if(!rBitmap.IsEmpty())
					{
						Bitmap aCroppedBitmap(rBitmap);
						const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize());

						if(!aCropRectangle.IsEmpty())
						{
							aCroppedBitmap.Crop(aCropRectangle);
						}

						const BitmapEx aCroppedBitmapEx(createMaskBmpEx(aCroppedBitmap, pA->GetColor()));
						createBitmapExPrimitive(aCroppedBitmapEx, pA->GetDestPoint(), pA->GetDestSize(), rTargetHolders.Current(), rPropertyHolders.Current());
					}

                    break;
                }
                case META_GRADIENT_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaGradientAction* pA = (const MetaGradientAction*)pAction;
					const Rectangle& rRectangle = pA->GetRect();

					if(!rRectangle.IsEmpty())
					{
						basegfx::B2DRange aRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom());

						if(!aRange.isEmpty())
						{
							const Gradient& rGradient = pA->GetGradient();
							const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient));
							basegfx::B2DPolyPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));

							if(aAttribute.getStartColor() == aAttribute.getEndColor())
							{
								// not really a gradient. Create filled rectangle
								createFillPrimitive(
                                    aOutline,
                                    rTargetHolders.Current(),
                                    rPropertyHolders.Current());
							}
							else
							{
								// really a gradient
								aRange.transform(rPropertyHolders.Current().getTransformation());
                                drawinglayer::primitive2d::Primitive2DSequence xGradient(1);

                                if(rPropertyHolders.Current().isRasterOpInvert())
                                {
                                    // use a special version of FillGradientPrimitive2D which creates
                                    // non-overlapping geometry on decomposition to makethe old XOR
                                    // paint 'trick' work.
                                    xGradient[0] = drawinglayer::primitive2d::Primitive2DReference(
									    new drawinglayer::primitive2d::NonOverlappingFillGradientPrimitive2D(
										    aRange,
										    aAttribute));
                                }
                                else
                                {
                                    xGradient[0] = drawinglayer::primitive2d::Primitive2DReference(
									    new drawinglayer::primitive2d::FillGradientPrimitive2D(
										    aRange,
										    aAttribute));
                                }

                                // #i112300# clip against polygon representing the rectangle from
                                // the action. This is implicitely done using a temp Clipping in VCL
                                // when a MetaGradientAction is executed
                    			aOutline.transform(rPropertyHolders.Current().getTransformation());
                                rTargetHolders.Current().append(
								    new drawinglayer::primitive2d::MaskPrimitive2D(
									    aOutline,
									    xGradient));
							}
						}
					}

                    break;
                }
                case META_HATCH_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaHatchAction* pA = (const MetaHatchAction*)pAction;
					basegfx::B2DPolyPolygon aOutline(pA->GetPolyPolygon().getB2DPolyPolygon());

					if(aOutline.count())
					{
                    	const Hatch& rHatch = pA->GetHatch();
						const drawinglayer::attribute::FillHatchAttribute aAttribute(createFillHatchAttribute(rHatch));

                        aOutline.transform(rPropertyHolders.Current().getTransformation());

                        const basegfx::B2DRange aObjectRange(aOutline.getB2DRange());
						const drawinglayer::primitive2d::Primitive2DReference aFillHatch(
							new drawinglayer::primitive2d::FillHatchPrimitive2D(
								aObjectRange,
                                basegfx::BColor(),
								aAttribute));

                        rTargetHolders.Current().append(
							new drawinglayer::primitive2d::MaskPrimitive2D(
								aOutline,
								drawinglayer::primitive2d::Primitive2DSequence(&aFillHatch, 1)));
                    }

                    break;
                }
                case META_WALLPAPER_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaWallpaperAction* pA = (const MetaWallpaperAction*)pAction;
                	Rectangle aWallpaperRectangle(pA->GetRect());

                    if(!aWallpaperRectangle.IsEmpty())
                    {
                    	const Wallpaper& rWallpaper = pA->GetWallpaper();
                       	const WallpaperStyle eWallpaperStyle(rWallpaper.GetStyle());
		                basegfx::B2DRange aWallpaperRange(
                            aWallpaperRectangle.Left(), aWallpaperRectangle.Top(),
                            aWallpaperRectangle.Right(), aWallpaperRectangle.Bottom());

                        if(WALLPAPER_NULL != eWallpaperStyle)
                        {
	                        if(rWallpaper.IsBitmap())
                            {
                                // create bitmap background. Caution: This
                                // also will create gradient/color background(s)
                                // when the bitmap is transparent or not tiled
				                CreateAndAppendBitmapWallpaper(
					                aWallpaperRange,
                                    rWallpaper,
									rTargetHolders.Current(),
                                    rPropertyHolders.Current());
                            }
	                        else if(rWallpaper.IsGradient())
                            {
                                // create gradient background
                                rTargetHolders.Current().append(
							        CreateGradientWallpaper(
								        aWallpaperRange,
                                        rWallpaper.GetGradient(),
                                        rPropertyHolders.Current()));
                            }
	                        else if(!rWallpaper.GetColor().GetTransparency())
                            {
                                // create color background
                                rTargetHolders.Current().append(
							        CreateColorWallpaper(
								        aWallpaperRange,
                                        rWallpaper.GetColor().getBColor(),
                                        rPropertyHolders.Current()));
                            }
                        }
                    }

                    break;
                }
                case META_CLIPREGION_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaClipRegionAction* pA = (const MetaClipRegionAction*)pAction;

                    if(pA->IsClipping())
                    {
                        // new clipping. Get PolyPolygon and transform with current transformation
                        basegfx::B2DPolyPolygon aNewClipPolyPolygon(getB2DPolyPolygonFromRegion(pA->GetRegion()));

                        aNewClipPolyPolygon.transform(rPropertyHolders.Current().getTransformation());
                        HandleNewClipRegion(aNewClipPolyPolygon, rTargetHolders, rPropertyHolders);
                    }
                    else
                    {
                        // end clipping
                        const basegfx::B2DPolyPolygon aEmptyPolyPolygon;

                        HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
                    }

                    break;
                }
                case META_ISECTRECTCLIPREGION_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*)pAction;
					const Rectangle& rRectangle = pA->GetRect();

					if(rRectangle.IsEmpty())
                    {
                        // intersect with empty rectangle will always give empty
                        // ClipPolyPolygon; start new clipping with empty PolyPolygon
                        const basegfx::B2DPolyPolygon aEmptyPolyPolygon;

                        HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
                    }
                    else
					{
                        // create transformed ClipRange
                        basegfx::B2DRange aClipRange(
                            rRectangle.Left(), rRectangle.Top(),
                            rRectangle.Right(), rRectangle.Bottom());

                        aClipRange.transform(rPropertyHolders.Current().getTransformation());

                        if(rPropertyHolders.Current().getClipPolyPolygonActive())
                        {
                            if(0 == rPropertyHolders.Current().getClipPolyPolygon().count())
                            {
                                // nothing to do, empty active clipPolyPolygon will stay
                                // empty when intersecting
                            }
                            else
                            {
                                // AND existing region and new ClipRange
                                const basegfx::B2DPolyPolygon aOriginalPolyPolygon(
                                    rPropertyHolders.Current().getClipPolyPolygon());
                                basegfx::B2DPolyPolygon aClippedPolyPolygon;

                                if(aOriginalPolyPolygon.count())
                                {
                                    aClippedPolyPolygon = basegfx::tools::clipPolyPolygonOnRange(
                                        aOriginalPolyPolygon,
                                        aClipRange,
                                        true,
                                        false);
                                }

                                if(aClippedPolyPolygon != aOriginalPolyPolygon)
                                {
                                    // start new clipping with intersected region
                                    HandleNewClipRegion(
                                        aClippedPolyPolygon,
                                        rTargetHolders,
                                        rPropertyHolders);
                                }
                            }
                        }
                        else
                        {
                            // start new clipping with ClipRange
                            const basegfx::B2DPolyPolygon aNewClipPolyPolygon(
                                basegfx::tools::createPolygonFromRect(aClipRange));

                            HandleNewClipRegion(aNewClipPolyPolygon, rTargetHolders, rPropertyHolders);
                        }
                    }

                    break;
                }
                case META_ISECTREGIONCLIPREGION_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaISectRegionClipRegionAction* pA = (const MetaISectRegionClipRegionAction*)pAction;
                	const Region& rNewRegion = pA->GetRegion();

					if(rNewRegion.IsEmpty())
                    {
                        // intersect with empty region will always give empty
                        // region; start new clipping with empty PolyPolygon
                        const basegfx::B2DPolyPolygon aEmptyPolyPolygon;

                        HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
                    }
                    else
					{
                        // get new ClipPolyPolygon, transform it with current transformation
                        basegfx::B2DPolyPolygon aNewClipPolyPolygon(getB2DPolyPolygonFromRegion(rNewRegion));
                        aNewClipPolyPolygon.transform(rPropertyHolders.Current().getTransformation());

                        if(rPropertyHolders.Current().getClipPolyPolygonActive())
                        {
                            if(0 == rPropertyHolders.Current().getClipPolyPolygon().count())
                            {
                                // nothing to do, empty active clipPolyPolygon will stay empty
                                // when intersecting with any region
                            }
                            else
                            {
                                // AND existing and new region
                                const basegfx::B2DPolyPolygon aOriginalPolyPolygon(
                                    rPropertyHolders.Current().getClipPolyPolygon());
                                basegfx::B2DPolyPolygon aClippedPolyPolygon;

                                if(aOriginalPolyPolygon.count())
                                {
                                    aClippedPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
                                        aOriginalPolyPolygon, aNewClipPolyPolygon, true, false);
                                }

                                if(aClippedPolyPolygon != aOriginalPolyPolygon)
                                {
                                    // start new clipping with intersected ClipPolyPolygon
                                    HandleNewClipRegion(aClippedPolyPolygon, rTargetHolders, rPropertyHolders);
                                }
                            }
                        }
                        else
                        {
                            // start new clipping with new ClipPolyPolygon
                            HandleNewClipRegion(aNewClipPolyPolygon, rTargetHolders, rPropertyHolders);
                        }
                    }

                    break;
                }
                case META_MOVECLIPREGION_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*)pAction;

                    if(rPropertyHolders.Current().getClipPolyPolygonActive())
                    {
                        if(0 == rPropertyHolders.Current().getClipPolyPolygon().count())
                        {
                            // nothing to do
                        }
                        else
                        {
                            const sal_Int32 nHor(pA->GetHorzMove());
                            const sal_Int32 nVer(pA->GetVertMove());

                            if(0 != nHor || 0 != nVer)
                            {
                                // prepare translation, add current transformation
                                basegfx::B2DVector aVector(pA->GetHorzMove(), pA->GetVertMove());
                                aVector *= rPropertyHolders.Current().getTransformation();
                                basegfx::B2DHomMatrix aTransform(
                                    basegfx::tools::createTranslateB2DHomMatrix(aVector));

                                // transform existing region
                                basegfx::B2DPolyPolygon aClipPolyPolygon(
                                    rPropertyHolders.Current().getClipPolyPolygon());

                                aClipPolyPolygon.transform(aTransform);
                                HandleNewClipRegion(aClipPolyPolygon, rTargetHolders, rPropertyHolders);
                            }
                        }
                    }

                    break;
                }
                case META_LINECOLOR_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaLineColorAction* pA = (const MetaLineColorAction*)pAction;
                    const bool bActive(pA->IsSetting());

                    rPropertyHolders.Current().setLineColorActive(bActive);
                    if(bActive)
                        rPropertyHolders.Current().setLineColor(pA->GetColor().getBColor());

                    break;
                }
                case META_FILLCOLOR_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaFillColorAction* pA = (const MetaFillColorAction*)pAction;
                    const bool bActive(pA->IsSetting());

                    rPropertyHolders.Current().setFillColorActive(bActive);
                    if(bActive)
                        rPropertyHolders.Current().setFillColor(pA->GetColor().getBColor());

                    break;
                }
                case META_TEXTCOLOR_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaTextColorAction* pA = (const MetaTextColorAction*)pAction;
                    const bool bActivate(COL_TRANSPARENT != pA->GetColor().GetColor());

                    rPropertyHolders.Current().setTextColorActive(bActivate);
                    rPropertyHolders.Current().setTextColor(pA->GetColor().getBColor());

                    break;
                }
                case META_TEXTFILLCOLOR_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*)pAction;
                    const bool bWithColorArgument(pA->IsSetting());

                    if(bWithColorArgument)
                    {
                        // emulate OutputDevice::SetTextFillColor(...) WITH argument
                    	const Color& rFontFillColor = pA->GetColor();
                        rPropertyHolders.Current().setTextFillColor(rFontFillColor.getBColor());
                        rPropertyHolders.Current().setTextFillColorActive(COL_TRANSPARENT != rFontFillColor.GetColor());
                    }
                    else
                    {
                        // emulate SetFillColor() <- NO argument (!)
                        rPropertyHolders.Current().setTextFillColorActive(false);
                    }

                    break;
                }
                case META_TEXTALIGN_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaTextAlignAction* pA = (const MetaTextAlignAction*)pAction;
            	    const TextAlign aNewTextAlign = pA->GetTextAlign();

                    // TextAlign is applied to the current font (as in
                    // OutputDevice::SetTextAlign which would be used when
                    // playing the Metafile)
                    if(rPropertyHolders.Current().getFont().GetAlign() != aNewTextAlign)
                    {
                        Font aNewFont(rPropertyHolders.Current().getFont());
                        aNewFont.SetAlign(aNewTextAlign);
                        rPropertyHolders.Current().setFont(aNewFont);
                    }

                    break;
                }
                case META_MAPMODE_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    // the most necessary MapMode to be interpreted is MAP_RELATIVE,
                    // but also the others may occur. Even not yet supported ones
                    // may need to be added here later
                    const MetaMapModeAction* pA = (const MetaMapModeAction*)pAction;
					const MapMode& rMapMode = pA->GetMapMode();
					basegfx::B2DHomMatrix aMapping;

					if(MAP_RELATIVE == rMapMode.GetMapUnit())
					{
						aMapping = getTransformFromMapMode(rMapMode);
					}
					else
					{
						switch(rMapMode.GetMapUnit())
						{
							case MAP_100TH_MM :
							{
								if(MAP_TWIP == rPropertyHolders.Current().getMapUnit())
								{
									// MAP_TWIP -> MAP_100TH_MM
									const double fTwipTo100thMm(127.0 / 72.0);
									aMapping.scale(fTwipTo100thMm, fTwipTo100thMm);
								}
								break;
							}
							case MAP_TWIP :
							{
								if(MAP_100TH_MM == rPropertyHolders.Current().getMapUnit())
								{
									// MAP_100TH_MM -> MAP_TWIP
									const double f100thMmToTwip(72.0 / 127.0);
									aMapping.scale(f100thMmToTwip, f100thMmToTwip);
								}
								break;
							}
							default :
							{
								OSL_ENSURE(false, "interpretMetafile: META_MAPMODE_ACTION with unsupported MapUnit (!)");
								break;
							}
						}

						aMapping = getTransformFromMapMode(rMapMode) * aMapping;
						rPropertyHolders.Current().setMapUnit(rMapMode.GetMapUnit());
					}

					if(!aMapping.isIdentity())
					{
						aMapping = aMapping * rPropertyHolders.Current().getTransformation();
						rPropertyHolders.Current().setTransformation(aMapping);
					}

					break;
                }
                case META_FONT_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaFontAction* pA = (const MetaFontAction*)pAction;
                    rPropertyHolders.Current().setFont(pA->GetFont());
                    Size aFontSize(pA->GetFont().GetSize());

                    if(0 == aFontSize.Height())
                    {
                        // this should not happen but i got Metafiles where this was the
                        // case. A height needs to be guessed (similar to OutputDevice::ImplNewFont())
                        Font aCorrectedFont(pA->GetFont());

                        // guess 16 pixel (as in VCL)
                        aFontSize = Size(0, 16);

                        // convert to target MapUnit if not pixels
					    aFontSize = Application::GetDefaultDevice()->LogicToLogic(
							aFontSize, MAP_PIXEL, rPropertyHolders.Current().getMapUnit());

                        aCorrectedFont.SetSize(aFontSize);
                        rPropertyHolders.Current().setFont(aCorrectedFont);
                    }

                    // older Metafiles have no META_TEXTCOLOR_ACTION which defines
                    // the FontColor now, so use the Font's color when not transparent
                    const Color& rFontColor = pA->GetFont().GetColor();
                    const bool bActivate(COL_TRANSPARENT != rFontColor.GetColor());

                    if(bActivate)
                    {
                        rPropertyHolders.Current().setTextColor(rFontColor.getBColor());
                    }

                    // caution: do NOT decativate here on transparet, see
                    // OutputDevice::SetFont(..) for more info
                    // rPropertyHolders.Current().setTextColorActive(bActivate);

                    // for fill color emulate a MetaTextFillColorAction with !transparent as bool,
                    // see OutputDevice::SetFont(..) the if(mpMetaFile) case
                    if(bActivate)
                    {
                    	const Color& rFontFillColor = pA->GetFont().GetFillColor();
                        rPropertyHolders.Current().setTextFillColor(rFontFillColor.getBColor());
                        rPropertyHolders.Current().setTextFillColorActive(COL_TRANSPARENT != rFontFillColor.GetColor());
                    }
                    else
                    {
                        rPropertyHolders.Current().setTextFillColorActive(false);
                    }

                    break;
                }
                case META_PUSH_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaPushAction* pA = (const MetaPushAction*)pAction;
                    rPropertyHolders.Push(pA->GetFlags());

                    break;
                }
                case META_POP_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const bool bRegionMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_CLIPREGION);
                    const bool bRasterOpMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_RASTEROP);

                    if(bRegionMayChange && rPropertyHolders.Current().getClipPolyPolygonActive())
                    {
                        // end evtl. clipping
                        const basegfx::B2DPolyPolygon aEmptyPolyPolygon;

                        HandleNewClipRegion(aEmptyPolyPolygon, rTargetHolders, rPropertyHolders);
                    }

                    if(bRasterOpMayChange && rPropertyHolders.Current().isRasterOpActive())
                    {
                        // end evtl. RasterOp
                        HandleNewRasterOp(ROP_OVERPAINT, rTargetHolders, rPropertyHolders);
                    }

                    rPropertyHolders.Pop();

                    if(bRasterOpMayChange && rPropertyHolders.Current().isRasterOpActive())
                    {
                        // start evtl. RasterOp
                        HandleNewRasterOp(rPropertyHolders.Current().getRasterOp(), rTargetHolders, rPropertyHolders);
                    }

                    if(bRegionMayChange && rPropertyHolders.Current().getClipPolyPolygonActive())
                    {
                        // start evtl. clipping
                        HandleNewClipRegion(
                            rPropertyHolders.Current().getClipPolyPolygon(), rTargetHolders, rPropertyHolders);
                    }

                    break;
                }
                case META_RASTEROP_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaRasterOpAction* pA = (const MetaRasterOpAction*)pAction;
                	const RasterOp aRasterOp = pA->GetRasterOp();

                    HandleNewRasterOp(aRasterOp, rTargetHolders, rPropertyHolders);

                    break;
                }
                case META_TRANSPARENT_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaTransparentAction* pA = (const MetaTransparentAction*)pAction;
					const basegfx::B2DPolyPolygon aOutline(pA->GetPolyPolygon().getB2DPolyPolygon());

					if(aOutline.count())
					{
						const sal_uInt16 nTransparence(pA->GetTransparence());

						if(0 == nTransparence)
						{
							// not transparent
							createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
						}
						else if(nTransparence >= 100)
						{
							// fully or more than transparent
						}
						else
						{
							// transparent. Create new target
                            rTargetHolders.Push();

							// create primitives there and get them
							createHairlineAndFillPrimitive(aOutline, rTargetHolders.Current(), rPropertyHolders.Current());
							const drawinglayer::primitive2d::Primitive2DSequence aSubContent(
                                rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current()));

							// back to old target
                            rTargetHolders.Pop();

							if(aSubContent.hasElements())
							{
								rTargetHolders.Current().append(
									new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
										aSubContent,
										nTransparence * 0.01));
							}
						}
					}

                    break;
                }
                case META_EPS_ACTION :
                {
					/** CHECKED, WORKS WELL */
					// To support this action, i have added a EpsPrimitive2D which will
					// by default decompose to the Metafile replacement data. To support
					// this EPS on screen, the renderer visualizing this has to support
					// that primitive and visualize the Eps file (e.g. printing)
                    const MetaEPSAction* pA = (const MetaEPSAction*)pAction;
					const Rectangle aRectangle(pA->GetPoint(), pA->GetSize());

					if(!aRectangle.IsEmpty())
                    {
						// create object transform
						basegfx::B2DHomMatrix aObjectTransform;

						aObjectTransform.set(0, 0, aRectangle.GetWidth());
						aObjectTransform.set(1, 1, aRectangle.GetHeight());
						aObjectTransform.set(0, 2, aRectangle.Left());
						aObjectTransform.set(1, 2, aRectangle.Top());

						// add current transformation
						aObjectTransform = rPropertyHolders.Current().getTransformation() * aObjectTransform;

						// embed using EpsPrimitive
						rTargetHolders.Current().append(
							new drawinglayer::primitive2d::EpsPrimitive2D(
								aObjectTransform,
								pA->GetLink(),
								pA->GetSubstitute()));
					}

					break;
                }
                case META_REFPOINT_ACTION :
                {
					/** SIMPLE, DONE */
                    // only used for hatch and line pattern offsets, pretty much no longer
                    // supported today
                    // const MetaRefPointAction* pA = (const MetaRefPointAction*)pAction;
                    break;
                }
                case META_TEXTLINECOLOR_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaTextLineColorAction* pA = (const MetaTextLineColorAction*)pAction;
                    const bool bActive(pA->IsSetting());

                    rPropertyHolders.Current().setTextLineColorActive(bActive);
                    if(bActive)
                        rPropertyHolders.Current().setTextLineColor(pA->GetColor().getBColor());

                    break;
                }
                case META_TEXTLINE_ACTION :
                {
					/** CHECKED, WORKS WELL */
					// actually creates overline, underline and strikeouts, so
					// these should be isolated from TextDecoratedPortionPrimitive2D
					// to own primitives. Done, available now.
					//
					// This Metaaction seems not to be used (was not used in any
					// checked files). It's used in combination with the current
					// Font.
                    const MetaTextLineAction* pA = (const MetaTextLineAction*)pAction;

					proccessMetaTextLineAction(
						*pA,
						rTargetHolders.Current(),
						rPropertyHolders.Current());

                    break;
                }
                case META_FLOATTRANSPARENT_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*)pAction;
					const basegfx::B2DRange aTargetRange(
                        pA->GetPoint().X(), 
                        pA->GetPoint().Y(), 
                        pA->GetPoint().X() + pA->GetSize().Width(), 
                        pA->GetPoint().Y() + pA->GetSize().Height());

					if(!aTargetRange.isEmpty())
					{
						const GDIMetaFile& rContent = pA->GetGDIMetaFile();

						if(rContent.GetActionCount())
						{
							// create the sub-content with no embedding specific to the
							// sub-metafile, this seems not to be used.
							drawinglayer::primitive2d::Primitive2DSequence xSubContent;
							{
                                rTargetHolders.Push();
								// #i# for sub-Mteafile contents, do start with new, default render state
								rPropertyHolders.PushDefault();
								interpretMetafile(rContent, rTargetHolders, rPropertyHolders, rViewInformation);
								xSubContent = rTargetHolders.Current().getPrimitive2DSequence(rPropertyHolders.Current());
								rPropertyHolders.Pop();
                                rTargetHolders.Pop();
							}

							if(xSubContent.hasElements())
							{
                                // prepare sub-content transform
                                basegfx::B2DHomMatrix aSubTransform;

                                // create SourceRange
                                const basegfx::B2DRange aSourceRange(
                                    rContent.GetPrefMapMode().GetOrigin().X(),
                                    rContent.GetPrefMapMode().GetOrigin().Y(),
                                    rContent.GetPrefMapMode().GetOrigin().X() + rContent.GetPrefSize().Width(),
                                    rContent.GetPrefMapMode().GetOrigin().Y() + rContent.GetPrefSize().Height());

                                // apply mapping if aTargetRange and aSourceRange are not equal
                                if(!aSourceRange.equal(aTargetRange))
                                {
                                    aSubTransform.translate(-aSourceRange.getMinX(), -aSourceRange.getMinY());
                                    aSubTransform.scale(
                                        aTargetRange.getWidth() / (basegfx::fTools::equalZero(aSourceRange.getWidth()) ? 1.0 : aSourceRange.getWidth()),
                                        aTargetRange.getHeight() / (basegfx::fTools::equalZero(aSourceRange.getHeight()) ? 1.0 : aSourceRange.getHeight()));
                                    aSubTransform.translate(aTargetRange.getMinX(), aTargetRange.getMinY());
                                }

                                // apply general current transformation
                                aSubTransform = rPropertyHolders.Current().getTransformation() * aSubTransform;

                                // evtl. embed sub-content to it's transformation
                                if(!aSubTransform.isIdentity())
                                {
                                    const drawinglayer::primitive2d::Primitive2DReference aEmbeddedTransform(
                                        new drawinglayer::primitive2d::TransformPrimitive2D(
                                            aSubTransform,
                                            xSubContent));

                                    xSubContent = drawinglayer::primitive2d::Primitive2DSequence(&aEmbeddedTransform, 1);
                                }

								// check if gradient is a real gradient
								const Gradient& rGradient = pA->GetGradient();
								const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient));

								if(aAttribute.getStartColor() == aAttribute.getEndColor())
								{
									// not really a gradient; create UnifiedTransparencePrimitive2D
									rTargetHolders.Current().append(
										new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
											xSubContent,
											aAttribute.getStartColor().luminance()));
								}
								else
								{
									// really a gradient. Create gradient sub-content (with correct scaling)
									basegfx::B2DRange aRange(aTargetRange);
									aRange.transform(rPropertyHolders.Current().getTransformation());

                                    // prepare gradient for transparent content
			                        const drawinglayer::primitive2d::Primitive2DReference xTransparence(
				                        new drawinglayer::primitive2d::FillGradientPrimitive2D(
										    aRange,
										    aAttribute));

									// create transparence primitive
									rTargetHolders.Current().append(
										new drawinglayer::primitive2d::TransparencePrimitive2D(
											xSubContent,
                                            drawinglayer::primitive2d::Primitive2DSequence(&xTransparence, 1)));
								}
							}
						}
					}

                    break;
                }
                case META_GRADIENTEX_ACTION :
                {
					/** SIMPLE, DONE */
                    // This is only a data holder which is interpreted inside comment actions,
                    // see META_COMMENT_ACTION for more info
                    // const MetaGradientExAction* pA = (const MetaGradientExAction*)pAction;
                    break;
                }
                case META_LAYOUTMODE_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaLayoutModeAction* pA = (const MetaLayoutModeAction*)pAction;
                    rPropertyHolders.Current().setLayoutMode(pA->GetLayoutMode());
                    break;
                }
                case META_TEXTLANGUAGE_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaTextLanguageAction* pA = (const MetaTextLanguageAction*)pAction;
                    rPropertyHolders.Current().setLanguageType(pA->GetTextLanguage());
                    break;
                }
                case META_OVERLINECOLOR_ACTION :
                {
					/** SIMPLE, DONE */
                    const MetaOverlineColorAction* pA = (const MetaOverlineColorAction*)pAction;
                    const bool bActive(pA->IsSetting());

                    rPropertyHolders.Current().setOverlineColorActive(bActive);
                    if(bActive)
                        rPropertyHolders.Current().setOverlineColor(pA->GetColor().getBColor());

                    break;
                }
                case META_COMMENT_ACTION :
                {
					/** CHECKED, WORKS WELL */
                    // I already implemented
                    //     XPATHFILL_SEQ_BEGIN, XPATHFILL_SEQ_END
                    //     XPATHSTROKE_SEQ_BEGIN, XPATHSTROKE_SEQ_END,
                    // but opted to remove these again; it works well without them
                    // and makes the code less dependent from those Metafile Add-Ons
                    const MetaCommentAction* pA = (const MetaCommentAction*)pAction;

					if(COMPARE_EQUAL == pA->GetComment().CompareIgnoreCaseToAscii("XGRAD_SEQ_BEGIN"))
					{
                        // XGRAD_SEQ_BEGIN, XGRAD_SEQ_END should be supported since the
                        // pure recorded paint of the gradients uses the XOR paint functionality
                        // ('trick'). This is (and will be) broblematic with AntAliasing, so it's
                        // better to use this info
						const MetaGradientExAction*	pMetaGradientExAction = 0;
						bool bDone(false);
						sal_uInt32 b(nAction + 1);

						for(; !bDone && b < nCount; b++)
						{
							pAction = rMetaFile.GetAction(b);

							if(META_GRADIENTEX_ACTION == pAction->GetType())
							{
								pMetaGradientExAction = (const MetaGradientExAction*)pAction;
							}
							else if(META_COMMENT_ACTION == pAction->GetType())
							{
								if(COMPARE_EQUAL == ((const MetaCommentAction*)pAction)->GetComment().CompareIgnoreCaseToAscii("XGRAD_SEQ_END"))
								{
									bDone = true;
								}
							}
						}

						if(bDone && pMetaGradientExAction)
						{
							// consume actions and skip forward
							nAction = b - 1;

							// get geometry data
							basegfx::B2DPolyPolygon aPolyPolygon(pMetaGradientExAction->GetPolyPolygon().getB2DPolyPolygon());

							if(aPolyPolygon.count())
							{
								// transform geometry
								aPolyPolygon.transform(rPropertyHolders.Current().getTransformation());

								// get and check if gradient is a real gradient
								const Gradient& rGradient = pMetaGradientExAction->GetGradient();
								const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient));

								if(aAttribute.getStartColor() == aAttribute.getEndColor())
								{
									// not really a gradient
									rTargetHolders.Current().append(
										new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
											aPolyPolygon,
											aAttribute.getStartColor()));
								}
								else
								{
									// really a gradient
									rTargetHolders.Current().append(
										new drawinglayer::primitive2d::PolyPolygonGradientPrimitive2D(
											aPolyPolygon,
											aAttribute));
								}
							}
						}
					}

					break;
                }
                default:
                {
                    OSL_ENSURE(false, "Unknown MetaFile Action (!)");
                    break;
                }
            }
        }
    }
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
	namespace primitive2d
	{
		Primitive2DSequence MetafilePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
        {
			// prepare target and porperties; each will have one default entry
            TargetHolders aTargetHolders;
            PropertyHolders aPropertyHolders;

			// set target MapUnit at Properties
			aPropertyHolders.Current().setMapUnit(getMetaFile().GetPrefMapMode().GetMapUnit());

			// interpret the Metafile
            interpretMetafile(getMetaFile(), aTargetHolders, aPropertyHolders, rViewInformation);

			// get the content. There should be ony one target, as in the start condition,
            // but iterating will be the right thing to do when some push/pop is not closed
			Primitive2DSequence xRetval;

            while(aTargetHolders.size() > 1)
            {
                appendPrimitive2DSequenceToPrimitive2DSequence(xRetval,
                    aTargetHolders.Current().getPrimitive2DSequence(aPropertyHolders.Current()));
                aTargetHolders.Pop();
            }

            appendPrimitive2DSequenceToPrimitive2DSequence(xRetval,
                aTargetHolders.Current().getPrimitive2DSequence(aPropertyHolders.Current()));

			if(xRetval.hasElements())
			{
				// get target size
				const Rectangle aMtfTarget(getMetaFile().GetPrefMapMode().GetOrigin(), getMetaFile().GetPrefSize());

                // create transformation
				basegfx::B2DHomMatrix aAdaptedTransform;

				aAdaptedTransform.translate(-aMtfTarget.Left(), -aMtfTarget.Top());
				aAdaptedTransform.scale(
					aMtfTarget.getWidth() ? 1.0 / aMtfTarget.getWidth() : 1.0,
					aMtfTarget.getHeight() ? 1.0 / aMtfTarget.getHeight() : 1.0);
				aAdaptedTransform = getTransform() * aAdaptedTransform;

				// embed to target transformation
				const Primitive2DReference aEmbeddedTransform(
					new TransformPrimitive2D(
						aAdaptedTransform,
						xRetval));

				xRetval = Primitive2DSequence(&aEmbeddedTransform, 1);
			}

            return xRetval;
        }

		MetafilePrimitive2D::MetafilePrimitive2D(
			const basegfx::B2DHomMatrix& rMetaFileTransform,
			const GDIMetaFile& rMetaFile)
		:	BufferedDecompositionPrimitive2D(),
			maMetaFileTransform(rMetaFileTransform),
			maMetaFile(rMetaFile)
		{
		}

		bool MetafilePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
		{
			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
			{
				const MetafilePrimitive2D& rCompare = (MetafilePrimitive2D&)rPrimitive;

				return (getTransform() == rCompare.getTransform()
					&& getMetaFile() == rCompare.getMetaFile());
			}

			return false;
		}

		basegfx::B2DRange MetafilePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
		{
			// use own implementation to quickly answer the getB2DRange question. The
            // MetafilePrimitive2D assumes that all geometry is inside of the shape. If
            // this is not the case (i have already seen some wrong Metafiles) it should
            // be embedded to a MaskPrimitive2D
			basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
			aRetval.transform(getTransform());

            return aRetval;
		}

		// provide unique ID
		ImplPrimitrive2DIDBlock(MetafilePrimitive2D, PRIMITIVE2D_ID_METAFILEPRIMITIVE2D)

	} // end of namespace primitive2d
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////
// eof
