/**************************************************************
 * 
 * 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/processor2d/vclpixelprocessor2d.hxx>
#include <vcl/outdev.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
#include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
#include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx>
#include <drawinglayer/primitive2d/controlprimitive2d.hxx>
#include <com/sun/star/awt/XWindow2.hpp>
#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
#include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
#include <helperwrongspellrenderer.hxx>
#include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <vcl/hatch.hxx>
#include <tools/diagnose_ex.h>
#include <com/sun/star/awt/PosSize.hpp>
#include <drawinglayer/primitive2d/invertprimitive2d.hxx>
#include <cstdio>
#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <drawinglayer/primitive2d/epsprimitive2d.hxx>
#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/window.hxx>

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

using namespace com::sun::star;

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

namespace drawinglayer
{
	namespace processor2d
	{
		VclPixelProcessor2D::VclPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev)
		:	VclProcessor2D(rViewInformation, rOutDev)
		{
			// prepare maCurrentTransformation matrix with viewTransformation to target directly to pixels
			maCurrentTransformation = rViewInformation.getObjectToViewTransformation();

            // prepare output directly to pixels
   			mpOutputDevice->Push(PUSH_MAPMODE);
    		mpOutputDevice->SetMapMode();

            // react on AntiAliasing settings
            if(getOptionsDrawinglayer().IsAntiAliasing())
            {
                mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW);
            }
            else
            {
                mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
            }
        }

		VclPixelProcessor2D::~VclPixelProcessor2D()
		{
            // restore MapMode
   			mpOutputDevice->Pop();

            // restore AntiAliasing
            mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
		}

        bool VclPixelProcessor2D::tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency)
        {
            basegfx::B2DPolyPolygon aLocalPolyPolygon(rSource.getB2DPolyPolygon());

            if(!aLocalPolyPolygon.count())
            {
                // no geometry, done
                return true;
            }

            const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rSource.getBColor()));

            mpOutputDevice->SetFillColor(Color(aPolygonColor));
            mpOutputDevice->SetLineColor();
            aLocalPolyPolygon.transform(maCurrentTransformation);
            mpOutputDevice->DrawTransparent(
                aLocalPolyPolygon, 
                fTransparency);

            return true;
        }

        bool VclPixelProcessor2D::tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency)
        {
            basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon());

            if(!aLocalPolygon.count())
            {
                // no geometry, done
                return true;
            }

            const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rSource.getBColor()));

            mpOutputDevice->SetFillColor();
            mpOutputDevice->SetLineColor(Color(aLineColor));
            aLocalPolygon.transform(maCurrentTransformation);

            // try drawing; if it did not work, use standard fallback
            if(mpOutputDevice->TryDrawPolyLineDirect(
                aLocalPolygon, 
                0.0, 
                fTransparency))
            {
                return true;
            }

            return false;
        }

        bool VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency)
        {
            basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon());

            if(!aLocalPolygon.count())
            {
                // no geometry, done
                return true;
            }

            aLocalPolygon = basegfx::tools::simplifyCurveSegments(aLocalPolygon);
            basegfx::B2DPolyPolygon aHairLinePolyPolygon;

            if(rSource.getStrokeAttribute().isDefault() || 0.0 == rSource.getStrokeAttribute().getFullDotDashLen())
            {
                // no line dashing, just copy
                aHairLinePolyPolygon.append(aLocalPolygon);
            }
            else
            {
                // apply LineStyle
                basegfx::tools::applyLineDashing(
                    aLocalPolygon, 
                    rSource.getStrokeAttribute().getDotDashArray(), 
                    &aHairLinePolyPolygon, 
                    0, 
                    rSource.getStrokeAttribute().getFullDotDashLen());
            }

            if(!aHairLinePolyPolygon.count())
            {
                // no geometry, done
                return true;
            }

            const basegfx::BColor aLineColor(
                maBColorModifierStack.getModifiedColor(
                    rSource.getLineAttribute().getColor()));

            mpOutputDevice->SetFillColor();
            mpOutputDevice->SetLineColor(Color(aLineColor));
            aHairLinePolyPolygon.transform(maCurrentTransformation);

            double fLineWidth(rSource.getLineAttribute().getWidth());

            if(basegfx::fTools::more(fLineWidth, 0.0))
            {
                basegfx::B2DVector aLineWidth(fLineWidth, 0.0);

                aLineWidth = maCurrentTransformation * aLineWidth;
                fLineWidth = aLineWidth.getLength();
            }

            bool bHasPoints(false);
            bool bTryWorked(false);

            for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++)
            {
                const basegfx::B2DPolygon aSingle(aHairLinePolyPolygon.getB2DPolygon(a));

                if(aSingle.count())
                {
                    bHasPoints = true;

                    if(mpOutputDevice->TryDrawPolyLineDirect(
                        aSingle, 
                        fLineWidth, 
                        fTransparency,
                        rSource.getLineAttribute().getLineJoin(),
                        rSource.getLineAttribute().getLineCap()))
                    {
                        bTryWorked = true;
                    }
                }
            }

            if(!bTryWorked && !bHasPoints)
            {
                // no geometry despite try
                bTryWorked = true;
            }

            return bTryWorked;
        }

		void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
		{
			switch(rCandidate.getPrimitive2DID())
			{
                case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
                {
					// directdraw of wrong spell primitive; added test possibility to check wrong spell decompose
                    static bool bHandleWrongSpellDirectly(true);

                    if(bHandleWrongSpellDirectly)
                    {
						const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate);

						if(!renderWrongSpellPrimitive2D(
							rWrongSpellPrimitive, 
							*mpOutputDevice, 
							maCurrentTransformation,
							maBColorModifierStack))
						{
							// fallback to decomposition (MetaFile)
							process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D()));
						}
                    }
                    else
                    {
    					process(rCandidate.get2DDecomposition(getViewInformation2D()));
                    }
                    break;
                }
				case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
				{
					// directdraw of text simple portion; added test possibility to check text decompose
                    static bool bForceSimpleTextDecomposition(false);

					// Adapt evtl. used special DrawMode
					const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
					adaptTextToFillDrawMode();

					if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect())
                    {
    					RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate));
                    }
                    else
                    {
    					process(rCandidate.get2DDecomposition(getViewInformation2D()));
                    }
					
					// restore DrawMode
					mpOutputDevice->SetDrawMode(nOriginalDrawMode);
					
					break;
				}
				case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D :
				{
					// directdraw of text simple portion; added test possibility to check text decompose
                    static bool bForceComplexTextDecomposition(false);

					// Adapt evtl. used special DrawMode
					const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
					adaptTextToFillDrawMode();

					if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect())
                    {
    					RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate));
                    }
                    else
                    {
    					process(rCandidate.get2DDecomposition(getViewInformation2D()));
                    }

					// restore DrawMode
					mpOutputDevice->SetDrawMode(nOriginalDrawMode);

					break;
				}
				case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
				{
                    // try to use directly
                    const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate);
                    static bool bAllowed(true);

                    if(bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0))
                    {
                        break;
                    }

                    // direct draw of hairline
                    RenderPolygonHairlinePrimitive2D(rPolygonHairlinePrimitive2D, true);
					break;
				}
				case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
				{
                    // direct draw of transformed BitmapEx primitive
                    const primitive2d::BitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate);

                    // check if graphic content is inside discrete local ViewPort
                    const basegfx::B2DRange& rDiscreteViewPort(getViewInformation2D().getDiscreteViewport());
                    const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rBitmapCandidate.getTransform());

                    if(!rDiscreteViewPort.isEmpty())
                    {
                        basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);

                        aUnitRange.transform(aLocalTransform);

                        if(!aUnitRange.overlaps(rDiscreteViewPort))
                        {
                            // content is outside discrete local ViewPort
                            break;
                        }
                    }

					RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D :
				{
					// direct draw of fillBitmapPrimitive
					RenderFillGraphicPrimitive2D(static_cast< const primitive2d::FillGraphicPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D :
				{
				    // direct draw of gradient
					const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate);
			        const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient());
			        basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor()));
			        basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor()));
			        basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());

			        if(aLocalPolyPolygon.count())
			        {
				        aLocalPolyPolygon.transform(maCurrentTransformation);

				        if(aStartColor == aEndColor)
				        {
					        // no gradient at all, draw as polygon in AA and non-AA case
					        mpOutputDevice->SetLineColor();
					        mpOutputDevice->SetFillColor(Color(aStartColor));
					        mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
				        }
				        else
				        {
                            // use the primitive decomposition of the metafile
					        process(rPolygonCandidate.get2DDecomposition(getViewInformation2D()));
				        }
			        }
					break;
				}
				case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D :
				{
				    // direct draw of bitmap
				    RenderPolyPolygonGraphicPrimitive2D(static_cast< const primitive2d::PolyPolygonGraphicPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
				{
                    // try to use directly
                    const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D = static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate);
                    basegfx::B2DPolyPolygon aLocalPolyPolygon;
                    static bool bAllowed(true);

                    if(bAllowed && tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0))
                    {
                        // okay, done. In this case no gaps should have to be repaired, too
                    }
                    else
                    {
                        // direct draw of PolyPolygon with color
                        const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));

                        mpOutputDevice->SetFillColor(Color(aPolygonColor));
                        mpOutputDevice->SetLineColor();
                        aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
                        aLocalPolyPolygon.transform(maCurrentTransformation);
                        mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
                    }

                    // when AA is on and this filled polygons are the result of stroked line geometry,
                    // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons
                    // Caution: This is needed in both cases (!)
                    if(mnPolygonStrokePrimitive2D
                        && getOptionsDrawinglayer().IsAntiAliasing()
                        && (mpOutputDevice->GetAntialiasing() & ANTIALIASING_ENABLE_B2DDRAW))
                    {
                        const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
                        sal_uInt32 nCount(aLocalPolyPolygon.count());

                        if(!nCount)
                        {
                            aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
                            aLocalPolyPolygon.transform(maCurrentTransformation);
                            nCount = aLocalPolyPolygon.count();
                        }

                        mpOutputDevice->SetFillColor();
                        mpOutputDevice->SetLineColor(Color(aPolygonColor));

                        for(sal_uInt32 a(0); a < nCount; a++)
                        {
                            mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0);
                        }
                    }

					break;
				}
				case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
				{
       				// #i98289#
                    const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete());
                    const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing());

                    if(bForceLineSnap)
                    {
                        mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE);
                    }

                    // use new Metafile decomposition
    				process(rCandidate.get2DDecomposition(getViewInformation2D()));
                    
                    if(bForceLineSnap)
                    {
                        mpOutputDevice->SetAntialiasing(nOldAntiAliase);
                    }
					
                    break;
				}
				case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
				{
					// mask group.
					RenderMaskPrimitive2DPixel(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D :
				{
					// modified color group. Force output to unified color.
					RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D :
				{
					// Detect if a single PolyPolygonColorPrimitive2D is contained; in that case,
					// use the faster OutputDevice::DrawTransparent method
					const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate);
					const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren();

					if(rContent.hasElements())
					{
                        if(0.0 == rUniTransparenceCandidate.getTransparence())
                        {
                            // not transparent at all, use content
	                        process(rUniTransparenceCandidate.getChildren());
                        }
			            else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0)
			            {
					        bool bDrawTransparentUsed(false);

					        // since DEV300 m33 DrawTransparent is supported in VCL (for some targets
                            // natively), so i am now enabling this shortcut
					        static bool bAllowUsingDrawTransparent(true);

					        if(bAllowUsingDrawTransparent && 1 == rContent.getLength())
					        {
						        const primitive2d::Primitive2DReference xReference(rContent[0]);
								const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get());

								if(pBasePrimitive)
								{
									switch(pBasePrimitive->getPrimitive2DID())
									{
										case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D:
										{
                                            // single transparent PolyPolygon identified, use directly
                                            const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive);
                                            OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)");
                                            bDrawTransparentUsed = tryDrawPolyPolygonColorPrimitive2DDirect(*pPoPoColor, rUniTransparenceCandidate.getTransparence());
                                            break;
                                        }
                                        case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D:
                                        {
                                            // single transparent PolygonHairlinePrimitive2D identified, use directly
                                            const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive);
                                            OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)");

                                            // do no tallow by default - problem is that self-overlapping parts of this geometry will
                                            // not be in a all-same transparency but will already alpha-cover themselves with blending.
                                            // This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's
                                            // content to be uniformely transparent.
                                            // For hairline the effect is pretty minimal, but still not correct.
                                            static bool bAllowed(false);

                                            bDrawTransparentUsed = bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(*pPoHair, rUniTransparenceCandidate.getTransparence());
                                            break;
                                        }
                                        case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
                                        {
                                            // single transparent PolygonStrokePrimitive2D identified, use directly
                                            const primitive2d::PolygonStrokePrimitive2D* pPoStroke = static_cast< const primitive2d::PolygonStrokePrimitive2D* >(pBasePrimitive);
                                            OSL_ENSURE(pPoStroke, "OOps, PrimitiveID and PrimitiveType do not match (!)");

                                            // do no tallow by default - problem is that self-overlapping parts of this geometry will
                                            // not be in a all-same transparency but will already alpha-cover themselves with blending.
                                            // This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's
                                            // content to be uniformely transparent.
                                            // To check, acitvate and draw a wide transparent self-crossing line/curve
                                            static bool bAllowed(false);

                                            bDrawTransparentUsed = bAllowed && tryDrawPolygonStrokePrimitive2DDirect(*pPoStroke, rUniTransparenceCandidate.getTransparence());
                                            break;
                                        }
									}
								}
					        }

					        if(!bDrawTransparentUsed)
					        {
					            // unified sub-transparence. Draw to VDev first.
					            RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate);
					        }
                        }
                    }

					break;
				}
				case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D :
				{
					// sub-transparence group. Draw to VDev first.
					RenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D :
				{
					// transform group.
					RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate));
					break;
				}
                case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D :
				{
					// new XDrawPage for ViewInformation2D
					RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
				{
					// marker array
					RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
				{
					// point array
					RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate));
					break;
				}
				case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D :
				{
					// control primitive
					const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate);
        			const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl());

                    try
                    {
                        // remember old graphics and create new
					    uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW);
                        const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics());
					    const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics());

                        if(xNewGraphics.is())
                        {
				            // link graphics and view
				            xControlView->setGraphics(xNewGraphics);

                            // get position
                            const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation * rControlPrimitive.getTransform());
                            const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0));

                            // find out if the control is already visualized as a VCL-ChildWindow. If yes,
                            // it does not need to be painted at all.
                            uno::Reference< awt::XWindow2 > xControlWindow(rXControl, uno::UNO_QUERY_THROW);
	                        const bool bControlIsVisibleAsChildWindow(rXControl->getPeer().is() && xControlWindow->isVisible());
                            
    					    if(!bControlIsVisibleAsChildWindow)
                            {
                                // draw it. Do not forget to use the evtl. offsetted origin of the target device,
                                // e.g. when used with mask/transparence buffer device
                                const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin());
                                xControlView->draw(
                                    aOrigin.X() + basegfx::fround(aTopLeftPixel.getX()), 
                                    aOrigin.Y() + basegfx::fround(aTopLeftPixel.getY()));
                            }
                            
                            // restore original graphics
				            xControlView->setGraphics(xOriginalGraphics);
                        }
                    }
                    catch(const uno::Exception&)
                    {
						// #i116763# removing since there is a good alternative when the xControlView
						// is not found and it is allowed to happen
                        // DBG_UNHANDLED_EXCEPTION();
                        
                        // process recursively and use the decomposition as Bitmap
				        process(rCandidate.get2DDecomposition(getViewInformation2D()));
                    }

                    break;
				}
				case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
				{
                    // try to use directly
                    const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive2D = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);

                    if(tryDrawPolygonStrokePrimitive2DDirect(rPolygonStrokePrimitive2D, 0.0))
                    {
                        break;
                    }

					// the stroke primitive may be decomposed to filled polygons. To keep
					// evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE,
					// DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE
					// working, these need to be copied to the corresponding fill modes
					const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
					adaptLineToFillDrawMode();

					// polygon stroke primitive
					static bool bSuppressFatToHairlineCorrection(false);

					if(bSuppressFatToHairlineCorrection)
					{
                        // remeber that we enter a PolygonStrokePrimitive2D decomposition,
                        // used for AA thick line drawing
                        mnPolygonStrokePrimitive2D++;

                        // with AA there is no need to handle thin lines special
						process(rCandidate.get2DDecomposition(getViewInformation2D()));

                        // leave PolygonStrokePrimitive2D
                        mnPolygonStrokePrimitive2D--;
					}
					else
					{
						// Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation
						// as filled polygons is geometrically corret but looks wrong since polygon filling avoids
						// the right and bottom pixels. The used method evaluates that and takes the correct action,
						// including calling recursively with decomposition if line is wide enough
						RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D);
					}

					// restore DrawMode
					mpOutputDevice->SetDrawMode(nOriginalDrawMode);

					break;
				}
				case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D :
				{
					static bool bForceIgnoreHatchSmoothing(false);

                    if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing())
                    {
						// if AA is used (or ignore smoothing is on), there is no need to smooth 
						// hatch painting, use decomposition
						process(rCandidate.get2DDecomposition(getViewInformation2D()));
					}
					else
					{
						// without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel 
						// and forces hatch distance to be >= 3 pixels to make the hatch display look smoother. 
						// This is wrong in principle, but looks nicer. This could also be done here directly
						// without VCL usage if needed
						const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate);
						const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch();
						
						// create hatch polygon in range size and discrete coordinates
						basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getObjectRange());
						aHatchRange.transform(maCurrentTransformation);
						const basegfx::B2DPolygon aHatchPolygon(basegfx::tools::createPolygonFromRect(aHatchRange));

                        if(rFillHatchAttributes.isFillBackground())
                        {
                            // #i111846# background fill is active; draw fill polygon
			                const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
			                
                            mpOutputDevice->SetFillColor(Color(aPolygonColor));
			                mpOutputDevice->SetLineColor();
            			    mpOutputDevice->DrawPolygon(aHatchPolygon);
                        }

						// set hatch line color
						const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
						mpOutputDevice->SetFillColor();
						mpOutputDevice->SetLineColor(Color(aHatchColor));

						// get hatch style
						HatchStyle eHatchStyle(HATCH_SINGLE);

						switch(rFillHatchAttributes.getStyle())
						{
							default : // HATCHSTYLE_SINGLE
							{
								break;
							}
							case attribute::HATCHSTYLE_DOUBLE :
							{
								eHatchStyle = HATCH_DOUBLE;
								break;
							}
							case attribute::HATCHSTYLE_TRIPLE :
							{
								eHatchStyle = HATCH_TRIPLE;
								break;
							}
						}

						// create hatch
						const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0));
						const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength()));
						const sal_uInt16 nAngle10((sal_uInt16)basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800));
						::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10);

						// draw hatch using VCL
						mpOutputDevice->DrawHatch(PolyPolygon(Polygon(aHatchPolygon)), aVCLHatch);
					}
					break;
				}
				case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D :
				{
					// #i98404# Handle directly, especially when AA is active
					const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate);
					const sal_uInt16 nOriginalAA(mpOutputDevice->GetAntialiasing());

					// switch AA off in all cases
	                mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);

					// create color for fill
					const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor()));
					mpOutputDevice->SetFillColor(Color(aPolygonColor));
					mpOutputDevice->SetLineColor();

					// create rectangle for fill
					const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport());
					const Rectangle aRectangle(
						(sal_Int32)floor(aViewport.getMinX()), (sal_Int32)floor(aViewport.getMinY()),
						(sal_Int32)ceil(aViewport.getMaxX()), (sal_Int32)ceil(aViewport.getMaxY()));
					mpOutputDevice->DrawRect(aRectangle);

					// restore AA setting
					mpOutputDevice->SetAntialiasing(nOriginalAA);
					break;
				}
                case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D :
                {
                    // #i97628#
                    // This primitive means that the content is derived from an active text edit,
                    // not from model data itself. Some renderers need to suppress this content, e.g.
                    // the pixel renderer used for displaying the edit view (like this one). It's
                    // not to be suppressed by the MetaFile renderers, so that the edited text is
                    // part of the MetaFile, e.g. needed for presentation previews.
                    // Action: Ignore here, do nothing.
                    break;
                }
				case PRIMITIVE2D_ID_INVERTPRIMITIVE2D :
				{
					// invert primitive (currently only used for HighContrast fallback for selection in SW and SC).
					// Set OutDev to XOR and switch AA off (XOR does not work with AA)
                    mpOutputDevice->Push();
                    mpOutputDevice->SetRasterOp( ROP_XOR );
                    const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing());
                    mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW);

					// process content recursively
					process(rCandidate.get2DDecomposition(getViewInformation2D()));

					// restore OutDev
					mpOutputDevice->Pop();
                    mpOutputDevice->SetAntialiasing(nAntiAliasing);
					break;
				}
                case PRIMITIVE2D_ID_EPSPRIMITIVE2D :
                {
					RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate));
                    break;
                }
                case PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D:
                {
                    RenderSvgLinearAtomPrimitive2D(static_cast< const primitive2d::SvgLinearAtomPrimitive2D& >(rCandidate));
                    break;
                }
                case PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D:
                {
                    RenderSvgRadialAtomPrimitive2D(static_cast< const primitive2d::SvgRadialAtomPrimitive2D& >(rCandidate));
                    break;
                }
				default :
				{
					// process recursively
					process(rCandidate.get2DDecomposition(getViewInformation2D()));
					break;
				}
			}
		}
	} // end of namespace processor2d
} // end of namespace drawinglayer

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