From 6fdad545b4056a3500b07ab87610aaf8a69d1b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Timm?= Date: Wed, 30 Mar 2005 07:30:28 +0000 Subject: [PATCH] INTEGRATION: CWS presfixes02 (1.4.2); FILE MERGED 2005/03/14 16:04:52 thb 1.4.2.1: #i35136# #i36914# #i41113# #i44100# #i40115# #i41839# #i44404# Merge from presfixes01 patches --- cppcanvas/source/mtfrenderer/lineaction.cxx | 108 +++-- cppcanvas/source/mtfrenderer/lineaction.hxx | 50 +- cppcanvas/source/mtfrenderer/mtftools.cxx | 493 +++++++++++++++++++- 3 files changed, 588 insertions(+), 63 deletions(-) diff --git a/cppcanvas/source/mtfrenderer/lineaction.cxx b/cppcanvas/source/mtfrenderer/lineaction.cxx index ca40734d2e9b..026db13e4da7 100644 --- a/cppcanvas/source/mtfrenderer/lineaction.cxx +++ b/cppcanvas/source/mtfrenderer/lineaction.cxx @@ -2,9 +2,9 @@ * * $RCSfile: lineaction.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: vg $ $Date: 2005-03-10 13:24:30 $ + * last change: $Author: rt $ $Date: 2005-03-30 08:28:31 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -83,6 +83,8 @@ #include #endif +#include + #include #include @@ -94,37 +96,85 @@ namespace cppcanvas { namespace internal { - LineAction::LineAction( const ::Point& rStartPoint, - const ::Point& rEndPoint, - const CanvasSharedPtr& rCanvas, - const OutDevState& rState ) : - maStartPoint( rStartPoint ), - maEndPoint( rEndPoint ), - mpCanvas( rCanvas ), - maState() + namespace { - tools::initRenderState(maState,rState); - maState.DeviceColor = rState.lineColor; + class LineAction : public Action, private ::boost::noncopyable + { + public: + LineAction( const ::Point&, + const ::Point&, + const CanvasSharedPtr&, + const OutDevState& ); + + virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation ) const; + virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation, + const Subset& rSubset ) const; + + virtual sal_Int32 getActionCount() const; + + private: + Point maStartPoint; + Point maEndPoint; + CanvasSharedPtr mpCanvas; + rendering::RenderState maState; + }; + + LineAction::LineAction( const ::Point& rStartPoint, + const ::Point& rEndPoint, + const CanvasSharedPtr& rCanvas, + const OutDevState& rState ) : + maStartPoint( rStartPoint ), + maEndPoint( rEndPoint ), + mpCanvas( rCanvas ), + maState() + { + tools::initRenderState(maState,rState); + maState.DeviceColor = rState.lineColor; + } + + bool LineAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const + { + RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::LineAction::render()" ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::LineAction: 0x%X", this ); + + rendering::RenderState aLocalState( maState ); + ::canvas::tools::prependToRenderState(aLocalState, rTransformation); + + mpCanvas->getUNOCanvas()->drawLine( ::vcl::unotools::point2DFromPoint(maStartPoint), + ::vcl::unotools::point2DFromPoint(maEndPoint), + mpCanvas->getViewState(), + aLocalState ); + + return true; + } + + bool LineAction::render( const ::basegfx::B2DHomMatrix& rTransformation, + const Subset& rSubset ) const + { + // line only contains a single action, fail if subset + // requests different range + if( rSubset.mnSubsetBegin != 0 || + rSubset.mnSubsetEnd != 1 ) + return false; + + return render( rTransformation ); + } + + sal_Int32 LineAction::getActionCount() const + { + return 1; + } } - LineAction::~LineAction() + ActionSharedPtr LineActionFactory::createLineAction( const ::Point& rStartPoint, + const ::Point& rEndPoint, + const CanvasSharedPtr& rCanvas, + const OutDevState& rState ) { - } - - bool LineAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const - { - RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::LineAction::render()" ); - RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::LineAction: 0x%X", this ); - - rendering::RenderState aLocalState( maState ); - ::canvas::tools::prependToRenderState(aLocalState, rTransformation); - - mpCanvas->getUNOCanvas()->drawLine( ::vcl::unotools::point2DFromPoint(maStartPoint), - ::vcl::unotools::point2DFromPoint(maEndPoint), - mpCanvas->getViewState(), - aLocalState ); - - return true; + return ActionSharedPtr( new LineAction( rStartPoint, + rEndPoint, + rCanvas, + rState) ); } } diff --git a/cppcanvas/source/mtfrenderer/lineaction.hxx b/cppcanvas/source/mtfrenderer/lineaction.hxx index 20a0a199abff..e2e63937959e 100644 --- a/cppcanvas/source/mtfrenderer/lineaction.hxx +++ b/cppcanvas/source/mtfrenderer/lineaction.hxx @@ -2,9 +2,9 @@ * * $RCSfile: lineaction.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: vg $ $Date: 2005-03-10 13:24:44 $ + * last change: $Author: rt $ $Date: 2005-03-30 08:29:38 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -62,21 +62,13 @@ #ifndef _CPPCANVAS_LINEACTION_HXX #define _CPPCANVAS_LINEACTION_HXX -#ifndef _COM_SUN_STAR_RENDERING_RENDERSTATE_HPP__ -#include -#endif - -#ifndef _SV_GEN_HXX -#include -#endif - #include #include -class Color; +class Point; -/* Definition of internal::LineAction class */ +/* Definition of internal::LineActionFactory class */ namespace cppcanvas { @@ -84,26 +76,28 @@ namespace cppcanvas { struct OutDevState; - class LineAction : public Action + /** Creates encapsulated converters between GDIMetaFile and + XCanvas. The Canvas argument is deliberately placed at the + constructor, to force reconstruction of this object for a + new canvas. This considerably eases internal state + handling, since a lot of the internal state (e.g. fonts, + text layout) is Canvas-dependent. + */ + class LineActionFactory { public: - LineAction( const ::Point&, - const ::Point&, - const CanvasSharedPtr&, - const OutDevState& ); - virtual ~LineAction(); - - virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation ) const; + /// Plain hair line from point 1 to point 2 + static ActionSharedPtr createLineAction( const ::Point&, + const ::Point&, + const CanvasSharedPtr&, + const OutDevState& ); private: - // default: disabled copy/assignment - LineAction(const LineAction&); - LineAction& operator=( const LineAction& ); - - Point maStartPoint; - Point maEndPoint; - CanvasSharedPtr mpCanvas; - ::com::sun::star::rendering::RenderState maState; + // static factory, disable big four + LineActionFactory(); + ~LineActionFactory(); + LineActionFactory(const LineActionFactory&); + LineActionFactory& operator=( const LineActionFactory& ); }; } } diff --git a/cppcanvas/source/mtfrenderer/mtftools.cxx b/cppcanvas/source/mtfrenderer/mtftools.cxx index bbd3101f4372..5de3a01920c1 100644 --- a/cppcanvas/source/mtfrenderer/mtftools.cxx +++ b/cppcanvas/source/mtfrenderer/mtftools.cxx @@ -2,9 +2,9 @@ * * $RCSfile: mtftools.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: vg $ $Date: 2005-03-10 13:25:00 $ + * last change: $Author: rt $ $Date: 2005-03-30 08:30:28 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,27 +59,67 @@ * ************************************************************************/ +#include +#include + #include #include +#include #ifndef _COM_SUN_STAR_RENDERING_RENDERSTATE_HPP__ #include #endif +#ifndef _COM_SUN_STAR_RENDERING_XCANVAS_HPP__ +#include +#endif +#ifndef _BGFX_NUMERIC_FTOOLS_HXX +#include +#endif +#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX +#include +#endif +#ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX +#include +#endif +#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX +#include +#endif +#ifndef _BGFX_RANGE_B2DRECTANGLE_HXX +#include +#endif +#ifndef _BGFX_VECTOR_B2DVECTOR_HXX +#include +#endif #ifndef _CANVAS_CANVASTOOLS_HXX #include #endif +#ifndef _SV_GDIMTF_HXX +#include +#endif +#ifndef _SV_METAACT_HXX +#include +#endif +#ifndef _SV_VIRDEV_HXX +#include +#endif +#ifndef _SV_METRIC_HXX +#include +#endif +#ifndef _TL_POLY_HXX +#include +#endif + using namespace ::com::sun::star; namespace cppcanvas { - namespace tools { - void initRenderState( ::com::sun::star::rendering::RenderState& renderState, - const struct ::cppcanvas::internal::OutDevState& outdevState ) + void initRenderState( rendering::RenderState& renderState, + const ::cppcanvas::internal::OutDevState& outdevState ) { ::canvas::tools::initRenderState( renderState ); ::canvas::tools::setRenderStateTransform( renderState, @@ -87,6 +127,447 @@ namespace cppcanvas 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() ); + + case ALIGN_BASELINE: + return ::Size( 0, 0 ); + + case ALIGN_BOTTOM: + return ::Size( 0, + -aMetric.GetDescent() ); + + default: + ENSURE_AND_THROW( false, + "tools::getBaselineOffset(): Unexpected TextAlign value" ); + } + } + + ::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.identity(); + o_rMatrix.scale( aSizePixel.Width() / (double)aSizeLogic.Width(), + aSizePixel.Height() / (double)aSizeLogic.Height() ); + + 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 ::Point aEmptyPoint; + + const bool bOffsetting( !rOffset.equalZero() ); + const bool bScaling( pScaling && + pScaling->getX() != 1.0 && + pScaling->getY() != 1.0 ); + + if( !bOffsetting && !bScaling ) + 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() ); + + 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( 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 ) + { + return modifyClip( o_rRenderState, + rOutdevState, + rCanvas, + ::basegfx::B2DPoint( rOffset.X(), + rOffset.Y() ), + pScaling ); + } + + 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 underline/strikeout line info struct + TextLineInfo createTextLineInfo( const ::VirtualDevice& rVDev, + const ::cppcanvas::internal::OutDevState& rState ) + { + const BOOL bOldMode( rVDev.IsMapModeEnabled() ); + + // will restore map mode below + const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( FALSE ); + + const ::FontMetric aMetric = rVDev.GetFontMetric(); + + TextLineInfo aTextInfo( + (aMetric.GetDescent() + 2) / 4.0, + aMetric.GetDescent() / 2.0, + (aMetric.GetIntLeading() - aMetric.GetAscent()) / 3.0, + 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