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 $
|
* $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,180 +241,345 @@ 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,
|
||||||
const ::Point& rDstPoint,
|
const ::Point& rDstPoint,
|
||||||
const ::Size& rDstSize,
|
const ::Size& rDstSize,
|
||||||
double nAlpha,
|
double nAlpha,
|
||||||
const CanvasSharedPtr& rCanvas,
|
const CanvasSharedPtr& rCanvas,
|
||||||
const OutDevState& rState ) :
|
const OutDevState& rState ) :
|
||||||
mpGroupMtf( rGroupMtf ),
|
mpGroupMtf( rGroupMtf ),
|
||||||
mpAlphaGradient(),
|
mpAlphaGradient(),
|
||||||
maParms( rParms ),
|
maParms( rParms ),
|
||||||
maDstSize( rDstSize ),
|
maDstSize( rDstSize ),
|
||||||
mxBufferBitmap(),
|
mxBufferBitmap(),
|
||||||
maLastTransformation(),
|
maLastTransformation(),
|
||||||
mpCanvas( rCanvas ),
|
mpCanvas( rCanvas ),
|
||||||
maState(),
|
maState(),
|
||||||
mnAlpha( nAlpha )
|
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)
|
|
||||||
{
|
{
|
||||||
DBG_TESTSOLARMUTEX();
|
tools::initRenderState(maState,rState);
|
||||||
|
implSetupTransform( maState, rDstPoint );
|
||||||
|
|
||||||
// determine total scaling factor of the
|
maLastSubset.mnSubsetBegin = 0;
|
||||||
// transformation matrix - need to make the bitmap
|
maLastSubset.mnSubsetEnd = -1;
|
||||||
// large enough
|
}
|
||||||
::basegfx::B2DTuple aScale;
|
|
||||||
::basegfx::B2DTuple aTranslate;
|
TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr& rGroupMtf,
|
||||||
double nRotate;
|
GradientAutoPtr& rAlphaGradient,
|
||||||
double nShearX;
|
const Renderer::Parameters& rParms,
|
||||||
if( !aTotalTransform.decompose( aScale,
|
const ::Point& rDstPoint,
|
||||||
aTranslate,
|
const ::Size& rDstSize,
|
||||||
nRotate,
|
const CanvasSharedPtr& rCanvas,
|
||||||
nShearX ) )
|
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,
|
DBG_TESTSOLARMUTEX();
|
||||||
"TransparencyGroupAction::render(): non-decomposable transformation" );
|
|
||||||
return false;
|
// 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() ),
|
// determine target transformation (we can't simply pass
|
||||||
::basegfx::fround( aScale.getY() * maDstSize.Height() ) );
|
// 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
|
// given that aTotalTransform is the identity
|
||||||
// VirtualDevice with alpha channel
|
// transformation, we could simply render our bitmap
|
||||||
VirtualDevice aVDev(
|
// as-is. Now, since the mxBufferBitmap content already
|
||||||
*::Application::GetDefaultDevice(), 0, 0 );
|
// accounts for scale changes in the overall
|
||||||
aVDev.SetOutputSizePixel( aSize );
|
// transformation, we must factor this out
|
||||||
aVDev.SetMapMode();
|
// 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;
|
::basegfx::B2DHomMatrix aScaleCorrection;
|
||||||
aVDev.DrawTransparent( *mpGroupMtf,
|
aScaleCorrection.scale( (double)maDstSize.Width() / aBmpSize.getX(),
|
||||||
aEmptyPoint,
|
(double)maDstSize.Height() / aBmpSize.getY() );
|
||||||
aSize,
|
aTransform = aTransform * aScaleCorrection;
|
||||||
*mpAlphaGradient );
|
|
||||||
|
|
||||||
|
rendering::RenderState aLocalState( maState );
|
||||||
|
::canvas::tools::setRenderStateTransform(aLocalState, aTransform);
|
||||||
|
|
||||||
// update buffered bitmap and transformation
|
if( ::rtl::math::approxEqual(mnAlpha, 1.0) )
|
||||||
BitmapSharedPtr aBmp( VCLFactory::getInstance().createBitmap(
|
{
|
||||||
mpCanvas,
|
// no further alpha changes necessary -> draw directly
|
||||||
aVDev.GetBitmapEx(
|
mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
|
||||||
aEmptyPoint,
|
mpCanvas->getViewState(),
|
||||||
aSize ) ) );
|
aLocalState );
|
||||||
mxBufferBitmap = aBmp->getUNOBitmap();
|
}
|
||||||
maLastTransformation = aTotalTransform;
|
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
|
// TODO(P3): The whole float transparency handling is a mess,
|
||||||
// aTotalTransform as assembled above, since we must take
|
// this should be refactored. What's more, the old idea of
|
||||||
// the canvas' view state as is, it might contain clipping
|
// having only internal 'metaactions', and not the original
|
||||||
// (which, in turn, is relative to the view
|
// GDIMetaFile now looks a lot less attractive. Try to move
|
||||||
// transformation))
|
// into the direction of having a direct GDIMetaFile2XCanvas
|
||||||
|
// renderer, and maybe a separate metafile XCanvas
|
||||||
// given that aTotalTransform is the identity
|
// implementation.
|
||||||
// transformation, we could simply render our bitmap
|
bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
|
||||||
// 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) )
|
|
||||||
{
|
{
|
||||||
// no further alpha changes necessary -> draw directly
|
Subset aSubset;
|
||||||
mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
|
|
||||||
mpCanvas->getViewState(),
|
aSubset.mnSubsetBegin = 0;
|
||||||
aLocalState );
|
aSubset.mnSubsetEnd = -1;
|
||||||
}
|
|
||||||
else
|
return render( rTransformation, aSubset );
|
||||||
{
|
|
||||||
// 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;
|
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