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

#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>

#include <rtl/math.hxx>

#include <com/sun/star/rendering/TextDirection.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
#include <com/sun/star/rendering/PathCapType.hpp>
#include <com/sun/star/rendering/PathJoinType.hpp>

#include <tools/poly.hxx>
#include <vcl/window.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/virdev.hxx>
#include <vcl/canvastools.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dsize.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dlinegeometry.hxx>
#include <basegfx/tools/tools.hxx>
#include <basegfx/tools/lerp.hxx>
#include <basegfx/tools/keystoplerp.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/numeric/ftools.hxx>

#include <comphelper/sequence.hxx>

#include <canvas/canvastools.hxx>
#include <canvas/parametricpolypolygon.hxx>

#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>

#include "spritecanvas.hxx"
#include "canvashelper.hxx"
#include "impltools.hxx"


using namespace ::com::sun::star;

namespace vclcanvas
{
    namespace
    {
        bool textureFill( OutputDevice&			rOutDev,
                          GraphicObject&		rGraphic,
                          const ::Point&		rPosPixel,
                          const ::Size&			rNextTileX,
                          const ::Size&			rNextTileY,
                          sal_Int32				nTilesX,
                          sal_Int32				nTilesY,
                          const ::Size&			rTileSize,
                          const GraphicAttr&	rAttr)
        {
            bool bRet( false );
            Point 	aCurrPos;
            int 	nX, nY;

            for( nY=0; nY < nTilesY; ++nY )
            {
                aCurrPos.X() = rPosPixel.X() + nY*rNextTileY.Width();
                aCurrPos.Y() = rPosPixel.Y() + nY*rNextTileY.Height();

                for( nX=0; nX < nTilesX; ++nX )
                {
                    // update return value. This method should return true, if
                    // at least one of the looped Draws succeeded.
                    bRet |= ( sal_True == rGraphic.Draw( &rOutDev, 
                                           aCurrPos,
                                           rTileSize,
                                           &rAttr ) );
                    
                    aCurrPos.X() += rNextTileX.Width();
                    aCurrPos.Y() += rNextTileX.Height();
                }
            }

            return bRet;
        }


