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:
@@ -2,9 +2,9 @@
|
||||
*
|
||||
* $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
|
||||
* either of the following licenses
|
||||
@@ -80,6 +80,9 @@
|
||||
#include <rtl/math.hxx>
|
||||
#endif
|
||||
|
||||
#ifndef _SV_METAACT_HXX
|
||||
#include <vcl/metaact.hxx>
|
||||
#endif
|
||||
#ifndef _SV_BITMAPEX_HXX
|
||||
#include <vcl/bitmapex.hxx>
|
||||
#endif
|
||||
@@ -122,6 +125,8 @@
|
||||
#include <basegfx/tools/canvastools.hxx>
|
||||
#endif
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <mtftools.hxx>
|
||||
#include <cppcanvas/vclfactory.hxx>
|
||||
|
||||
@@ -136,6 +141,92 @@ namespace cppcanvas
|
||||
// ======================
|
||||
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
|
||||
moved rPoint away, and scaled according to the ratio
|
||||
given by src and dst size.
|
||||
@@ -150,180 +241,345 @@ namespace cppcanvas
|
||||
::canvas::tools::appendToRenderState( rRenderState,
|
||||
aLocalTransformation );
|
||||
}
|
||||
}
|
||||
|
||||
TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
|
||||
const Renderer::Parameters& rParms,
|
||||
const ::Point& rDstPoint,
|
||||
const ::Size& rDstSize,
|
||||
double nAlpha,
|
||||
const CanvasSharedPtr& rCanvas,
|
||||
const OutDevState& rState ) :
|
||||
mpGroupMtf( rGroupMtf ),
|
||||
mpAlphaGradient(),
|
||||
maParms( rParms ),
|
||||
maDstSize( rDstSize ),
|
||||
mxBufferBitmap(),
|
||||
maLastTransformation(),
|
||||
mpCanvas( rCanvas ),
|
||||
maState(),
|
||||
mnAlpha( nAlpha )
|
||||
{
|
||||
tools::initRenderState(maState,rState);
|
||||
implSetupTransform( maState, rDstPoint );
|
||||
}
|
||||
|
||||
TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
|
||||
GradientAutoPtr& rAlphaGradient,
|
||||
const Renderer::Parameters& rParms,
|
||||
const ::Point& rDstPoint,
|
||||
const ::Size& rDstSize,
|
||||
const CanvasSharedPtr& rCanvas,
|
||||
const OutDevState& rState ) :
|
||||
mpGroupMtf( rGroupMtf ),
|
||||
mpAlphaGradient( rAlphaGradient ),
|
||||
maParms( rParms ),
|
||||
maDstSize( rDstSize ),
|
||||
mxBufferBitmap(),
|
||||
maLastTransformation(),
|
||||
mpCanvas( rCanvas ),
|
||||
maState(),
|
||||
mnAlpha( 1.0 )
|
||||
{
|
||||
tools::initRenderState(maState,rState);
|
||||
implSetupTransform( maState, rDstPoint );
|
||||
}
|
||||
|
||||
TransparencyGroupAction::~TransparencyGroupAction()
|
||||
{
|
||||
// outline, because of incomplete types in header
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" );
|
||||
RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this );
|
||||
|
||||
// determine overall transformation matrix (render, view,
|
||||
// and passed transformation)
|
||||
::basegfx::B2DHomMatrix aTransform;
|
||||
::canvas::tools::getRenderStateTransform( aTransform, maState );
|
||||
aTransform = rTransformation * aTransform;
|
||||
|
||||
::basegfx::B2DHomMatrix aTotalTransform;
|
||||
::canvas::tools::getViewStateTransform( aTotalTransform, mpCanvas->getViewState() );
|
||||
aTotalTransform = aTotalTransform * aTransform;
|
||||
|
||||
// since pure translational changes to the transformation
|
||||
// does not matter, remove them before comparing
|
||||
aTotalTransform.set( 0, 2, 0.0 );
|
||||
aTotalTransform.set( 1, 2, 0.0 );
|
||||
|
||||
// as soon as the total transformation changes, we've got
|
||||
// to re-render the bitmap
|
||||
if( aTotalTransform != maLastTransformation)
|
||||
TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
|
||||
const Renderer::Parameters& rParms,
|
||||
const ::Point& rDstPoint,
|
||||
const ::Size& rDstSize,
|
||||
double nAlpha,
|
||||
const CanvasSharedPtr& rCanvas,
|
||||
const OutDevState& rState ) :
|
||||
mpGroupMtf( rGroupMtf ),
|
||||
mpAlphaGradient(),
|
||||
maParms( rParms ),
|
||||
maDstSize( rDstSize ),
|
||||
mxBufferBitmap(),
|
||||
maLastTransformation(),
|
||||
mpCanvas( rCanvas ),
|
||||
maState(),
|
||||
mnAlpha( nAlpha )
|
||||
{
|
||||
DBG_TESTSOLARMUTEX();
|
||||
tools::initRenderState(maState,rState);
|
||||
implSetupTransform( maState, rDstPoint );
|
||||
|
||||
// determine total scaling factor of the
|
||||
// transformation matrix - need to make the bitmap
|
||||
// large enough
|
||||
::basegfx::B2DTuple aScale;
|
||||
::basegfx::B2DTuple aTranslate;
|
||||
double nRotate;
|
||||
double nShearX;
|
||||
if( !aTotalTransform.decompose( aScale,
|
||||
aTranslate,
|
||||
nRotate,
|
||||
nShearX ) )
|
||||
maLastSubset.mnSubsetBegin = 0;
|
||||
maLastSubset.mnSubsetEnd = -1;
|
||||
}
|
||||
|
||||
TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
|
||||
GradientAutoPtr& rAlphaGradient,
|
||||
const Renderer::Parameters& rParms,
|
||||
const ::Point& rDstPoint,
|
||||
const ::Size& rDstSize,
|
||||
const CanvasSharedPtr& rCanvas,
|
||||
const OutDevState& rState ) :
|
||||
mpGroupMtf( rGroupMtf ),
|
||||
mpAlphaGradient( rAlphaGradient ),
|
||||
maParms( rParms ),
|
||||
maDstSize( rDstSize ),
|
||||
mxBufferBitmap(),
|
||||
maLastTransformation(),
|
||||
mpCanvas( rCanvas ),
|
||||
maState(),
|
||||
mnAlpha( 1.0 )
|
||||
{
|
||||
tools::initRenderState(maState,rState);
|
||||
implSetupTransform( maState, rDstPoint );
|
||||
|
||||
maLastSubset.mnSubsetBegin = 0;
|
||||
maLastSubset.mnSubsetEnd = -1;
|
||||
}
|
||||
|
||||
// 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& rSubset ) const
|
||||
{
|
||||
RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" );
|
||||
RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this );
|
||||
|
||||
// determine overall transformation matrix (render, view,
|
||||
// and passed transformation)
|
||||
::basegfx::B2DHomMatrix aTransform;
|
||||
::canvas::tools::getRenderStateTransform( aTransform, maState );
|
||||
aTransform = rTransformation * aTransform;
|
||||
|
||||
::basegfx::B2DHomMatrix aTotalTransform;
|
||||
::canvas::tools::getViewStateTransform( aTotalTransform, mpCanvas->getViewState() );
|
||||
aTotalTransform = aTotalTransform * aTransform;
|
||||
|
||||
// since pure translational changes to the transformation
|
||||
// does not matter, remove them before comparing
|
||||
aTotalTransform.set( 0, 2, 0.0 );
|
||||
aTotalTransform.set( 1, 2, 0.0 );
|
||||
|
||||
// as soon as the total transformation changes, we've got
|
||||
// to re-render the bitmap
|
||||
if( aTotalTransform != maLastTransformation ||
|
||||
rSubset.mnSubsetBegin != maLastSubset.mnSubsetBegin ||
|
||||
rSubset.mnSubsetEnd != maLastSubset.mnSubsetEnd )
|
||||
{
|
||||
OSL_ENSURE( false,
|
||||
"TransparencyGroupAction::render(): non-decomposable transformation" );
|
||||
return false;
|
||||
DBG_TESTSOLARMUTEX();
|
||||
|
||||
// determine total scaling factor of the
|
||||
// transformation matrix - need to make the bitmap
|
||||
// large enough
|
||||
::basegfx::B2DTuple aScale;
|
||||
::basegfx::B2DTuple aTranslate;
|
||||
double nRotate;
|
||||
double nShearX;
|
||||
if( !aTotalTransform.decompose( aScale,
|
||||
aTranslate,
|
||||
nRotate,
|
||||
nShearX ) )
|
||||
{
|
||||
OSL_ENSURE( false,
|
||||
"TransparencyGroupAction::render(): non-decomposable transformation" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// output size of metafile
|
||||
::Size aOutputSizePixel( ::basegfx::fround( aScale.getX() * maDstSize.Width() ),
|
||||
::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
|
||||
// VirtualDevice with alpha channel
|
||||
VirtualDevice aVDev(
|
||||
*::Application::GetDefaultDevice(), 0, 0 );
|
||||
aVDev.SetOutputSizePixel( aBitmapSizePixel );
|
||||
aVDev.SetMapMode();
|
||||
|
||||
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,
|
||||
aEmptyPoint,
|
||||
aOutputSizePixel,
|
||||
*mpAlphaGradient );
|
||||
}
|
||||
|
||||
|
||||
// update buffered bitmap and transformation
|
||||
BitmapSharedPtr aBmp( VCLFactory::getInstance().createBitmap(
|
||||
mpCanvas,
|
||||
aVDev.GetBitmapEx(
|
||||
aEmptyPoint,
|
||||
aBitmapSizePixel ) ) );
|
||||
mxBufferBitmap = aBmp->getUNOBitmap();
|
||||
maLastTransformation = aTotalTransform;
|
||||
maLastSubset = rSubset;
|
||||
}
|
||||
|
||||
::Size aSize( ::basegfx::fround( aScale.getX() * maDstSize.Width() ),
|
||||
::basegfx::fround( aScale.getY() * maDstSize.Height() ) );
|
||||
// determine target transformation (we can't simply pass
|
||||
// aTotalTransform as assembled above, since we must take
|
||||
// the canvas' view state as is, it might contain clipping
|
||||
// (which, in turn, is relative to the view
|
||||
// transformation))
|
||||
|
||||
// render our content into an appropriately sized
|
||||
// VirtualDevice with alpha channel
|
||||
VirtualDevice aVDev(
|
||||
*::Application::GetDefaultDevice(), 0, 0 );
|
||||
aVDev.SetOutputSizePixel( aSize );
|
||||
aVDev.SetMapMode();
|
||||
// given that aTotalTransform is the identity
|
||||
// transformation, we could simply render our bitmap
|
||||
// as-is. Now, since the mxBufferBitmap content already
|
||||
// accounts for scale changes in the overall
|
||||
// transformation, we must factor this out
|
||||
// before. Generally, the transformation matrix should be
|
||||
// structured like this:
|
||||
// Translation*Rotation*Shear*Scale. Thus, to neutralize
|
||||
// the contained scaling, we've got to right-multiply with
|
||||
// the inverse.
|
||||
::basegfx::B2ISize aBmpSize(
|
||||
::basegfx::unotools::b2ISizeFromIntegerSize2D( mxBufferBitmap->getSize() ) );
|
||||
|
||||
::Point aEmptyPoint;
|
||||
aVDev.DrawTransparent( *mpGroupMtf,
|
||||
aEmptyPoint,
|
||||
aSize,
|
||||
*mpAlphaGradient );
|
||||
::basegfx::B2DHomMatrix aScaleCorrection;
|
||||
aScaleCorrection.scale( (double)maDstSize.Width() / aBmpSize.getX(),
|
||||
(double)maDstSize.Height() / aBmpSize.getY() );
|
||||
aTransform = aTransform * aScaleCorrection;
|
||||
|
||||
rendering::RenderState aLocalState( maState );
|
||||
::canvas::tools::setRenderStateTransform(aLocalState, aTransform);
|
||||
|
||||
// update buffered bitmap and transformation
|
||||
BitmapSharedPtr aBmp( VCLFactory::getInstance().createBitmap(
|
||||
mpCanvas,
|
||||
aVDev.GetBitmapEx(
|
||||
aEmptyPoint,
|
||||
aSize ) ) );
|
||||
mxBufferBitmap = aBmp->getUNOBitmap();
|
||||
maLastTransformation = aTotalTransform;
|
||||
if( ::rtl::math::approxEqual(mnAlpha, 1.0) )
|
||||
{
|
||||
// no further alpha changes necessary -> draw directly
|
||||
mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
|
||||
mpCanvas->getViewState(),
|
||||
aLocalState );
|
||||
}
|
||||
else
|
||||
{
|
||||
// add alpha modulation value to DeviceColor
|
||||
aLocalState.DeviceColor.realloc(4);
|
||||
aLocalState.DeviceColor[0] = 1.0;
|
||||
aLocalState.DeviceColor[1] = 1.0;
|
||||
aLocalState.DeviceColor[2] = 1.0;
|
||||
aLocalState.DeviceColor[3] = mnAlpha;
|
||||
mpCanvas->getUNOCanvas()->drawBitmapModulated( mxBufferBitmap,
|
||||
mpCanvas->getViewState(),
|
||||
aLocalState );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// determine target transformation (we can't simply pass
|
||||
// aTotalTransform as assembled above, since we must take
|
||||
// the canvas' view state as is, it might contain clipping
|
||||
// (which, in turn, is relative to the view
|
||||
// transformation))
|
||||
|
||||
// given that aTotalTransform is the identity
|
||||
// transformation, we could simply render our bitmap
|
||||
// as-is. Now, since the mxBufferBitmap content already
|
||||
// accounts for scale changes in the overall
|
||||
// transformation, we must factor this out
|
||||
// before. Generally, the transformation matrix should be
|
||||
// structured like this:
|
||||
// Translation*Rotation*Shear*Scale. Thus, to neutralize
|
||||
// the contained scaling, we've got to right-multiply with
|
||||
// the inverse.
|
||||
::basegfx::B2ISize aBmpSize(
|
||||
::basegfx::unotools::b2ISizeFromIntegerSize2D( mxBufferBitmap->getSize() ) );
|
||||
|
||||
::basegfx::B2DHomMatrix aScaleCorrection;
|
||||
aScaleCorrection.scale( (double)maDstSize.Width() / aBmpSize.getX(),
|
||||
(double)maDstSize.Height() / aBmpSize.getY() );
|
||||
aTransform = aTransform * aScaleCorrection;
|
||||
|
||||
rendering::RenderState aLocalState( maState );
|
||||
::canvas::tools::setRenderStateTransform(aLocalState, aTransform);
|
||||
|
||||
if( ::rtl::math::approxEqual(mnAlpha, 1.0) )
|
||||
// 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
|
||||
{
|
||||
// no further alpha changes necessary -> draw directly
|
||||
mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
|
||||
mpCanvas->getViewState(),
|
||||
aLocalState );
|
||||
}
|
||||
else
|
||||
{
|
||||
// add alpha modulation value to DeviceColor
|
||||
aLocalState.DeviceColor.realloc(4);
|
||||
aLocalState.DeviceColor[0] = 1.0;
|
||||
aLocalState.DeviceColor[1] = 1.0;
|
||||
aLocalState.DeviceColor[2] = 1.0;
|
||||
aLocalState.DeviceColor[3] = mnAlpha;
|
||||
mpCanvas->getUNOCanvas()->drawBitmapModulated( mxBufferBitmap,
|
||||
mpCanvas->getViewState(),
|
||||
aLocalState );
|
||||
Subset aSubset;
|
||||
|
||||
aSubset.mnSubsetBegin = 0;
|
||||
aSubset.mnSubsetEnd = -1;
|
||||
|
||||
return render( rTransformation, aSubset );
|
||||
}
|
||||
|
||||
return true;
|
||||
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 ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user