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

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

#include <math.h>

#include <rtl/logfile.hxx>
#include <rtl/math.hxx>

#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/rendering/XIntegerBitmap.hpp>
#include <com/sun/star/rendering/PanoseLetterForm.hpp>
#include <com/sun/star/awt/FontSlant.hpp>

#include <cppuhelper/exc_hlp.hxx>
#include <comphelper/anytostring.hxx>

#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>

#include <canvas/verbosetrace.hxx>
#include <canvas/canvastools.hxx>
#include <cppcanvas/vclfactory.hxx>
#include <cppcanvas/basegfxfactory.hxx>

#include "viewshape.hxx"
#include "tools.hxx"

#include <boost/bind.hpp>


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

namespace slideshow
{
    namespace internal
    {

        // TODO(F2): Provide sensible setup for mtf-related attributes (fill mode,
        // char rotation etc.). Do that via mtf argument at this object

        bool ViewShape::prefetch( RendererCacheEntry&					io_rCacheEntry,
                                  const ::cppcanvas::CanvasSharedPtr&	rDestinationCanvas,
                                  const GDIMetaFileSharedPtr&			rMtf,
                                  const ShapeAttributeLayerSharedPtr&	rAttr ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::prefetch()" );
            ENSURE_OR_RETURN_FALSE( rMtf,
                               "ViewShape::prefetch(): no valid metafile!" );

            if( rMtf != io_rCacheEntry.mpMtf ||
                rDestinationCanvas != io_rCacheEntry.getDestinationCanvas() )
            {
                // buffered renderer invalid, re-create
                ::cppcanvas::Renderer::Parameters aParms;

                // rendering attribute override parameter struct.  For
                // every valid attribute, the corresponding struct
                // member is filled, which in the metafile renderer
                // forces rendering with the given attribute.
                if( rAttr )
                {
                    if( rAttr->isFillColorValid() )
                    {
                        // convert RGBColor to RGBA32 integer. Note
                        // that getIntegerColor() also truncates
                        // out-of-range values appropriately
                        aParms.maFillColor =
                            rAttr->getFillColor().getIntegerColor();
                    }
                    if( rAttr->isLineColorValid() )
                    {
                        // convert RGBColor to RGBA32 integer. Note
                        // that getIntegerColor() also truncates
                        // out-of-range values appropriately
                        aParms.maLineColor =
                            rAttr->getLineColor().getIntegerColor();
                    }
                    if( rAttr->isCharColorValid() )
                    {
                        // convert RGBColor to RGBA32 integer. Note
                        // that getIntegerColor() also truncates
                        // out-of-range values appropriately
                        aParms.maTextColor =
                            rAttr->getCharColor().getIntegerColor();
                    }
                    if( rAttr->isDimColorValid() )
                    {
                        // convert RGBColor to RGBA32 integer. Note
                        // that getIntegerColor() also truncates
                        // out-of-range values appropriately

                        // dim color overrides all other colors
                        aParms.maFillColor =
                        aParms.maLineColor =
                        aParms.maTextColor =
                            rAttr->getDimColor().getIntegerColor();
                    }
                    if( rAttr->isFontFamilyValid() )
                    {
                        aParms.maFontName =
                            rAttr->getFontFamily();
                    }
                    if( rAttr->isCharScaleValid() )
                    {
                        ::basegfx::B2DHomMatrix aMatrix;

                        // enlarge text by given scale factor. Do that
                        // with the middle of the shape as the center
                        // of scaling.
                        aMatrix.translate( -0.5, -0.5 );
                        aMatrix.scale( rAttr->getCharScale(),
                                       rAttr->getCharScale() );
                        aMatrix.translate( 0.5, 0.5 );

                        aParms.maTextTransformation = aMatrix;
                    }
                    if( rAttr->isCharWeightValid() )
                    {
                        aParms.maFontWeight =
                            static_cast< sal_Int8 >(
                                ::basegfx::fround(
                                    ::std::max( 0.0,
                                                ::std::min( 11.0,
                                                            rAttr->getCharWeight() / 20.0 ) ) ) );
                    }
                    if( rAttr->isCharPostureValid() )
                    {
                        aParms.maFontLetterForm =
                            rAttr->getCharPosture() == awt::FontSlant_NONE ?
                            rendering::PanoseLetterForm::ANYTHING :
                            rendering::PanoseLetterForm::OBLIQUE_CONTACT;
                    }
                    if( rAttr->isUnderlineModeValid() )
                    {
                        aParms.maFontUnderline =
                            rAttr->getUnderlineMode();
                    }
                }

                io_rCacheEntry.mpRenderer = ::cppcanvas::VCLFactory::getInstance().createRenderer( rDestinationCanvas,
                                                                                                   *rMtf.get(),
                                                                                                   aParms );

                io_rCacheEntry.mpMtf      		   = rMtf;
                io_rCacheEntry.mpDestinationCanvas = rDestinationCanvas;

                // also invalidate alpha compositing bitmap (created
                // new renderer, which possibly generates different
                // output). Do NOT invalidate, if we're incidentally
                // rendering INTO it.
                if( rDestinationCanvas != io_rCacheEntry.mpLastBitmapCanvas )
                {
                    io_rCacheEntry.mpLastBitmapCanvas.reset();
                    io_rCacheEntry.mpLastBitmap.reset();
                }
            }

            return (io_rCacheEntry.mpRenderer.get() != NULL);
        }

