/**************************************************************
 *
 * 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 );
        }
    }
}
