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

#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/verbosetrace.hxx>
#include <com/sun/star/rendering/RenderState.hpp>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <canvas/canvastools.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/metaact.hxx>
#include <vcl/virdev.hxx>
#include <vcl/metric.hxx>
#include <tools/poly.hxx>
#include "mtftools.hxx"
#include "outdevstate.hxx"
#include "polypolyaction.hxx"
#include <basegfx/matrix/b2dhommatrixtools.hxx>



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

namespace cppcanvas
{
    namespace tools
    {
        void initRenderState( rendering::RenderState&					renderState,
                              const ::cppcanvas::internal::OutDevState&	outdevState )
        {
            ::canvas::tools::initRenderState( renderState );
            ::canvas::tools::setRenderStateTransform( renderState, 
                                                      outdevState.transform );
            renderState.Clip = outdevState.xClipPoly;
        }

        ::Size getBaselineOffset( const ::cppcanvas::internal::OutDevState&	outdevState,
                                  const VirtualDevice&						rVDev )
        {
            const ::FontMetric& aMetric = rVDev.GetFontMetric();

            // calc offset for text output, the XCanvas always renders
            // baseline offset.
            switch( outdevState.textReferencePoint )
            {
                case ALIGN_TOP:
                    return ::Size( 0,
                                   aMetric.GetIntLeading() + aMetric.GetAscent() );

                default:
                    ENSURE_OR_THROW( false,
                                      "tools::getBaselineOffset(): Unexpected TextAlign value" );
                    // FALLTHROUGH intended (to calm compiler warning - case won't happen)
                case ALIGN_BASELINE:
                    return ::Size( 0, 0 );

                case ALIGN_BOTTOM:
                    return ::Size( 0,
                                   -aMetric.GetDescent() );

            }
        }

        ::basegfx::B2DHomMatrix& calcLogic2PixelLinearTransform( ::basegfx::B2DHomMatrix&	o_rMatrix,
                                                                 const VirtualDevice& 		rVDev )
        {
            // select size value in the middle of the available range,
            // to have headroom both when map mode scales up, and when
            // it scales down.
            const ::Size aSizeLogic( 0x00010000L,
                                     0x00010000L );

            const ::Size aSizePixel( rVDev.LogicToPixel( aSizeLogic ) );

			o_rMatrix = basegfx::tools::createScaleB2DHomMatrix(
				aSizePixel.Width() / (double)aSizeLogic.Width(),
				aSizePixel.Height() / (double)aSizeLogic.Height() );

            return o_rMatrix;
        }

        ::basegfx::B2DHomMatrix& calcLogic2PixelAffineTransform( ::basegfx::B2DHomMatrix&	o_rMatrix,
                                                                 const VirtualDevice& 		rVDev )
        {
            // retrieves scale
            calcLogic2PixelLinearTransform(o_rMatrix, rVDev);

            // translate according to curr map mode/pref map mode offset
            const ::Point  aEmptyPoint;
            const ::Point& rTranslatedPoint( 
                rVDev.LogicToPixel( aEmptyPoint ));

            o_rMatrix.translate(rTranslatedPoint.X(),
                                rTranslatedPoint.Y());

            return o_rMatrix;
        }

        bool modifyClip( rendering::RenderState&							o_rRenderState,
                         const struct ::cppcanvas::internal::OutDevState&	rOutdevState,
                         const CanvasSharedPtr&								rCanvas,
                         const ::basegfx::B2DPoint&							rOffset,
                         const ::basegfx::B2DVector*						pScaling,
                         const double*                                      pRotation )
        {
            const ::Point aEmptyPoint;

            const bool bOffsetting( !rOffset.equalZero() );
            const bool bScaling( pScaling && 
                                 pScaling->getX() != 1.0 && 
                                 pScaling->getY() != 1.0 );
            const bool bRotation( pRotation &&
                                  *pRotation != 0.0 );

            if( !bOffsetting && !bScaling && !bRotation )
                return false; // nothing to do
            
            if( rOutdevState.clip.count() )
            {
                // general polygon case

                ::basegfx::B2DPolyPolygon aLocalClip( rOutdevState.clip );
                ::basegfx::B2DHomMatrix	  aTransform;
                    
                if( bOffsetting )
                    aTransform.translate( -rOffset );
                if( bScaling )
                    aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );

                if( bRotation )
                    aTransform.rotate( - *pRotation );

                aLocalClip.transform( aTransform );
                
                o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
                    rCanvas->getUNOCanvas()->getDevice(),
                    aLocalClip );