        bool ViewShape::draw( const ::cppcanvas::CanvasSharedPtr&	rDestinationCanvas,
                              const GDIMetaFileSharedPtr&			rMtf,
                              const ShapeAttributeLayerSharedPtr&	rAttr,
                              const ::basegfx::B2DHomMatrix&		rTransform,
                              const ::basegfx::B2DPolyPolygon*		pClip,
                              const VectorOfDocTreeNodes&			rSubsets ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::draw()" );

            ::cppcanvas::RendererSharedPtr pRenderer(
                getRenderer( rDestinationCanvas, rMtf, rAttr ) );

            ENSURE_OR_RETURN_FALSE( pRenderer, "ViewShape::draw(): Invalid renderer" );

            pRenderer->setTransformation( rTransform );
#if defined(VERBOSE) && OSL_DEBUG_LEVEL > 0
            rendering::RenderState aRenderState;
            ::canvas::tools::initRenderState(aRenderState);
            ::canvas::tools::setRenderStateTransform(aRenderState,
                                                     rTransform);
            aRenderState.DeviceColor.realloc(4);
            aRenderState.DeviceColor[0] = 1.0;
            aRenderState.DeviceColor[1] = 0.0;
            aRenderState.DeviceColor[2] = 0.0;
            aRenderState.DeviceColor[3] = 1.0;

            try
            {
                rDestinationCanvas->getUNOCanvas()->drawLine( geometry::RealPoint2D(0.0,0.0),
                                                              geometry::RealPoint2D(1.0,1.0),
                                                              rDestinationCanvas->getViewState(),
                                                              aRenderState );
                rDestinationCanvas->getUNOCanvas()->drawLine( geometry::RealPoint2D(1.0,0.0),
                                                              geometry::RealPoint2D(0.0,1.0),
                                                              rDestinationCanvas->getViewState(),
                                                              aRenderState );
            }
            catch( uno::Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
#endif
            if( pClip )
                pRenderer->setClip( *pClip );
            else
                pRenderer->setClip();

            if( rSubsets.empty() )
            {
                return pRenderer->draw();
            }
            else
            {
                // render subsets of whole metafile
                // --------------------------------

                bool bRet(true);
                VectorOfDocTreeNodes::const_iterator 		aIter( rSubsets.begin() );
                const VectorOfDocTreeNodes::const_iterator	aEnd ( rSubsets.end() );
                while( aIter != aEnd )
                {
                    if( !pRenderer->drawSubset( aIter->getStartIndex(),
                                                aIter->getEndIndex() ) )
                        bRet = false;

                    ++aIter;
                }

                return bRet;
            }
        }

        namespace
        {
            /// Convert untransformed shape update area to device pixel.
            ::basegfx::B2DRectangle shapeArea2AreaPixel( const ::basegfx::B2DHomMatrix&	rCanvasTransformation,
                                                         const ::basegfx::B2DRectangle&	rUntransformedArea		)
            {
                // convert area to pixel, and add anti-aliasing border

                // TODO(P1): Should the view transform some
                // day contain rotation/shear, transforming
                // the original bounds with the total
                // transformation might result in smaller
                // overall bounds.

                ::basegfx::B2DRectangle aBoundsPixel;
                ::canvas::tools::calcTransformedRectBounds( aBoundsPixel,
                                                            rUntransformedArea,
                                                            rCanvasTransformation );

                // add antialiasing border around the shape (AA
                // touches pixel _outside_ the nominal bound rect)
                aBoundsPixel.grow( ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE );

                return aBoundsPixel;
            }

            /// Convert shape unit rect to device pixel.
            ::basegfx::B2DRectangle calcUpdateAreaPixel( const ::basegfx::B2DRectangle& 		rUnitBounds,
                                                         const ::basegfx::B2DHomMatrix& 		rShapeTransformation,
                                                         const ::basegfx::B2DHomMatrix&			rCanvasTransformation,
                                                         const ShapeAttributeLayerSharedPtr&	pAttr					)
            {
                // calc update area for whole shape (including
                // character scaling)
                return shapeArea2AreaPixel( rCanvasTransformation,
                                            getShapeUpdateArea( rUnitBounds,
                                                                rShapeTransformation,
                                                                pAttr ) );
            }
        }

        bool ViewShape::renderSprite( const ViewLayerSharedPtr&             rViewLayer,
                                      const GDIMetaFileSharedPtr&			rMtf,
                                      const ::basegfx::B2DRectangle&		rOrigBounds,
                                      const ::basegfx::B2DRectangle&		rBounds,
                                      const ::basegfx::B2DRectangle&		rUnitBounds,
                                      int									nUpdateFlags,
                                      const ShapeAttributeLayerSharedPtr&	pAttr,
                                      const VectorOfDocTreeNodes&			rSubsets,
                                      double                                nPrio,
                                      bool 									bIsVisible ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::renderSprite()" );

            // TODO(P1): For multiple views, it might pay off to reorg Shape and ViewShape,
            // in that all the common setup steps here are refactored to Shape (would then
            // have to be performed only _once_ per Shape paint).

            if( !bIsVisible ||
                rUnitBounds.isEmpty() ||
                rOrigBounds.isEmpty() ||
                rBounds.isEmpty() )
            {
                // shape is invisible or has zero size, no need to
                // update anything.
                if( mpSprite )
                    mpSprite->hide();

                return true;
            }


            // calc sprite position, size and content transformation
            // =====================================================

            // the shape transformation for a sprite is always a
            // simple scale-up to the nominal shape size. Everything
            // else is handled via the sprite transformation
            ::basegfx::B2DHomMatrix aNonTranslationalShapeTransformation;
            aNonTranslationalShapeTransformation.scale( rOrigBounds.getWidth(),
                                                        rOrigBounds.getHeight() );
            ::basegfx::B2DHomMatrix aShapeTransformation( aNonTranslationalShapeTransformation );
            aShapeTransformation.translate( rOrigBounds.getMinX(),
                                            rOrigBounds.getMinY() );

            const ::basegfx::B2DHomMatrix& rCanvasTransform(
                rViewLayer->getSpriteTransformation() );

            // area actually needed for the sprite
            const ::basegfx::B2DRectangle& rSpriteBoundsPixel(
                calcUpdateAreaPixel( rUnitBounds,
                                     aShapeTransformation,
                                     rCanvasTransform,
                                     pAttr ) );

            // actual area for the shape (without subsetting, but
            // including char scaling)
            const ::basegfx::B2DRectangle& rShapeBoundsPixel(
                calcUpdateAreaPixel( ::basegfx::B2DRectangle(0.0,0.0,1.0,1.0),
                                     aShapeTransformation,
                                     rCanvasTransform,
                                     pAttr ) );

            // nominal area for the shape (without subsetting, without
            // char scaling). NOTE: to cancel the shape translation,
            // contained in rSpriteBoundsPixel, this is _without_ any
            // translational component (fixed along with #121921#).
            ::basegfx::B2DRectangle		   aLogShapeBounds;
            const ::basegfx::B2DRectangle& rNominalShapeBoundsPixel(
                shapeArea2AreaPixel( rCanvasTransform,
                                     ::canvas::tools::calcTransformedRectBounds(
                                         aLogShapeBounds,
                                         ::basegfx::B2DRectangle(0.0,0.0,1.0,1.0),
                                         aNonTranslationalShapeTransformation ) ) );

            // create (or resize) sprite with sprite's pixel size, if
            // not done already
            const ::basegfx::B2DSize& rSpriteSizePixel(rSpriteBoundsPixel.getRange());
            if( !mpSprite )
            {
                mpSprite.reset(
                    new AnimatedSprite( mpViewLayer,
                                        rSpriteSizePixel,
                                        nPrio ));
            }
            else
            {
                // TODO(F2): when the sprite _actually_ gets resized,
                // content needs a repaint!
                mpSprite->resize( rSpriteSizePixel );
            }

            ENSURE_OR_RETURN_FALSE( mpSprite, "ViewShape::renderSprite(): No sprite" );

            VERBOSE_TRACE( "ViewShape::renderSprite(): Rendering sprite 0x%X",
                           mpSprite.get() );


            // always show the sprite (might have been hidden before)
            mpSprite->show();

            // determine center of sprite output position in pixel
            // (assumption here: all shape transformations have the
            // shape center as the pivot point). From that, subtract
            // distance of rSpriteBoundsPixel's left, top edge from
            // rShapeBoundsPixel's center. This moves the sprite at
            // the appropriate output position within the virtual
            // rShapeBoundsPixel area.
            ::basegfx::B2DPoint aSpritePosPixel( rBounds.getCenter() );
            aSpritePosPixel *= rCanvasTransform;
            aSpritePosPixel -= rShapeBoundsPixel.getCenter() - rSpriteBoundsPixel.getMinimum();

            // the difference between rShapeBoundsPixel and
            // rSpriteBoundsPixel upper, left corner is: the offset we
            // have to move sprite output to the right, top (to make
            // the desired subset content visible at all)
            const ::basegfx::B2DSize& rSpriteCorrectionOffset(
                rSpriteBoundsPixel.getMinimum() - rNominalShapeBoundsPixel.getMinimum() );

            // offset added top, left for anti-aliasing (otherwise,
            // shapes fully filling the sprite will have anti-aliased
            // pixel cut off)
            const ::basegfx::B2DSize aAAOffset(
                ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE,
                ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE );

            // set pixel output offset to sprite: we always leave
            // ANTIALIASING_EXTRA_SIZE room atop and to the left, and,
            // what's more, for subsetted shapes, we _have_ to cancel
            // the effect of the shape renderer outputting the subset
            // at its absolute position inside the shape, instead of
            // at the origin.
            // NOTE: As for now, sprites are always positioned on
            // integer pixel positions on screen, have to round to
            // nearest integer here, too (fixed along with #121921#)
            mpSprite->setPixelOffset(
                aAAOffset - ::basegfx::B2DSize(
                    ::basegfx::fround( rSpriteCorrectionOffset.getX() ),
                    ::basegfx::fround( rSpriteCorrectionOffset.getY() ) ) );

            // always set sprite position and transformation, since
            // they do not relate directly to the update flags
            // (e.g. sprite position changes when sprite size changes)
            mpSprite->movePixel( aSpritePosPixel );
            mpSprite->transform( getSpriteTransformation( rSpriteSizePixel,
                                                          rOrigBounds.getRange(),
                                                          pAttr ) );


            // process flags
            // =============

            bool bRedrawRequired( mbForceUpdate || (nUpdateFlags & FORCE) );

            if( mbForceUpdate || (nUpdateFlags & ALPHA) )
            {
                mpSprite->setAlpha( (pAttr && pAttr->isAlphaValid()) ?
                                    ::basegfx::clamp(pAttr->getAlpha(),
                                                     0.0,
                                                     1.0) :
                                    1.0 );
            }
            if( mbForceUpdate || (nUpdateFlags & CLIP) )
            {
                if( pAttr && pAttr->isClipValid() )
                {
                    ::basegfx::B2DPolyPolygon aClipPoly( pAttr->getClip() );

                    // extract linear part of canvas view transformation
                    // (linear means: without translational components)
                    ::basegfx::B2DHomMatrix aViewTransform(
                        mpViewLayer->getTransformation() );
                    aViewTransform.set( 0, 2, 0.0 );
                    aViewTransform.set( 1, 2, 0.0 );

                    // make the clip 2*ANTIALIASING_EXTRA_SIZE larger
                    // such that it's again centered over the sprite.
                    aViewTransform.scale(rSpriteSizePixel.getX()/
                                         (rSpriteSizePixel.getX()-2*::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE),
                                         rSpriteSizePixel.getY()/
                                         (rSpriteSizePixel.getY()-2*::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE));

                    // transform clip polygon from view to device
                    // coordinate space
                    aClipPoly.transform( aViewTransform );

                    mpSprite->clip( aClipPoly );
                }
                else
                    mpSprite->clip();
            }
            if( mbForceUpdate || (nUpdateFlags & CONTENT) )
            {
                bRedrawRequired = true;

                // TODO(P1): maybe provide some appearance change methods at
                // the Renderer interface

                // force the renderer to be regenerated below, for the
                // different attributes to take effect
                invalidateRenderer();
            }

            mbForceUpdate = false;

            if( !bRedrawRequired )
                return true;


            // sprite needs repaint - output to sprite canvas
            // ==============================================

            ::cppcanvas::CanvasSharedPtr pContentCanvas( mpSprite->getContentCanvas() );

            return draw( pContentCanvas,
                         rMtf,
                         pAttr,
                         aShapeTransformation,
                         NULL, // clipping is done via Sprite::clip()
                         rSubsets );
        }

        bool ViewShape::render( const ::cppcanvas::CanvasSharedPtr&	rDestinationCanvas,
                                const GDIMetaFileSharedPtr&			rMtf,
                                const ::basegfx::B2DRectangle&		rBounds,
                                const ::basegfx::B2DRectangle&		rUpdateBounds,
                                int									nUpdateFlags,
                                const ShapeAttributeLayerSharedPtr&	pAttr,
                                const VectorOfDocTreeNodes&			rSubsets,
                                bool 								bIsVisible ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::render()" );

            // TODO(P1): For multiple views, it might pay off to reorg Shape and ViewShape,
            // in that all the common setup steps here are refactored to Shape (would then
            // have to be performed only _once_ per Shape paint).

            if( !bIsVisible )
            {
                VERBOSE_TRACE( "ViewShape::render(): skipping shape %X", this );

                // shape is invisible, no need to update anything.
                return true;
            }

            // since we have no sprite here, _any_ update request
            // translates into a required redraw.
            bool bRedrawRequired( mbForceUpdate || nUpdateFlags != 0 );

            if( (nUpdateFlags & CONTENT) )
            {
                // TODO(P1): maybe provide some appearance change methods at
                // the Renderer interface

                // force the renderer to be regenerated below, for the
                // different attributes to take effect
                invalidateRenderer();
            }

            mbForceUpdate = false;

            if( !bRedrawRequired )
                return true;

            VERBOSE_TRACE( "ViewShape::render(): rendering shape %X at position (%f,%f)",
                           this,
                           rBounds.getMinX(),
                           rBounds.getMinY() );


            // shape needs repaint - setup all that's needed
            // ---------------------------------------------

            boost::optional<basegfx::B2DPolyPolygon> aClip;

            if( pAttr )
            {
                // setup clip poly
                if( pAttr->isClipValid() )
                    aClip.reset( pAttr->getClip() );

                // emulate global shape alpha by first rendering into
                // a temp bitmap, and then to screen (this would have
                // been much easier if we'd be currently a sprite -
                // see above)
                if( pAttr->isAlphaValid() )
                {
                    const double nAlpha( pAttr->getAlpha() );

                    if( !::basegfx::fTools::equalZero( nAlpha ) &&
                        !::rtl::math::approxEqual(nAlpha, 1.0) )
                    {
                        // render with global alpha - have to prepare
                        // a bitmap, and render that with modulated
                        // alpha
                        // -------------------------------------------

                        const ::basegfx::B2DHomMatrix aTransform(
                            getShapeTransformation( rBounds,
                                                    pAttr ) );

                        // TODO(P1): Should the view transform some
                        // day contain rotation/shear, transforming
                        // the original bounds with the total
                        // transformation might result in smaller
                        // overall bounds.

                        // determine output rect of _shape update
                        // area_ in device pixel
                        const ::basegfx::B2DHomMatrix aCanvasTransform(
                            rDestinationCanvas->getTransformation() );
                        ::basegfx::B2DRectangle aTmpRect;
                        ::canvas::tools::calcTransformedRectBounds( aTmpRect,
                                                                    rUpdateBounds,
                                                                    aCanvasTransform );

                        // pixel size of cache bitmap: round up to
                        // nearest int
                        const ::basegfx::B2ISize aBmpSize( static_cast<sal_Int32>( aTmpRect.getWidth() )+1,
                                                           static_cast<sal_Int32>( aTmpRect.getHeight() )+1 );

                        // try to fetch temporary surface for alpha
                        // compositing (to achieve the global alpha
                        // blend effect, have to first render shape as
                        // a whole, then blit that surface with global
                        // alpha to the destination)
                        const RendererCacheVector::iterator aCompositingSurface(
                            getCacheEntry( rDestinationCanvas ) );

                        if( !aCompositingSurface->mpLastBitmapCanvas ||
                            aCompositingSurface->mpLastBitmapCanvas->getSize() != aBmpSize )
                        {
                            // create a bitmap of appropriate size
                            ::cppcanvas::BitmapSharedPtr pBitmap(
                                ::cppcanvas::BaseGfxFactory::getInstance().createAlphaBitmap(
                                    rDestinationCanvas,
                                    aBmpSize ) );

                            ENSURE_OR_THROW(pBitmap,
                                             "ViewShape::render(): Could not create compositing surface");

                            aCompositingSurface->mpDestinationCanvas = rDestinationCanvas;
                            aCompositingSurface->mpLastBitmap		 = pBitmap;
                            aCompositingSurface->mpLastBitmapCanvas	 = pBitmap->getBitmapCanvas();
                        }

                        // buffer aCompositingSurface iterator content
                        // - said one might get invalidated during
                        // draw() below.
                        ::cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas(
                            aCompositingSurface->mpLastBitmapCanvas );

                        ::cppcanvas::BitmapSharedPtr pBitmap(
                            aCompositingSurface->mpLastBitmap);

                        // setup bitmap canvas transformation -
                        // which happens to be the destination
                        // canvas transformation without any
                        // translational components.
                        //
                        // But then, the render transformation as
                        // calculated by getShapeTransformation()
                        // above outputs the shape at its real
                        // destination position. Thus, we have to
                        // offset the output back to the origin,
                        // for which we simply plug in the
                        // negative position of the left, top edge
                        // of the shape's bound rect in device
                        // pixel into aLinearTransform below.
                        ::basegfx::B2DHomMatrix aAdjustedCanvasTransform( aCanvasTransform );
                        aAdjustedCanvasTransform.translate( -aTmpRect.getMinX(),
                                                            -aTmpRect.getMinY() );

                        pBitmapCanvas->setTransformation( aAdjustedCanvasTransform );

                        // TODO(P2): If no update flags, or only
                        // alpha_update is set, we can save us the
                        // rendering into the bitmap (uh, it's not
                        // _that_ easy - for a forced redraw,
                        // e.g. when ending an animation, we always
                        // get UPDATE_FORCE here).

                        // render into this bitmap
                        if( !draw( pBitmapCanvas,
                                   rMtf,
                                   pAttr,
                                   aTransform,
                                   !aClip ? NULL : &(*aClip),
                                   rSubsets ) )
                        {
                            return false;
                        }

                        // render bitmap to screen, with given global
                        // alpha. Since the bitmap already contains
                        // pixel-equivalent output, we have to use the
                        // inverse view transformation, adjusted with
                        // the final shape output position (note:
                        // cannot simply change the view
                        // transformation here, as that would affect a
                        // possibly set clip!)
                        ::basegfx::B2DHomMatrix aBitmapTransform( aCanvasTransform );
                        OSL_ENSURE( aBitmapTransform.isInvertible(),
                                    "ViewShape::render(): View transformation is singular!" );

                        aBitmapTransform.invert();

                        const basegfx::B2DHomMatrix aTranslation(basegfx::tools::createTranslateB2DHomMatrix(
                            aTmpRect.getMinX(), aTmpRect.getMinY()));

                        aBitmapTransform = aBitmapTransform * aTranslation;
                        pBitmap->setTransformation( aBitmapTransform );

                        // finally, render bitmap alpha-modulated
                        pBitmap->drawAlphaModulated( nAlpha );

                        return true;
                    }
                }
            }

            // retrieve shape transformation, _with_ shape translation
            // to actual page position.
            const ::basegfx::B2DHomMatrix aTransform(
                getShapeTransformation( rBounds,
                                        pAttr ) );

            return draw( rDestinationCanvas,
                         rMtf,
                         pAttr,
                         aTransform,
                         !aClip ? NULL : &(*aClip),
                         rSubsets );
        }


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

        ViewShape::ViewShape( const ViewLayerSharedPtr& rViewLayer ) :
            mpViewLayer( rViewLayer ),
            maRenderers(),
            mpSprite(),
            mbAnimationMode( false ),
            mbForceUpdate( true )
        {
            ENSURE_OR_THROW( mpViewLayer, "ViewShape::ViewShape(): Invalid View" );
        }

        ViewLayerSharedPtr ViewShape::getViewLayer() const
        {
            return mpViewLayer;
        }

        ViewShape::RendererCacheVector::iterator ViewShape::getCacheEntry( const ::cppcanvas::CanvasSharedPtr&	rDestinationCanvas ) const
        {
            // lookup destination canvas - is there already a renderer
            // created for that target?
            RendererCacheVector::iterator 		aIter;
            const RendererCacheVector::iterator aEnd( maRenderers.end() );

            // already there?
            if( (aIter=::std::find_if( maRenderers.begin(),
                                       aEnd,
                                       ::boost::bind(
                                           ::std::equal_to< ::cppcanvas::CanvasSharedPtr >(),
                                           ::boost::cref( rDestinationCanvas ),
                                           ::boost::bind(
                                               &RendererCacheEntry::getDestinationCanvas,
                                               _1 ) ) ) ) == aEnd )
            {
                if( maRenderers.size() >= MAX_RENDER_CACHE_ENTRIES )
                {
                    // cache size exceeded - prune entries. For now,
                    // simply remove the first one, which of course
                    // breaks for more complex access schemes. But in
                    // general, this leads to most recently used
                    // entries to reside at the end of the vector.
                    maRenderers.erase( maRenderers.begin() );

                    // ATTENTION: after this, both aIter and aEnd are
                    // invalid!
                }

                // not yet in cache - add default-constructed cache
                // entry, to have something to return
                maRenderers.push_back( RendererCacheEntry() );
                aIter = maRenderers.end()-1;
            }

            return aIter;
        }

        ::cppcanvas::RendererSharedPtr ViewShape::getRenderer( const ::cppcanvas::CanvasSharedPtr&	rDestinationCanvas,
                                                               const GDIMetaFileSharedPtr&			rMtf,
                                                               const ShapeAttributeLayerSharedPtr&	rAttr ) const
        {
            // lookup destination canvas - is there already a renderer
            // created for that target?
            const RendererCacheVector::iterator aIter(
                getCacheEntry( rDestinationCanvas ) );

            // now we have a valid entry, either way. call prefetch()
            // on it, nevertheless - maybe the metafile changed, and
            // the renderer still needs an update (prefetch() will
            // detect that)
            if( prefetch( *aIter,
                          rDestinationCanvas,
                          rMtf,
                          rAttr ) )
            {
                return aIter->mpRenderer;
            }
            else
            {
                // prefetch failed - renderer is invalid
                return ::cppcanvas::RendererSharedPtr();
            }
        }

        void ViewShape::invalidateRenderer() const
        {
            // simply clear the cache. Subsequent getRenderer() calls
            // will regenerate the Renderers.
            maRenderers.clear();
        }

        ::basegfx::B2DSize ViewShape::getAntialiasingBorder() const
        {
            ENSURE_OR_THROW( mpViewLayer->getCanvas(),
                              "ViewShape::getAntialiasingBorder(): Invalid ViewLayer canvas" );

            const ::basegfx::B2DHomMatrix& rViewTransform(
                mpViewLayer->getTransformation() );

            // TODO(F1): As a quick shortcut (did not want to invert
            // whole matrix here), taking only scale components of
            // view transformation matrix. This will be wrong when
            // e.g. shearing is involved.
            const double nXBorder( ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE / rViewTransform.get(0,0) );
            const double nYBorder( ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE / rViewTransform.get(1,1) );

            return ::basegfx::B2DSize( nXBorder,
                                       nYBorder );
        }

        bool ViewShape::enterAnimationMode()
        {
            mbForceUpdate   = true;
            mbAnimationMode = true;

            return true;
        }

        void ViewShape::leaveAnimationMode()
        {
            mpSprite.reset();
            mbAnimationMode = false;
            mbForceUpdate   = true;
        }

        bool ViewShape::update( const GDIMetaFileSharedPtr&	rMtf,
                                const RenderArgs&			rArgs,
                                int							nUpdateFlags,
                                bool						bIsVisible ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::update()" );
            ENSURE_OR_RETURN_FALSE( mpViewLayer->getCanvas(), "ViewShape::update(): Invalid layer canvas" );

            // Shall we render to a sprite, or to a plain canvas?
            if( isBackgroundDetached() )
                return renderSprite( mpViewLayer,
                                     rMtf,
                                     rArgs.maOrigBounds,
                                     rArgs.maBounds,
                                     rArgs.maUnitBounds,
                                     nUpdateFlags,
                                     rArgs.mrAttr,
                                     rArgs.mrSubsets,
                                     rArgs.mnShapePriority,
                                     bIsVisible );
            else
                return render( mpViewLayer->getCanvas(),
                               rMtf,
                               rArgs.maBounds,
                               rArgs.maUpdateBounds,
                               nUpdateFlags,
                               rArgs.mrAttr,
                               rArgs.mrSubsets,
                               bIsVisible );
        }

    }
}