        /** Fill linear or axial gradient

        	Since most of the code for linear and axial gradients are
        	the same, we've a unified method here
         */
        void fillLinearGradient( OutputDevice&					                rOutDev,
                                 const ::basegfx::B2DHomMatrix&	                rTextureTransform,
                                 const ::Rectangle&				                rBounds,
                                 unsigned int								    nStepCount,
                                 const ::canvas::ParametricPolyPolygon::Values& rValues,
                                 const std::vector< ::Color >&                  rColors )
        {
            // determine general position of gradient in relation to
            // the bound rect
            // =====================================================

            ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 );
            ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 );
            ::basegfx::B2DPoint aRightTop( 1.0, 0.0 );
            ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 );

            aLeftTop	*= rTextureTransform;
            aLeftBottom *= rTextureTransform;
            aRightTop 	*= rTextureTransform;
            aRightBottom*= rTextureTransform;

            // calc length of bound rect diagonal
            const ::basegfx::B2DVector aBoundRectDiagonal( 
                ::vcl::unotools::b2DPointFromPoint( rBounds.TopLeft() ) -
                ::vcl::unotools::b2DPointFromPoint( rBounds.BottomRight() ) );
            const double nDiagonalLength( aBoundRectDiagonal.getLength() );

            // create direction of gradient:
            //     _______
            //     |  |  | 
            // ->  |  |  | ...
            //     |  |  | 
            //     -------            
            ::basegfx::B2DVector aDirection( aRightTop - aLeftTop );
            aDirection.normalize();

            // now, we potentially have to enlarge our gradient area
            // atop and below the transformed [0,1]x[0,1] unit rect,
            // for the gradient to fill the complete bound rect.
            ::basegfx::tools::infiniteLineFromParallelogram( aLeftTop,
                                                             aLeftBottom,
                                                             aRightTop,
                                                             aRightBottom,
                                                             ::vcl::unotools::b2DRectangleFromRectangle( rBounds ) );
            

            // render gradient
            // ===============

            // for linear gradients, it's easy to render
            // non-overlapping polygons: just split the gradient into
            // nStepCount small strips. Prepare the strip now.

            // For performance reasons, we create a temporary VCL
            // polygon here, keep it all the way and only change the
            // vertex values in the loop below (as ::Polygon is a
            // pimpl class, creating one every loop turn would really
            // stress the mem allocator)
            ::Polygon aTempPoly( static_cast<sal_uInt16>(5) );

            OSL_ENSURE( nStepCount >= 3,
                        "fillLinearGradient(): stepcount smaller than 3" );

        
            // fill initial strip (extending two times the bound rect's
            // diagonal to the 'left'
            // ------------------------------------------------------

            // calculate left edge, by moving left edge of the
            // gradient rect two times the bound rect's diagonal to
            // the 'left'. Since we postpone actual rendering into the
            // loop below, we set the _right_ edge here, which will be
            // readily copied into the left edge in the loop below
            const ::basegfx::B2DPoint& rPoint1( aLeftTop - 2.0*nDiagonalLength*aDirection );
            aTempPoly[1] = ::Point( ::basegfx::fround( rPoint1.getX() ),
                                    ::basegfx::fround( rPoint1.getY() ) );

            const ::basegfx::B2DPoint& rPoint2( aLeftBottom - 2.0*nDiagonalLength*aDirection );
            aTempPoly[2] = ::Point( ::basegfx::fround( rPoint2.getX() ),
                                    ::basegfx::fround( rPoint2.getY() ) );


            // iteratively render all other strips
            // -----------------------------------
            
            // ensure that nStepCount matches color stop parity, to
            // have a well-defined middle color e.g. for axial
            // gradients.
            if( (rColors.size() % 2) != (nStepCount % 2) )
                ++nStepCount;

            rOutDev.SetLineColor();

            basegfx::tools::KeyStopLerp aLerper(rValues.maStops);

            // only iterate nStepCount-1 steps, as the last strip is
            // explicitely painted below
            for( unsigned int i=0; i<nStepCount-1; ++i )
            {
                std::ptrdiff_t nIndex;
                double fAlpha;
                boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(double(i)/nStepCount);

                rOutDev.SetFillColor( 
                    Color( (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetRed(),rColors[nIndex+1].GetRed(),fAlpha)),
                           (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetGreen(),rColors[nIndex+1].GetGreen(),fAlpha)),
                           (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetBlue(),rColors[nIndex+1].GetBlue(),fAlpha)) ));

                // copy right egde of polygon to left edge (and also
                // copy the closing point)
                aTempPoly[0] = aTempPoly[4] = aTempPoly[1];
                aTempPoly[3] = aTempPoly[2];

                // calculate new right edge, from interpolating
                // between start and end line. Note that i is
                // increased by one, to account for the fact that we
                // calculate the right border here (whereas the fill
                // color is governed by the left edge)
                const ::basegfx::B2DPoint& rPoint3( 
                    (nStepCount - i-1)/double(nStepCount)*aLeftTop + 
                    (i+1)/double(nStepCount)*aRightTop );
                aTempPoly[1] = ::Point( ::basegfx::fround( rPoint3.getX() ),
                                        ::basegfx::fround( rPoint3.getY() ) );

                const ::basegfx::B2DPoint& rPoint4( 
                    (nStepCount - i-1)/double(nStepCount)*aLeftBottom + 
                    (i+1)/double(nStepCount)*aRightBottom );
                aTempPoly[2] = ::Point( ::basegfx::fround( rPoint4.getX() ),
                                        ::basegfx::fround( rPoint4.getY() ) );
                
                rOutDev.DrawPolygon( aTempPoly );
            }

            // fill final strip (extending two times the bound rect's
            // diagonal to the 'right'
            // ------------------------------------------------------

            // copy right egde of polygon to left edge (and also
            // copy the closing point)
            aTempPoly[0] = aTempPoly[4] = aTempPoly[1];
            aTempPoly[3] = aTempPoly[2];

            // calculate new right edge, by moving right edge of the
            // gradient rect two times the bound rect's diagonal to
            // the 'right'.
            const ::basegfx::B2DPoint& rPoint3( aRightTop + 2.0*nDiagonalLength*aDirection );
            aTempPoly[0] = aTempPoly[4] = ::Point( ::basegfx::fround( rPoint3.getX() ),
                                                   ::basegfx::fround( rPoint3.getY() ) );

            const ::basegfx::B2DPoint& rPoint4( aRightBottom + 2.0*nDiagonalLength*aDirection );
            aTempPoly[3] = ::Point( ::basegfx::fround( rPoint4.getX() ),
                                    ::basegfx::fround( rPoint4.getY() ) );

            rOutDev.SetFillColor( rColors.back() );

            rOutDev.DrawPolygon( aTempPoly );
        }

        void fillPolygonalGradient( OutputDevice&                                  rOutDev,
                                    const ::basegfx::B2DHomMatrix&                 rTextureTransform,
                                    const ::Rectangle&                             rBounds,
                                    unsigned int                                   nStepCount,
                                    bool                                           bFillNonOverlapping,
                                    const ::canvas::ParametricPolyPolygon::Values& rValues,
                                    const std::vector< ::Color >&                  rColors )
        {
            const ::basegfx::B2DPolygon& rGradientPoly( rValues.maGradientPoly );

            ENSURE_OR_THROW( rGradientPoly.count() > 2,
                              "fillPolygonalGradient(): polygon without area given" );

            // For performance reasons, we create a temporary VCL polygon
            // here, keep it all the way and only change the vertex values
            // in the loop below (as ::Polygon is a pimpl class, creating
            // one every loop turn would really stress the mem allocator)
            ::basegfx::B2DPolygon 	aOuterPoly( rGradientPoly );
            ::basegfx::B2DPolygon 	aInnerPoly;

            // subdivide polygon _before_ rendering, would otherwise have
            // to be performed on every loop turn.
            if( aOuterPoly.areControlPointsUsed() )
                aOuterPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aOuterPoly);

            aInnerPoly = aOuterPoly;
        
            // only transform outer polygon _after_ copying it into
            // aInnerPoly, because inner polygon has to be scaled before
            // the actual texture transformation takes place
            aOuterPoly.transform( rTextureTransform );

            // determine overall transformation for inner polygon (might
            // have to be prefixed by anisotrophic scaling)
            ::basegfx::B2DHomMatrix aInnerPolygonTransformMatrix;

        
            // apply scaling (possibly anisotrophic) to inner polygon
            // ------------------------------------------------------

            // scale inner polygon according to aspect ratio: for
            // wider-than-tall bounds (nAspectRatio > 1.0), the inner
            // polygon, representing the gradient focus, must have
            // non-zero width. Specifically, a bound rect twice as wide as
            // tall has a focus polygon of half it's width.
            const double nAspectRatio( rValues.mnAspectRatio );
            if( nAspectRatio > 1.0 )
            {
                // width > height case
                aInnerPolygonTransformMatrix.scale( 1.0 - 1.0/nAspectRatio,
                                                    0.0 );
            }
            else if( nAspectRatio < 1.0 )
            {
                // width < height case
                aInnerPolygonTransformMatrix.scale( 0.0, 
                                                    1.0 - nAspectRatio );
            }
            else
            {
                // isotrophic case
                aInnerPolygonTransformMatrix.scale( 0.0, 0.0 );
            }

            // and finally, add texture transform to it.
            aInnerPolygonTransformMatrix *= rTextureTransform;

            // apply final matrix to polygon
            aInnerPoly.transform( aInnerPolygonTransformMatrix );
        

            const sal_uInt32 nNumPoints( aOuterPoly.count() );
            ::Polygon		 aTempPoly( static_cast<sal_uInt16>(nNumPoints+1) );
        
            // increase number of steps by one: polygonal gradients have
            // the outermost polygon rendered in rColor2, and the
            // innermost in rColor1. The innermost polygon will never
            // have zero area, thus, we must divide the interval into
            // nStepCount+1 steps. For example, to create 3 steps:
            //
            // |                       |
            // |-------|-------|-------|
            // |                       |
            // 3       2       1       0 
            //
            // This yields 4 tick marks, where 0 is never attained (since
            // zero-area polygons typically don't display perceivable
            // color).
            ++nStepCount;

            rOutDev.SetLineColor();

            basegfx::tools::KeyStopLerp aLerper(rValues.maStops);

            if( !bFillNonOverlapping )
            {
                // fill background
                rOutDev.SetFillColor( rColors.front() );
                rOutDev.DrawRect( rBounds );

                // render polygon
                // ==============

                for( unsigned int i=1,p; i<nStepCount; ++i )
                {
                    const double fT( i/double(nStepCount) );            

                    std::ptrdiff_t nIndex;
                    double fAlpha;
                    boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(fT);

                    // lerp color
                    rOutDev.SetFillColor( 
                        Color( (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetRed(),rColors[nIndex+1].GetRed(),fAlpha)),
                               (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetGreen(),rColors[nIndex+1].GetGreen(),fAlpha)),
                               (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetBlue(),rColors[nIndex+1].GetBlue(),fAlpha)) ));

                    // scale and render polygon, by interpolating between
                    // outer and inner polygon. 

                    for( p=0; p<nNumPoints; ++p )
                    {
                        const ::basegfx::B2DPoint& rOuterPoint( aOuterPoly.getB2DPoint(p) );
                        const ::basegfx::B2DPoint& rInnerPoint( aInnerPoly.getB2DPoint(p) );

                        aTempPoly[(sal_uInt16)p] = ::Point( 
                            basegfx::fround( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ),
                            basegfx::fround( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) );
                    }

                    // close polygon explicitely
                    aTempPoly[(sal_uInt16)p] = aTempPoly[0];

                    // TODO(P1): compare with vcl/source/gdi/outdev4.cxx,
                    // OutputDevice::ImplDrawComplexGradient(), there's a note
                    // that on some VDev's, rendering disjunct poly-polygons
                    // is faster!
                    rOutDev.DrawPolygon( aTempPoly );
                }
            }
            else
            {
                // render polygon
                // ==============

                // For performance reasons, we create a temporary VCL polygon
                // here, keep it all the way and only change the vertex values
                // in the loop below (as ::Polygon is a pimpl class, creating
                // one every loop turn would really stress the mem allocator)
                ::PolyPolygon			aTempPolyPoly;
                ::Polygon				aTempPoly2( static_cast<sal_uInt16>(nNumPoints+1) );

                aTempPoly2[0] = rBounds.TopLeft();
                aTempPoly2[1] = rBounds.TopRight();
                aTempPoly2[2] = rBounds.BottomRight();
                aTempPoly2[3] = rBounds.BottomLeft();
                aTempPoly2[4] = rBounds.TopLeft();

                aTempPolyPoly.Insert( aTempPoly );
                aTempPolyPoly.Insert( aTempPoly2 );

                for( unsigned int i=0,p; i<nStepCount; ++i )
                {
                    const double fT( (i+1)/double(nStepCount) );
            
                    std::ptrdiff_t nIndex;
                    double fAlpha;
                    boost::tuples::tie(nIndex,fAlpha)=aLerper.lerp(fT);

                    // lerp color
                    rOutDev.SetFillColor( 
                        Color( (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetRed(),rColors[nIndex+1].GetRed(),fAlpha)),
                               (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetGreen(),rColors[nIndex+1].GetGreen(),fAlpha)),
                               (sal_uInt8)(basegfx::tools::lerp(rColors[nIndex].GetBlue(),rColors[nIndex+1].GetBlue(),fAlpha)) ));