                return true;
            }
            else if( !rOutdevState.clipRect.IsEmpty() )
            {
                // simple rect case

                const ::Rectangle aLocalClipRect( rOutdevState.clipRect );
                
                if( bRotation )
                {
                    // rotation involved - convert to polygon first,
                    // then transform that
                    ::basegfx::B2DPolygon aLocalClip( 
                        ::basegfx::tools::createPolygonFromRect( 
                                ::basegfx::B2DRectangle( 
                                    (double)(aLocalClipRect.Left()),
                                    (double)(aLocalClipRect.Top()),
                                    (double)(aLocalClipRect.Right()),
                                    (double)(aLocalClipRect.Bottom()) ) ) );
                    ::basegfx::B2DHomMatrix aTransform;
                    
                    if( bOffsetting )
                        aTransform.translate( -rOffset );
                    if( bScaling )
                        aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );

                    aTransform.rotate( - *pRotation );

                    aLocalClip.transform( aTransform );

                    o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
                        rCanvas->getUNOCanvas()->getDevice(),
                        ::basegfx::B2DPolyPolygon( aLocalClip ) );
                }
                else if( bScaling )
                {
                    // scale and offset - do it on the fly, have to
                    // convert to float anyway.
                    o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
                        rCanvas->getUNOCanvas()->getDevice(),
                        ::basegfx::B2DPolyPolygon(
                            ::basegfx::tools::createPolygonFromRect( 
                                ::basegfx::B2DRectangle( 
                                    (double)(aLocalClipRect.Left() - rOffset.getX())/pScaling->getX(),
                                    (double)(aLocalClipRect.Top() - rOffset.getY())/pScaling->getY(),
                                    (double)(aLocalClipRect.Right() - rOffset.getX())/pScaling->getX(),
                                    (double)(aLocalClipRect.Bottom() - rOffset.getY())/pScaling->getY() ) ) ) );
                }
                else
                {
                    // offset only - do it on the fly, have to convert
                    // to float anyway.
                    o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
                        rCanvas->getUNOCanvas()->getDevice(),
                        ::basegfx::B2DPolyPolygon(
                            ::basegfx::tools::createPolygonFromRect( 
                                ::basegfx::B2DRectangle( aLocalClipRect.Left() - rOffset.getX(),
                                                         aLocalClipRect.Top() - rOffset.getY(),
                                                         aLocalClipRect.Right() - rOffset.getX(),
                                                         aLocalClipRect.Bottom() - rOffset.getY() ) ) ) );
                }

                return true;
            }

            // empty clip, nothing to do
            return false;
        }

        bool modifyClip( rendering::RenderState&							o_rRenderState,
                         const struct ::cppcanvas::internal::OutDevState&	rOutdevState,
                         const CanvasSharedPtr&								rCanvas,
                         const ::Point&										rOffset,
                         const ::basegfx::B2DVector*						pScaling,
                         const double*                                      pRotation )
        {
            return modifyClip( o_rRenderState, 
                               rOutdevState, 
                               rCanvas, 
                               ::basegfx::B2DPoint( rOffset.X(), 
                                                    rOffset.Y() ), 
                               pScaling,
                               pRotation );
        }

        bool modifyClip( rendering::RenderState&							o_rRenderState,
                         const struct ::cppcanvas::internal::OutDevState&	rOutdevState,
                         const CanvasSharedPtr&								rCanvas,
                         const ::basegfx::B2DHomMatrix&						rTransform )
        {
            if( !rTransform.isIdentity() ||
                !rTransform.isInvertible() )
                return false; // nothing to do
            
            ::basegfx::B2DPolyPolygon aLocalClip;

            if( rOutdevState.clip.count() )
            {
                aLocalClip = rOutdevState.clip;
            }
            else if( !rOutdevState.clipRect.IsEmpty() )
            {
                const ::Rectangle aLocalClipRect( rOutdevState.clipRect );

                aLocalClip = ::basegfx::B2DPolyPolygon(
                    ::basegfx::tools::createPolygonFromRect( 
                        ::basegfx::B2DRectangle( 
                            aLocalClipRect.Left(),
                            aLocalClipRect.Top(),
                            aLocalClipRect.Right(),
                            aLocalClipRect.Bottom() ) ) );
            }
            else
            {
                // empty clip, nothing to do
                return false;
            }

            // invert transformation and modify
            ::basegfx::B2DHomMatrix aLocalTransform( rTransform );
            aLocalTransform.invert();

            aLocalClip.transform( aLocalTransform );

            o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
                rCanvas->getUNOCanvas()->getDevice(),
                aLocalClip );

            return true;
        }

        // create overline/underline/strikeout line info struct
        TextLineInfo createTextLineInfo( const ::VirtualDevice& 					rVDev,
                                         const ::cppcanvas::internal::OutDevState&	rState )
        {
            const sal_Bool bOldMode( rVDev.IsMapModeEnabled() );

            // #i68512# Force metric regeneration with mapmode enabled
            // (prolly OutDev bug)
            rVDev.GetFontMetric();
                
            // will restore map mode below
            const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( sal_False );

            const ::FontMetric aMetric = rVDev.GetFontMetric();

            TextLineInfo aTextInfo(
                (aMetric.GetDescent() + 2) / 4.0,
                ((aMetric.GetIntLeading() + 1.5) / 3.0),
                (aMetric.GetIntLeading() / 2.0) - aMetric.GetAscent(),
                aMetric.GetDescent() / 2.0,
                (aMetric.GetIntLeading() - aMetric.GetAscent()) / 3.0,
                rState.textOverlineStyle,
                rState.textUnderlineStyle,
                rState.textStrikeoutStyle );

            const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( bOldMode );

            return aTextInfo;
        }

        namespace
        {
            void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
                             const ::basegfx::B2DPoint& rStartPos,
                             const double 				nX1,
                             const double 				nY1,
                             const double 				nX2,
                             const double 				nY2 )
            {
                const double x( rStartPos.getX() );
                const double y( rStartPos.getY() );

                o_rPoly.append(
                    ::basegfx::tools::createPolygonFromRect( 
                        ::basegfx::B2DRectangle( x + nX1, y + nY1, x + nX2, y + nY2 ) ) );
            }

            void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
                             const double 				nX1,
                             const double 				nY1,
                             const double 				nX2,
                             const double 				nY2 )
            {
                o_rPoly.append(
                    ::basegfx::tools::createPolygonFromRect( 
                        ::basegfx::B2DRectangle( nX1, nY1, nX2, nY2 ) ) );
            }

            void appendDashes( ::basegfx::B2DPolyPolygon&	o_rPoly,
                               const double 				nX,
                               const double 				nY,
                               const double 				nLineWidth,
                               const double 				nLineHeight,
                               const double 				nDashWidth,
                               const double 				nDashSkip )
            {
                const sal_Int32 nNumLoops( 
                    static_cast< sal_Int32 >(
                        ::std::max( 1.0,
                                    nLineWidth / nDashSkip ) + .5) );

                double x = nX;
                for( sal_Int32 i=0; i<nNumLoops; ++i )
                {
                    appendRect( o_rPoly,
                                x, 				nY,
                                x + nDashWidth, nY + nLineHeight );

                    x += nDashSkip;
                }
            }
        }

        // create line actions for text such as underline and
        // strikeout
        ::basegfx::B2DPolyPolygon createTextLinesPolyPolygon( const ::basegfx::B2DPoint rStartPos,
                                                              const double&				rLineWidth,
                                                              const TextLineInfo&		rTextLineInfo )
        {
            // fill the polypolygon with all text lines
            ::basegfx::B2DPolyPolygon aTextLinesPolyPoly;

            switch( rTextLineInfo.mnOverlineStyle )
            {
                case UNDERLINE_NONE:    	  // nothing to do
                    // FALLTHROUGH intended
                case UNDERLINE_DONTKNOW:
                    break;

                case UNDERLINE_SMALLWAVE:     // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_WAVE:          // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_SINGLE:
                    appendRect(
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnOverlineOffset,
                        rLineWidth,
                        rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
                    break;

                case UNDERLINE_BOLDDOTTED:    // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDDASH:      // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDLONGDASH:  // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDDASHDOT:   // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDDASHDOTDOT:// TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDWAVE:      // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLD:
                    appendRect(
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight,
                        rLineWidth,
                        rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
                    break;

                case UNDERLINE_DOUBLEWAVE:    // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_DOUBLE:
                    appendRect(
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight * 2.0 ,
                        rLineWidth,
                        rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight );

                    appendRect(
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight,
                        rLineWidth,
                        rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight * 2.0 );
                    break;

                case UNDERLINE_DASHDOTDOT:    // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_DOTTED:
                    appendDashes(
                        aTextLinesPolyPoly,
                        rStartPos.getX(),
                        rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
                        rLineWidth,
                        rTextLineInfo.mnOverlineHeight,
                        rTextLineInfo.mnOverlineHeight,
                        2*rTextLineInfo.mnOverlineHeight );
                    break;

                case UNDERLINE_DASHDOT:       // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_DASH:
                    appendDashes(
                        aTextLinesPolyPoly,
                        rStartPos.getX(),
                        rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
                        rLineWidth,
                        rTextLineInfo.mnOverlineHeight,
                        3*rTextLineInfo.mnOverlineHeight,
                        6*rTextLineInfo.mnOverlineHeight );
                    break;

                case UNDERLINE_LONGDASH:
                    appendDashes(
                        aTextLinesPolyPoly,
                        rStartPos.getX(),
                        rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
                        rLineWidth,
                        rTextLineInfo.mnOverlineHeight,
                        6*rTextLineInfo.mnOverlineHeight,
                        12*rTextLineInfo.mnOverlineHeight );
                    break;

                default:
                    ENSURE_OR_THROW( false,
                                      "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected overline case" );
            }

            switch( rTextLineInfo.mnUnderlineStyle )
            {
                case UNDERLINE_NONE:    	  // nothing to do
                    // FALLTHROUGH intended
                case UNDERLINE_DONTKNOW:
                    break;

                case UNDERLINE_SMALLWAVE:     // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_WAVE:          // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_SINGLE:
                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnUnderlineOffset, 
                        rLineWidth,
                        rTextLineInfo.mnUnderlineOffset + rTextLineInfo.mnLineHeight );
                    break;

                case UNDERLINE_BOLDDOTTED:    // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDDASH:      // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDLONGDASH:  // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDDASHDOT:   // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDDASHDOTDOT:// TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLDWAVE:      // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_BOLD:
                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnUnderlineOffset, 
                        rLineWidth,
                        rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight );
                    break;

                case UNDERLINE_DOUBLEWAVE:    // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_DOUBLE:
                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnUnderlineOffset - rTextLineInfo.mnLineHeight, 
                        rLineWidth,
                        rTextLineInfo.mnUnderlineOffset );

                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight, 
                        rLineWidth,
                        rTextLineInfo.mnUnderlineOffset + 3*rTextLineInfo.mnLineHeight );
                    break;

                case UNDERLINE_DASHDOTDOT:    // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_DOTTED:
                    appendDashes( 
                        aTextLinesPolyPoly,
                        rStartPos.getX(),
                        rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
                        rLineWidth,
                        rTextLineInfo.mnLineHeight,
                        rTextLineInfo.mnLineHeight, 
                        2*rTextLineInfo.mnLineHeight );
                    break;

                case UNDERLINE_DASHDOT:       // TODO(F3): NYI
                    // FALLTHROUGH intended
                case UNDERLINE_DASH:
                    appendDashes( 
                        aTextLinesPolyPoly,
                        rStartPos.getX(),
                        rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
                        rLineWidth,
                        rTextLineInfo.mnLineHeight,
                        3*rTextLineInfo.mnLineHeight, 
                        6*rTextLineInfo.mnLineHeight );
                    break;

                case UNDERLINE_LONGDASH:
                    appendDashes( 
                        aTextLinesPolyPoly,
                        rStartPos.getX(),
                        rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
                        rLineWidth,
                        rTextLineInfo.mnLineHeight,
                        6*rTextLineInfo.mnLineHeight, 
                        12*rTextLineInfo.mnLineHeight );
                    break;

                default:
                    ENSURE_OR_THROW( false,
                                      "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected underline case" );
            }

            switch( rTextLineInfo.mnStrikeoutStyle )
            {
                case STRIKEOUT_NONE:    // nothing to do
                    // FALLTHROUGH intended
                case STRIKEOUT_DONTKNOW:
                    break;

                case STRIKEOUT_SLASH:   // TODO(Q1): we should handle this in the text layer
                    // FALLTHROUGH intended
                case STRIKEOUT_X:
                    break;

                case STRIKEOUT_SINGLE:
                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnStrikeoutOffset, 
                        rLineWidth,
                        rTextLineInfo.mnStrikeoutOffset + rTextLineInfo.mnLineHeight );
                    break;

                case STRIKEOUT_BOLD:
                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnStrikeoutOffset, 
                        rLineWidth,
                        rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight );
                    break;

                case STRIKEOUT_DOUBLE:
                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnStrikeoutOffset - rTextLineInfo.mnLineHeight, 
                        rLineWidth,
                        rTextLineInfo.mnStrikeoutOffset );

                    appendRect( 
                        aTextLinesPolyPoly,
                        rStartPos,
                        0,
                        rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight, 
                        rLineWidth,
                        rTextLineInfo.mnStrikeoutOffset + 3*rTextLineInfo.mnLineHeight );
                    break;

                default:
                    ENSURE_OR_THROW( false,
                                      "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected strikeout case" );
            }

            return aTextLinesPolyPoly;
        }

        ::basegfx::B2DRange calcDevicePixelBounds( const ::basegfx::B2DRange& 		rBounds,
                                                   const rendering::ViewState&		viewState,
                                                   const rendering::RenderState&	renderState )
        {
            ::basegfx::B2DHomMatrix aTransform;
            ::canvas::tools::mergeViewAndRenderTransform( aTransform,
                                                          viewState,
                                                          renderState );
 
            ::basegfx::B2DRange aTransformedBounds;
            return ::canvas::tools::calcTransformedRectBounds( aTransformedBounds,
                                                               rBounds, 
                                                               aTransform );
        }

        // create line actions for text such as underline and
        // strikeout
        ::basegfx::B2DPolyPolygon createTextLinesPolyPolygon( const double&			rStartOffset,
                                                              const double&			rLineWidth,
                                                              const TextLineInfo&	rTextLineInfo )
        {
            return createTextLinesPolyPolygon( 
                ::basegfx::B2DPoint( rStartOffset,
                                     0.0 ),
                rLineWidth,
                rTextLineInfo );
        }
    }
}
