/**************************************************************
 * 
 * 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.getX(),
                                          -rOffset.getY() );
                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.getX(),
                                              -rOffset.getY() );
                    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 );
        }
    }
}