#if defined(VERBOSE) && OSL_DEBUG_LEVEL > 0        
                    if( i && !(i % 10) )
                        rOutDev.SetFillColor( COL_RED );
#endif

                    // scale and render polygon. Note that here, we
                    // calculate the inner polygon, which is actually the
                    // start of the _next_ color strip. Thus, i+1

                    for( p=0; p<nNumPoints; ++p )
                    {
                        const ::basegfx::B2DPoint& rOuterPoint( aOuterPoly.getB2DPoint(p) );
                        const ::basegfx::B2DPoint& rInnerPoint( aInnerPoly.getB2DPoint(p) );

                        aTempPoly[(sal_uInt16)p] = ::Point( 
                            basegfx::fround( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ),
                            basegfx::fround( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) );
                    }

                    // close polygon explicitely
                    aTempPoly[(sal_uInt16)p] = aTempPoly[0];

                    // swap inner and outer polygon
                    aTempPolyPoly.Replace( aTempPolyPoly.GetObject( 1 ), 0 );

                    if( i+1<nStepCount )
                    {
                        // assign new inner polygon. Note that with this
                        // formulation, the internal pimpl objects for both
                        // temp polygons and the polypolygon remain identical,
                        // minimizing heap accesses (only a Polygon wrapper
                        // object is freed and deleted twice during this swap).
                        aTempPolyPoly.Replace( aTempPoly, 1 );
                    }
                    else
                    {
                        // last, i.e. inner strip. Now, the inner polygon
                        // has zero area anyway, and to not leave holes in
                        // the gradient, finally render a simple polygon:
                        aTempPolyPoly.Remove( 1 );
                    }

                    rOutDev.DrawPolyPolygon( aTempPolyPoly );
                }
            }
        }

        void doGradientFill( OutputDevice&                                  rOutDev,
                             const ::canvas::ParametricPolyPolygon::Values&	rValues,
                             const std::vector< ::Color >&                  rColors,
                             const ::basegfx::B2DHomMatrix&                 rTextureTransform,
                             const ::Rectangle&                             rBounds,
                             unsigned int                                   nStepCount,
                             bool                                           bFillNonOverlapping )
        {
            switch( rValues.meType )
            {
                case ::canvas::ParametricPolyPolygon::GRADIENT_LINEAR:
                    fillLinearGradient( rOutDev,
                                        rTextureTransform,
                                        rBounds,
                                        nStepCount,
                                        rValues,
                                        rColors );
                    break;
               
                case ::canvas::ParametricPolyPolygon::GRADIENT_ELLIPTICAL:
                    // FALLTHROUGH intended
                case ::canvas::ParametricPolyPolygon::GRADIENT_RECTANGULAR:
                    fillPolygonalGradient( rOutDev,
                                           rTextureTransform,
                                           rBounds,
                                           nStepCount,
                                           bFillNonOverlapping,
                                           rValues,
                                           rColors );
                    break;

                default:
                    ENSURE_OR_THROW( false,
                                      "CanvasHelper::doGradientFill(): Unexpected case" );
            }
        }

        int numColorSteps( const ::Color& rColor1, const ::Color& rColor2 )
        {
            return ::std::max( 
                labs( rColor1.GetRed() - rColor2.GetRed() ),
                ::std::max(                    
                    labs( rColor1.GetGreen() - rColor2.GetGreen() ),
                    labs( rColor1.GetBlue()  - rColor2.GetBlue() ) ) );
        }

        bool gradientFill( OutputDevice&                                   rOutDev,
                           OutputDevice*                                   p2ndOutDev,
                           const ::canvas::ParametricPolyPolygon::Values&  rValues,
                           const std::vector< ::Color >&                   rColors,
                           const PolyPolygon&                              rPoly,
                           const rendering::ViewState&                     viewState, 
                           const rendering::RenderState&                   renderState,
                           const rendering::Texture&                       texture,
                           int                                             nTransparency )
        {
            (void)nTransparency;

            // TODO(T2): It is maybe necessary to lock here, should
            // maGradientPoly someday cease to be const. But then, beware of
            // deadlocks, canvashelper calls this method with locked own
            // mutex.

            // calc step size
            // --------------
            int nColorSteps = 0;
            for( size_t i=0; i<rColors.size()-1; ++i )
                nColorSteps += numColorSteps(rColors[i],rColors[i+1]);

            ::basegfx::B2DHomMatrix aTotalTransform;
            const int nStepCount=
                ::canvas::tools::calcGradientStepCount(aTotalTransform,
                                                       viewState,
                                                       renderState,
                                                       texture,
                                                       nColorSteps);

            rOutDev.SetLineColor(); 

            // determine maximal bound rect of texture-filled
            // polygon
            const ::Rectangle aPolygonDeviceRectOrig( 
                rPoly.GetBoundRect() );

            if( tools::isRectangle( rPoly ) )
            {
                // use optimized output path
                // -------------------------

                // this distinction really looks like a
                // micro-optimisation, but in fact greatly speeds up
                // especially complex gradients. That's because when using
                // clipping, we can output polygons instead of
                // poly-polygons, and don't have to output the gradient
                // twice for XOR

                rOutDev.Push( PUSH_CLIPREGION );
                rOutDev.IntersectClipRegion( aPolygonDeviceRectOrig );
                doGradientFill( rOutDev,
                                rValues,
                                rColors,
                                aTotalTransform,
                                aPolygonDeviceRectOrig,
                                nStepCount,
                                false );
                rOutDev.Pop();

                if( p2ndOutDev )
                {
                    p2ndOutDev->Push( PUSH_CLIPREGION );
                    p2ndOutDev->IntersectClipRegion( aPolygonDeviceRectOrig );
                    doGradientFill( *p2ndOutDev,
                                    rValues,
                                    rColors,
                                    aTotalTransform,
                                    aPolygonDeviceRectOrig,
                                    nStepCount,
                                    false );
                    p2ndOutDev->Pop();
                }
            }
            else
#if defined(QUARTZ) // TODO: other ports should avoid the XOR-trick too (implementation vs. interface!)
            {
                const Region aPolyClipRegion( rPoly );

                rOutDev.Push( PUSH_CLIPREGION );
                rOutDev.SetClipRegion( aPolyClipRegion );

                doGradientFill( rOutDev,
                                rValues,
                                rColors,
                                aTotalTransform,
                                aPolygonDeviceRectOrig,
                                nStepCount,
                                false );
                rOutDev.Pop();

                if( p2ndOutDev )
                {
                    p2ndOutDev->Push( PUSH_CLIPREGION );
                    p2ndOutDev->SetClipRegion( aPolyClipRegion );
                    doGradientFill( *p2ndOutDev,
                                    rValues,
                                    rColors,
                                    aTotalTransform,
                                    aPolygonDeviceRectOrig,
                                    nStepCount,
                                    false );
                    p2ndOutDev->Pop();
                }
            }
#else // TODO: remove once doing the XOR-trick in the canvas-layer becomes redundant
            {
                // output gradient the hard way: XORing out the polygon
                rOutDev.Push( PUSH_RASTEROP );
                rOutDev.SetRasterOp( ROP_XOR );
                doGradientFill( rOutDev,
                                rValues,
                                rColors,
                                aTotalTransform,
                                aPolygonDeviceRectOrig,
                                nStepCount,
                                true );
                rOutDev.SetFillColor( COL_BLACK );
                rOutDev.SetRasterOp( ROP_0 );
                rOutDev.DrawPolyPolygon( rPoly );
                rOutDev.SetRasterOp( ROP_XOR );
                doGradientFill( rOutDev,
                                rValues,
                                rColors,
                                aTotalTransform,
                                aPolygonDeviceRectOrig,
                                nStepCount,
                                true );
                rOutDev.Pop();

                if( p2ndOutDev )
                {
                    p2ndOutDev->Push( PUSH_RASTEROP );
                    p2ndOutDev->SetRasterOp( ROP_XOR );
                    doGradientFill( *p2ndOutDev,
                                    rValues,
                                    rColors,
                                    aTotalTransform,
                                    aPolygonDeviceRectOrig,
                                    nStepCount,
                                    true );
                    p2ndOutDev->SetFillColor( COL_BLACK );
                    p2ndOutDev->SetRasterOp( ROP_0 );
                    p2ndOutDev->DrawPolyPolygon( rPoly );
                    p2ndOutDev->SetRasterOp( ROP_XOR );
                    doGradientFill( *p2ndOutDev,
                                    rValues,
                                    rColors,
                                    aTotalTransform,
                                    aPolygonDeviceRectOrig,
                                    nStepCount,
                                    true );
                    p2ndOutDev->Pop();
                }
            }
#endif // complex-clipping vs. XOR-trick

#if 0 //defined(VERBOSE) && OSL_DEBUG_LEVEL > 0        
            {
                ::basegfx::B2DRectangle aRect(0.0, 0.0, 1.0, 1.0);
                ::basegfx::B2DRectangle aTextureDeviceRect;
                ::basegfx::B2DHomMatrix aTextureTransform;
                ::canvas::tools::calcTransformedRectBounds( aTextureDeviceRect, 
                                                            aRect, 
                                                            aTextureTransform );
                rOutDev.SetLineColor( COL_RED ); 
                rOutDev.SetFillColor();
                rOutDev.DrawRect( ::vcl::unotools::rectangleFromB2DRectangle( aTextureDeviceRect ) );

                rOutDev.SetLineColor( COL_BLUE ); 
                ::Polygon aPoly1( 
                    ::vcl::unotools::rectangleFromB2DRectangle( aRect ));
                ::basegfx::B2DPolygon aPoly2( aPoly1.getB2DPolygon() );
                aPoly2.transform( aTextureTransform );
                ::Polygon aPoly3( aPoly2 );
                rOutDev.DrawPolygon( aPoly3 );
            }
#endif

            return true;
        }
    }

    uno::Reference< rendering::XCachedPrimitive > CanvasHelper::fillTexturedPolyPolygon( const rendering::XCanvas* 							pCanvas, 
                                                                                         const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
                                                                                         const rendering::ViewState& 						viewState,
                                                                                         const rendering::RenderState& 						renderState,
                                                                                         const uno::Sequence< rendering::Texture >& 		textures )
    {
        ENSURE_ARG_OR_THROW( xPolyPolygon.is(),
                         "CanvasHelper::fillPolyPolygon(): polygon is NULL");
        ENSURE_ARG_OR_THROW( textures.getLength(), 
                         "CanvasHelper::fillTexturedPolyPolygon: empty texture sequence");

        if( mpOutDev )
        {
            tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev );

            const int nTransparency( setupOutDevState( viewState, renderState, IGNORE_COLOR ) );
            PolyPolygon aPolyPoly( tools::mapPolyPolygon( 
                                       ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon),
                                       viewState, renderState ) );

            // TODO(F1): Multi-texturing
            if( textures[0].Gradient.is() )
            {
                // try to cast XParametricPolyPolygon2D reference to
                // our implementation class.
                ::canvas::ParametricPolyPolygon* pGradient = 
                      dynamic_cast< ::canvas::ParametricPolyPolygon* >( textures[0].Gradient.get() );

                if( pGradient && pGradient->getValues().maColors.getLength() )
                {
                    // copy state from Gradient polypoly locally
                    // (given object might change!)
                    const ::canvas::ParametricPolyPolygon::Values& rValues(
                        pGradient->getValues() );

                    if( rValues.maColors.getLength() < 2 )
                    {
                        rendering::RenderState aTempState=renderState;
                        aTempState.DeviceColor = rValues.maColors[0];
                        fillPolyPolygon(pCanvas, xPolyPolygon, viewState, aTempState);
                    }
                    else
                    {
                        std::vector< ::Color > aColors(rValues.maColors.getLength());
                        std::transform(&rValues.maColors[0],
                                       &rValues.maColors[0]+rValues.maColors.getLength(),
                                       aColors.begin(),
                                       boost::bind(
                                           &vcl::unotools::stdColorSpaceSequenceToColor,
                                           _1));

                        // TODO(E1): Return value
                        // TODO(F1): FillRule
                        gradientFill( mpOutDev->getOutDev(),
                                      mp2ndOutDev.get() ? &mp2ndOutDev->getOutDev() : (OutputDevice*)NULL,
                                      rValues,
                                      aColors,
                                      aPolyPoly,
                                      viewState,
                                      renderState,
                                      textures[0],
                                      nTransparency );
                    }
                }
                else
                {
                    // TODO(F1): The generic case is missing here
                    ENSURE_OR_THROW( false,
                                      "CanvasHelper::fillTexturedPolyPolygon(): unknown parametric polygon encountered" );
                }
            }
            else if( textures[0].Bitmap.is() )
            {
                const geometry::IntegerSize2D aBmpSize( textures[0].Bitmap->getSize() );
                
                ENSURE_ARG_OR_THROW( aBmpSize.Width != 0 &&
                                 aBmpSize.Height != 0,
                                 "CanvasHelper::fillTexturedPolyPolygon(): zero-sized texture bitmap" );

                // determine maximal bound rect of texture-filled
                // polygon
                const ::Rectangle aPolygonDeviceRect( 
                    aPolyPoly.GetBoundRect() );


                // first of all, determine whether we have a
                // drawBitmap() in disguise
                // =========================================

                const bool bRectangularPolygon( tools::isRectangle( aPolyPoly ) );

                ::basegfx::B2DHomMatrix aTotalTransform;
                ::canvas::tools::mergeViewAndRenderTransform(aTotalTransform,
                                                             viewState,
                                                             renderState);
                ::basegfx::B2DHomMatrix aTextureTransform;
                ::basegfx::unotools::homMatrixFromAffineMatrix( aTextureTransform, 
                                                                textures[0].AffineTransform );
                
                aTotalTransform *= aTextureTransform;

                const ::basegfx::B2DRectangle aRect(0.0, 0.0, 1.0, 1.0);
                ::basegfx::B2DRectangle aTextureDeviceRect;
                ::canvas::tools::calcTransformedRectBounds( aTextureDeviceRect, 
                                                            aRect, 
                                                            aTotalTransform );

                const ::Rectangle aIntegerTextureDeviceRect( 
                    ::vcl::unotools::rectangleFromB2DRectangle( aTextureDeviceRect ) );

                if( bRectangularPolygon &&
                    aIntegerTextureDeviceRect == aPolygonDeviceRect )
                {
                    rendering::RenderState aLocalState( renderState );
                    ::canvas::tools::appendToRenderState(aLocalState,
                                                         aTextureTransform);
                    ::basegfx::B2DHomMatrix aScaleCorrection;
                    aScaleCorrection.scale( 1.0/aBmpSize.Width,
                                            1.0/aBmpSize.Height );
                    ::canvas::tools::appendToRenderState(aLocalState,
                                                         aScaleCorrection);

                    // need alpha modulation?
                    if( !::rtl::math::approxEqual( textures[0].Alpha,
                                                   1.0 ) )
                    {
                        // setup alpha modulation values
                        aLocalState.DeviceColor.realloc(4);
                        double* pColor = aLocalState.DeviceColor.getArray();
                        pColor[0] =
                        pColor[1] =
                        pColor[2] = 0.0;
                        pColor[3] = textures[0].Alpha;

                        return drawBitmapModulated( pCanvas, 
                                                    textures[0].Bitmap,
                                                    viewState,
                                                    aLocalState );
                    }
                    else
                    {
                        return drawBitmap( pCanvas, 
                                           textures[0].Bitmap,
                                           viewState,
                                           aLocalState );
                    }
                }
                else
                {
                    // No easy mapping to drawBitmap() - calculate
                    // texturing parameters
                    // ===========================================

                    BitmapEx aBmpEx( tools::bitmapExFromXBitmap( textures[0].Bitmap ) );

                    // scale down bitmap to [0,1]x[0,1] rect, as required
                    // from the XCanvas interface.
                    ::basegfx::B2DHomMatrix aScaling;
                    ::basegfx::B2DHomMatrix aPureTotalTransform; // pure view*render*texture transform
                    aScaling.scale( 1.0/aBmpSize.Width,
                                    1.0/aBmpSize.Height );

                    aTotalTransform = aTextureTransform * aScaling;
                    aPureTotalTransform = aTextureTransform;

                    // combine with view and render transform
                    ::basegfx::B2DHomMatrix aMatrix;
                    ::canvas::tools::mergeViewAndRenderTransform(aMatrix, viewState, renderState);
                    
                    // combine all three transformations into one
                    // global texture-to-device-space transformation
                    aTotalTransform *= aMatrix;
                    aPureTotalTransform *= aMatrix;

                    // analyze transformation, and setup an
                    // appropriate GraphicObject
                    ::basegfx::B2DVector aScale;
                    ::basegfx::B2DPoint  aOutputPos;
                    double				 nRotate;
                    double				 nShearX;
                    aTotalTransform.decompose( aScale, aOutputPos, nRotate, nShearX );
                
                    GraphicAttr 			aGrfAttr;
                    GraphicObjectSharedPtr 	pGrfObj;

                    if( ::basegfx::fTools::equalZero( nShearX ) )
                    {
                        // no shear, GraphicObject is enough (the
                        // GraphicObject only supports scaling, rotation
                        // and translation)

                        // setup GraphicAttr
                        aGrfAttr.SetMirrorFlags( 
                            ( aScale.getX() < 0.0 ? BMP_MIRROR_HORZ : 0 ) | 
                            ( aScale.getY() < 0.0 ? BMP_MIRROR_VERT : 0 ) );
                        aGrfAttr.SetRotation( static_cast< sal_uInt16 >(::basegfx::fround( nRotate*10.0 )) );

                        pGrfObj.reset( new GraphicObject( aBmpEx ) );
                    }
                    else
                    {
                        // complex transformation, use generic affine bitmap
                        // transformation
                        aBmpEx = tools::transformBitmap( aBmpEx,
                                                         aTotalTransform,
                                                         uno::Sequence< double >(),
                                                         tools::MODULATE_NONE);

                        pGrfObj.reset( new GraphicObject( aBmpEx ) );

                        // clear scale values, generated bitmap already
                        // contains scaling
                        aScale.setX( 0.0 ); aScale.setY( 0.0 );
                    }


                    // render texture tiled into polygon
                    // =================================

                    // calc device space direction vectors. We employ
                    // the followin approach for tiled output: the
                    // texture bitmap is output in texture space
                    // x-major order, i.e. tile neighbors in texture
                    // space x direction are rendered back-to-back in
                    // device coordinate space (after the full device
                    // transformation). Thus, the aNextTile* vectors
                    // denote the output position updates in device
                    // space, to get from one tile to the next.
                    ::basegfx::B2DVector aNextTileX( 1.0, 0.0 );
                    ::basegfx::B2DVector aNextTileY( 0.0, 1.0 );
                    aNextTileX *= aPureTotalTransform;
                    aNextTileY *= aPureTotalTransform;

                    ::basegfx::B2DHomMatrix aInverseTextureTransform( aPureTotalTransform );

                    ENSURE_ARG_OR_THROW( aInverseTextureTransform.isInvertible(),
                                     "CanvasHelper::fillTexturedPolyPolygon(): singular texture matrix" );

                    aInverseTextureTransform.invert();

                    // calc bound rect of extended texture area in
                    // device coordinates. Therefore, we first calc
                    // the area of the polygon bound rect in texture
                    // space. To maintain texture phase, this bound
                    // rect is then extended to integer coordinates
                    // (extended, because shrinking might leave some
                    // inner polygon areas unfilled).
                    // Finally, the bound rect is transformed back to
                    // device coordinate space, were we determine the
                    // start point from it.
                    ::basegfx::B2DRectangle aTextureSpacePolygonRect;
                    ::canvas::tools::calcTransformedRectBounds( aTextureSpacePolygonRect, 
                                                                ::vcl::unotools::b2DRectangleFromRectangle(
                                                                    aPolygonDeviceRect ), 
                                                                aInverseTextureTransform );

                    // calc left, top of extended polygon rect in
                    // texture space, create one-texture instance rect
                    // from it (i.e. rect from start point extending
                    // 1.0 units to the right and 1.0 units to the
                    // bottom). Note that the rounding employed here
                    // is a bit subtle, since we need to round up/down
                    // as _soon_ as any fractional amount is
                    // encountered. This is to ensure that the full
                    // polygon area is filled with texture tiles.
                    const sal_Int32 nX1( ::canvas::tools::roundDown( aTextureSpacePolygonRect.getMinX() ) );
                    const sal_Int32 nY1( ::canvas::tools::roundDown( aTextureSpacePolygonRect.getMinY() ) );
                    const sal_Int32 nX2( ::canvas::tools::roundUp( aTextureSpacePolygonRect.getMaxX() ) );
                    const sal_Int32 nY2( ::canvas::tools::roundUp( aTextureSpacePolygonRect.getMaxY() ) );
                    const ::basegfx::B2DRectangle aSingleTextureRect(
                        nX1, nY1,
                        nX1 + 1.0,
                        nY1 + 1.0 );

                    // and convert back to device space
                    ::basegfx::B2DRectangle aSingleDeviceTextureRect;
                    ::canvas::tools::calcTransformedRectBounds( aSingleDeviceTextureRect, 
                                                                aSingleTextureRect, 
                                                                aPureTotalTransform );
                    
                    const ::Point aPtRepeat( ::vcl::unotools::pointFromB2DPoint( 
                                                 aSingleDeviceTextureRect.getMinimum() ) );
                    const ::Size  aSz( ::basegfx::fround( aScale.getX() * aBmpSize.Width ),
                                       ::basegfx::fround( aScale.getY() * aBmpSize.Height ) );
                    const ::Size  aIntegerNextTileX( ::vcl::unotools::sizeFromB2DSize(aNextTileX) );
                    const ::Size  aIntegerNextTileY( ::vcl::unotools::sizeFromB2DSize(aNextTileY) );

                    const ::Point aPt( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? 
                                       ::basegfx::fround( aOutputPos.getX() ) : aPtRepeat.X(),
                                       textures[0].RepeatModeY == rendering::TexturingMode::NONE ? 
                                       ::basegfx::fround( aOutputPos.getY() ) : aPtRepeat.Y() );
                    const sal_Int32 nTilesX( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? 
                                             1 : nX2 - nX1 );
                    const sal_Int32 nTilesY( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? 
                                             1 : nY2 - nY1 );
                    
                    OutputDevice& rOutDev( mpOutDev->getOutDev() );

                    if( bRectangularPolygon )
                    {
                        // use optimized output path
                        // -------------------------

                        // this distinction really looks like a
                        // micro-optimisation, but in fact greatly speeds up
                        // especially complex fills. That's because when using
                        // clipping, we can output polygons instead of
                        // poly-polygons, and don't have to output the gradient
                        // twice for XOR

                        // setup alpha modulation
                        if( !::rtl::math::approxEqual( textures[0].Alpha,
                                                       1.0 ) )
                        {
                            // TODO(F1): Note that the GraphicManager has
                            // a subtle difference in how it calculates
                            // the resulting alpha value: it's using the
                            // inverse alpha values (i.e. 'transparency'),
                            // and calculates transOrig + transModulate,
                            // instead of transOrig + transModulate -
                            // transOrig*transModulate (which would be
                            // equivalent to the origAlpha*modulateAlpha
                            // the DX canvas performs)
                            aGrfAttr.SetTransparency( 
                                static_cast< sal_uInt8 >( 
                                    ::basegfx::fround( 255.0*( 1.0 - textures[0].Alpha ) ) ) );
                        }

                        rOutDev.IntersectClipRegion( aPolygonDeviceRect );
                        textureFill( rOutDev,
                                     *pGrfObj,
                                     aPt,
                                     aIntegerNextTileX,
                                     aIntegerNextTileY,
                                     nTilesX,
                                     nTilesY,
                                     aSz,
                                     aGrfAttr );

                        if( mp2ndOutDev )
                        {
                            OutputDevice& r2ndOutDev( mp2ndOutDev->getOutDev() );
                            r2ndOutDev.IntersectClipRegion( aPolygonDeviceRect );
                            textureFill( r2ndOutDev,
                                         *pGrfObj,
                                         aPt,
                                         aIntegerNextTileX,
                                         aIntegerNextTileY,
                                         nTilesX,
                                         nTilesY,
                                         aSz,
                                         aGrfAttr );
                        }
                    }
                    else
                    {
                        // output texture the hard way: XORing out the
                        // polygon
                        // ===========================================

                        if( !::rtl::math::approxEqual( textures[0].Alpha,
                                                       1.0 ) )
                        {
                            // uh-oh. alpha blending is required,
                            // cannot do direct XOR, but have to
                            // prepare the filled polygon within a
                            // VDev
                            VirtualDevice aVDev( rOutDev );
                            aVDev.SetOutputSizePixel( aPolygonDeviceRect.GetSize() );

                            // shift output to origin of VDev
                            const ::Point aOutPos( aPt - aPolygonDeviceRect.TopLeft() );
                            aPolyPoly.Translate( ::Point( -aPolygonDeviceRect.Left(),
                                                          -aPolygonDeviceRect.Top() ) );

                            const Region aPolyClipRegion( aPolyPoly );

                            aVDev.SetClipRegion( aPolyClipRegion );
                            textureFill( aVDev,
                                         *pGrfObj,
                                         aOutPos,
                                         aIntegerNextTileX,
                                         aIntegerNextTileY,
                                         nTilesX,
                                         nTilesY,
                                         aSz,
                                         aGrfAttr );

                            // output VDev content alpha-blended to
                            // target position.
                            const ::Point aEmptyPoint;
                            Bitmap aContentBmp( 
                                aVDev.GetBitmap( aEmptyPoint, 
                                                 aVDev.GetOutputSizePixel() ) );

                            sal_uInt8 nCol( static_cast< sal_uInt8 >( 
                                           ::basegfx::fround( 255.0*( 1.0 - textures[0].Alpha ) ) ) );
                            AlphaMask aAlpha( aVDev.GetOutputSizePixel(),
                                              &nCol );

                            BitmapEx aOutputBmpEx( aContentBmp, aAlpha );
                            rOutDev.DrawBitmapEx( aPolygonDeviceRect.TopLeft(),
                                                  aOutputBmpEx );

                            if( mp2ndOutDev )
                                mp2ndOutDev->getOutDev().DrawBitmapEx( aPolygonDeviceRect.TopLeft(),
                                                                       aOutputBmpEx );
                        }
                        else
                        {
                            const Region aPolyClipRegion( aPolyPoly );

                            rOutDev.Push( PUSH_CLIPREGION );
                            rOutDev.SetClipRegion( aPolyClipRegion );

                            textureFill( rOutDev,
                                         *pGrfObj,
                                         aPt,
                                         aIntegerNextTileX,
                                         aIntegerNextTileY,
                                         nTilesX,
                                         nTilesY,
                                         aSz,
                                         aGrfAttr );
                            rOutDev.Pop();

                            if( mp2ndOutDev )
                            {
                                OutputDevice& r2ndOutDev( mp2ndOutDev->getOutDev() );
                                r2ndOutDev.Push( PUSH_CLIPREGION );

                                r2ndOutDev.SetClipRegion( aPolyClipRegion );
                                textureFill( r2ndOutDev,
                                             *pGrfObj,
                                             aPt,
                                             aIntegerNextTileX,
                                             aIntegerNextTileY,
                                             nTilesX,
                                             nTilesY,
                                             aSz,
                                             aGrfAttr );
                                r2ndOutDev.Pop();
                            }
                        }
                    }
                }
            }
        }

        // TODO(P1): Provide caching here.
        return uno::Reference< rendering::XCachedPrimitive >(NULL);
    }

}
