INTEGRATION: CWS presfixes02 (1.3.2); FILE MERGED

2005/03/23 19:28:09 thb 1.3.2.2: #i38985# At least one of the reasons for the Solaris crash was requesting a zero-sized bitmap here. Now distinguishing between bitmap and output size (the former is rounded _up_ to the nearest integer)
2005/03/14 16:04:55 thb 1.3.2.1: #i35136# #i36914# #i41113# #i44100# #i40115# #i41839# #i44404# Merge from presfixes01 patches
This commit is contained in:
Rüdiger Timm
2005-03-30 07:32:26 +00:00
parent a7f89fdd4d
commit 25caa140ae

View File

@@ -2,9 +2,9 @@
* *
* $RCSfile: transparencygroupaction.cxx,v $ * $RCSfile: transparencygroupaction.cxx,v $
* *
* $Revision: 1.3 $ * $Revision: 1.4 $
* *
* last change: $Author: vg $ $Date: 2005-03-10 13:27:00 $ * last change: $Author: rt $ $Date: 2005-03-30 08:32:26 $
* *
* The Contents of this file are made available subject to the terms of * The Contents of this file are made available subject to the terms of
* either of the following licenses * either of the following licenses
@@ -80,6 +80,9 @@
#include <rtl/math.hxx> #include <rtl/math.hxx>
#endif #endif
#ifndef _SV_METAACT_HXX
#include <vcl/metaact.hxx>
#endif
#ifndef _SV_BITMAPEX_HXX #ifndef _SV_BITMAPEX_HXX
#include <vcl/bitmapex.hxx> #include <vcl/bitmapex.hxx>
#endif #endif
@@ -122,6 +125,8 @@
#include <basegfx/tools/canvastools.hxx> #include <basegfx/tools/canvastools.hxx>
#endif #endif
#include <boost/utility.hpp>
#include <mtftools.hxx> #include <mtftools.hxx>
#include <cppcanvas/vclfactory.hxx> #include <cppcanvas/vclfactory.hxx>
@@ -136,6 +141,92 @@ namespace cppcanvas
// ====================== // ======================
namespace namespace
{ {
class TransparencyGroupAction : public Action, private ::boost::noncopyable
{
public:
/** Create new transparency group action.
@param rGroupMtf
Metafile that groups all actions to be rendered
transparent
@param rParms
Render parameters
@param rDstPoint
Left, top edge of destination, in current state
coordinate system
@param rDstSize
Size of the transparency group object, in current
state coordinate system.
@param nAlpha
Alpha value, must be in the range [0,1]
*/
TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
const Renderer::Parameters& rParms,
const ::Point& rDstPoint,
const ::Size& rDstSize,
double nAlpha,
const CanvasSharedPtr& rCanvas,
const OutDevState& rState );
/** Create new transparency group action.
@param rGroupMtf
Metafile that groups all actions to be rendered
transparent.
@param rAlphaGradient
VCL gradient, to be rendered into the action's alpha
channel.
@param rParms
Render parameters
@param rDstPoint
Left, top edge of destination, in current state
coordinate system
@param rDstSize
Size of the transparency group object, in current
state coordinate system.
*/
TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
GradientAutoPtr& rAlphaGradient,
const Renderer::Parameters& rParms,
const ::Point& rDstPoint,
const ::Size& rDstSize,
const CanvasSharedPtr& rCanvas,
const OutDevState& rState );
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:
MtfAutoPtr mpGroupMtf;
GradientAutoPtr mpAlphaGradient;
const Renderer::Parameters maParms;
const ::Size maDstSize;
mutable uno::Reference< rendering::XBitmap > mxBufferBitmap; // contains last rendered version
mutable ::basegfx::B2DHomMatrix maLastTransformation; // contains last active transformation
mutable Subset maLastSubset; // contains last effective subset
// transformation for
// mxBufferBitmap content
CanvasSharedPtr mpCanvas;
rendering::RenderState maState;
const double mnAlpha;
};
/** Setup transformation such that the next render call is /** Setup transformation such that the next render call is
moved rPoint away, and scaled according to the ratio moved rPoint away, and scaled according to the ratio
given by src and dst size. given by src and dst size.
@@ -150,7 +241,6 @@ namespace cppcanvas
::canvas::tools::appendToRenderState( rRenderState, ::canvas::tools::appendToRenderState( rRenderState,
aLocalTransformation ); aLocalTransformation );
} }
}
TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf, TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
const Renderer::Parameters& rParms, const Renderer::Parameters& rParms,
@@ -171,6 +261,9 @@ namespace cppcanvas
{ {
tools::initRenderState(maState,rState); tools::initRenderState(maState,rState);
implSetupTransform( maState, rDstPoint ); implSetupTransform( maState, rDstPoint );
maLastSubset.mnSubsetBegin = 0;
maLastSubset.mnSubsetEnd = -1;
} }
TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf, TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
@@ -192,11 +285,9 @@ namespace cppcanvas
{ {
tools::initRenderState(maState,rState); tools::initRenderState(maState,rState);
implSetupTransform( maState, rDstPoint ); implSetupTransform( maState, rDstPoint );
}
TransparencyGroupAction::~TransparencyGroupAction() maLastSubset.mnSubsetBegin = 0;
{ maLastSubset.mnSubsetEnd = -1;
// outline, because of incomplete types in header
} }
// TODO(P3): The whole float transparency handling is a mess, // TODO(P3): The whole float transparency handling is a mess,
@@ -206,7 +297,8 @@ namespace cppcanvas
// into the direction of having a direct GDIMetaFile2XCanvas // into the direction of having a direct GDIMetaFile2XCanvas
// renderer, and maybe a separate metafile XCanvas // renderer, and maybe a separate metafile XCanvas
// implementation. // implementation.
bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation,
const Subset& rSubset ) const
{ {
RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" ); RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" );
RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this ); RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this );
@@ -228,7 +320,9 @@ namespace cppcanvas
// as soon as the total transformation changes, we've got // as soon as the total transformation changes, we've got
// to re-render the bitmap // to re-render the bitmap
if( aTotalTransform != maLastTransformation) if( aTotalTransform != maLastTransformation ||
rSubset.mnSubsetBegin != maLastSubset.mnSubsetBegin ||
rSubset.mnSubsetEnd != maLastSubset.mnSubsetEnd )
{ {
DBG_TESTSOLARMUTEX(); DBG_TESTSOLARMUTEX();
@@ -249,21 +343,124 @@ namespace cppcanvas
return false; return false;
} }
::Size aSize( ::basegfx::fround( aScale.getX() * maDstSize.Width() ), // output size of metafile
::Size aOutputSizePixel( ::basegfx::fround( aScale.getX() * maDstSize.Width() ),
::basegfx::fround( aScale.getY() * maDstSize.Height() ) ); ::basegfx::fround( aScale.getY() * maDstSize.Height() ) );
// pixel size of cache bitmap: round up to nearest int
::Size aBitmapSizePixel( static_cast<sal_Int32>( aScale.getX() * maDstSize.Width() )+1,
static_cast<sal_Int32>( aScale.getY() * maDstSize.Height() )+1 );
::Point aEmptyPoint;
// render our content into an appropriately sized // render our content into an appropriately sized
// VirtualDevice with alpha channel // VirtualDevice with alpha channel
VirtualDevice aVDev( VirtualDevice aVDev(
*::Application::GetDefaultDevice(), 0, 0 ); *::Application::GetDefaultDevice(), 0, 0 );
aVDev.SetOutputSizePixel( aSize ); aVDev.SetOutputSizePixel( aBitmapSizePixel );
aVDev.SetMapMode(); aVDev.SetMapMode();
::Point aEmptyPoint; if( rSubset.mnSubsetBegin != 0 ||
rSubset.mnSubsetEnd != -1 )
{
// true subset - extract referenced
// metaactions from mpGroupMtf
GDIMetaFile aMtf;
MetaAction* pCurrAct;
int nCurrActionIndex;
// extract subset actions
for( nCurrActionIndex=0,
pCurrAct=mpGroupMtf->FirstAction();
pCurrAct;
++nCurrActionIndex, pCurrAct = mpGroupMtf->NextAction() )
{
switch( pCurrAct->GetType() )
{
case META_PUSH_ACTION:
case META_POP_ACTION:
case META_CLIPREGION_ACTION:
case META_ISECTRECTCLIPREGION_ACTION:
case META_ISECTREGIONCLIPREGION_ACTION:
case META_MOVECLIPREGION_ACTION:
case META_LINECOLOR_ACTION:
case META_FILLCOLOR_ACTION:
case META_TEXTCOLOR_ACTION:
case META_TEXTFILLCOLOR_ACTION:
case META_TEXTLINECOLOR_ACTION:
case META_TEXTALIGN_ACTION:
case META_FONT_ACTION:
case META_RASTEROP_ACTION:
case META_REFPOINT_ACTION:
case META_LAYOUTMODE_ACTION:
// state-changing action - copy as-is
aMtf.AddAction( pCurrAct->Clone() );
break;
case META_GRADIENT_ACTION:
case META_HATCH_ACTION:
case META_EPS_ACTION:
case META_COMMENT_ACTION:
case META_POINT_ACTION:
case META_PIXEL_ACTION:
case META_LINE_ACTION:
case META_RECT_ACTION:
case META_ROUNDRECT_ACTION:
case META_ELLIPSE_ACTION:
case META_ARC_ACTION:
case META_PIE_ACTION:
case META_CHORD_ACTION:
case META_POLYLINE_ACTION:
case META_POLYGON_ACTION:
case META_POLYPOLYGON_ACTION:
case META_BMP_ACTION:
case META_BMPSCALE_ACTION:
case META_BMPSCALEPART_ACTION:
case META_BMPEX_ACTION:
case META_BMPEXSCALE_ACTION:
case META_BMPEXSCALEPART_ACTION:
case META_MASK_ACTION:
case META_MASKSCALE_ACTION:
case META_MASKSCALEPART_ACTION:
case META_GRADIENTEX_ACTION:
case META_WALLPAPER_ACTION:
case META_TRANSPARENT_ACTION:
case META_FLOATTRANSPARENT_ACTION:
case META_TEXT_ACTION:
case META_TEXTARRAY_ACTION:
case META_TEXTLINE_ACTION:
case META_TEXTRECT_ACTION:
case META_STRETCHTEXT_ACTION:
// output-generating action - only
// copy, if we're within the
// requested subset
if( rSubset.mnSubsetBegin <= nCurrActionIndex &&
rSubset.mnSubsetEnd > nCurrActionIndex )
{
aMtf.AddAction( pCurrAct->Clone() );
}
break;
default:
OSL_ENSURE( false,
"Unknown meta action type encountered" );
break;
}
}
aVDev.DrawTransparent( aMtf,
aEmptyPoint,
aOutputSizePixel,
*mpAlphaGradient );
}
else
{
// no subsetting - render whole mtf
aVDev.DrawTransparent( *mpGroupMtf, aVDev.DrawTransparent( *mpGroupMtf,
aEmptyPoint, aEmptyPoint,
aSize, aOutputSizePixel,
*mpAlphaGradient ); *mpAlphaGradient );
}
// update buffered bitmap and transformation // update buffered bitmap and transformation
@@ -271,9 +468,10 @@ namespace cppcanvas
mpCanvas, mpCanvas,
aVDev.GetBitmapEx( aVDev.GetBitmapEx(
aEmptyPoint, aEmptyPoint,
aSize ) ) ); aBitmapSizePixel ) ) );
mxBufferBitmap = aBmp->getUNOBitmap(); mxBufferBitmap = aBmp->getUNOBitmap();
maLastTransformation = aTotalTransform; maLastTransformation = aTotalTransform;
maLastSubset = rSubset;
} }
// determine target transformation (we can't simply pass // determine target transformation (we can't simply pass
@@ -326,5 +524,63 @@ namespace cppcanvas
return true; return true;
} }
// TODO(P3): The whole float transparency handling is a mess,
// this should be refactored. What's more, the old idea of
// having only internal 'metaactions', and not the original
// GDIMetaFile now looks a lot less attractive. Try to move
// into the direction of having a direct GDIMetaFile2XCanvas
// renderer, and maybe a separate metafile XCanvas
// implementation.
bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
{
Subset aSubset;
aSubset.mnSubsetBegin = 0;
aSubset.mnSubsetEnd = -1;
return render( rTransformation, aSubset );
}
sal_Int32 TransparencyGroupAction::getActionCount() const
{
return mpGroupMtf.get() ? mpGroupMtf->GetActionCount() : 0;
}
}
ActionSharedPtr TransparencyGroupActionFactory::createTransparencyGroupAction( MtfAutoPtr& rGroupMtf,
const Renderer::Parameters& rParms,
const ::Point& rDstPoint,
const ::Size& rDstSize,
double nAlpha,
const CanvasSharedPtr& rCanvas,
const OutDevState& rState )
{
return ActionSharedPtr( new TransparencyGroupAction(rGroupMtf,
rParms,
rDstPoint,
rDstSize,
nAlpha,
rCanvas,
rState ) );
}
ActionSharedPtr TransparencyGroupActionFactory::createTransparencyGroupAction( MtfAutoPtr& rGroupMtf,
GradientAutoPtr& rAlphaGradient,
const Renderer::Parameters& rParms,
const ::Point& rDstPoint,
const ::Size& rDstSize,
const CanvasSharedPtr& rCanvas,
const OutDevState& rState )
{
return ActionSharedPtr( new TransparencyGroupAction(rGroupMtf,
rAlphaGradient,
rParms,
rDstPoint,
rDstSize,
rCanvas,
rState ) );
}
} }
} }