summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cppcanvas/source/mtfrenderer/transparencygroupaction.cxx67
-rw-r--r--include/vcl/outdev.hxx5
-rw-r--r--vcl/source/outdev/transparent.cxx28
3 files changed, 86 insertions, 14 deletions
diff --git a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx
index b8350a8f3944..e0caeaa7cf2a 100644
--- a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx
+++ b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx
@@ -205,6 +205,8 @@ namespace cppcanvas::internal
return false;
}
+ ::Point aMtfOffsetPoint;
+
// if there's no buffer bitmap, or as soon as the
// total transformation changes, we've got to
// re-render the bitmap
@@ -215,15 +217,59 @@ namespace cppcanvas::internal
{
DBG_TESTSOLARMUTEX();
+ // tdf#150610 fix broken rendering of text meta actions
+ // Even when drawing to a VirtualDevice where antialiasing
+ // is disabled, text will still be drawn with some
+ // antialiased pixels on HiDPI displays. So, expand the
+ // size of the VirtualDevice slightly to capture any of
+ // the pixles drawn past the edges of the destination
+ // bounds.
+ bool bHasTextActions = false;
+ MetaAction* pCurrAct;
+ int nCurrActionIndex;
+ for( nCurrActionIndex=0, pCurrAct=mpGroupMtf->FirstAction();
+ pCurrAct && !bHasTextActions;
+ ++nCurrActionIndex, pCurrAct = mpGroupMtf->NextAction() )
+ {
+ switch( pCurrAct->GetType() )
+ {
+ case MetaActionType::TEXT:
+ case MetaActionType::TEXTARRAY:
+ case MetaActionType::STRETCHTEXT:
+ case MetaActionType::TEXTRECT:
+ if( ( rSubset.mnSubsetBegin == 0 && rSubset.mnSubsetEnd == -1 ) || ( rSubset.mnSubsetBegin <= nCurrActionIndex && rSubset.mnSubsetEnd > nCurrActionIndex ) )
+ bHasTextActions = true;
+ break;
+ default:
+ break;
+ }
+ }
+
// output size of metafile
::Size aOutputSizePixel( ::basegfx::fround( aScale.getX() * maDstSize.getWidth() ),
::basegfx::fround( aScale.getY() * maDstSize.getHeight() ) );
- // pixel size of cache bitmap: round up to nearest int
- ::Size aBitmapSizePixel( static_cast<sal_Int32>( aScale.getX() * maDstSize.getWidth() )+1,
- static_cast<sal_Int32>( aScale.getY() * maDstSize.getHeight() )+1 );
+ sal_Int32 nBitmapExtra;
+ if ( bHasTextActions )
+ {
+ nBitmapExtra = 10;
+ aMtfOffsetPoint = ::Point( nBitmapExtra / 2, nBitmapExtra / 2 );
+ }
+ else
+ {
+ // Related tdf#150610 assume antialiasing is enabled
+ // Although antialiasing is normally disabled in the
+ // VirtualDevice, lines in tdf#150610 will draw past
+ // the edge of the VirtualDevice when running a
+ // slideshow so always add an extra pixel on the
+ // right and bottom edges.
+ nBitmapExtra = 1;
+ }
- ::Point aEmptyPoint;
+ // pixel size of cache bitmap: round up to nearest int
+ ::Point aBitmapPoint;
+ ::Size aBitmapSizePixel( static_cast<sal_Int32>( aScale.getX() * maDstSize.getWidth() ) + nBitmapExtra,
+ static_cast<sal_Int32>( aScale.getY() * maDstSize.getHeight() ) + nBitmapExtra );
// render our content into an appropriately sized
// VirtualDevice with alpha channel
@@ -238,8 +284,6 @@ namespace cppcanvas::internal
// true subset - extract referenced
// metaactions from mpGroupMtf
GDIMetaFile aMtf;
- MetaAction* pCurrAct;
- int nCurrActionIndex;
// extract subset actions
for( nCurrActionIndex=0,
@@ -320,7 +364,9 @@ namespace cppcanvas::internal
}
aVDev->DrawTransparent( aMtf,
- aEmptyPoint,
+ aBitmapPoint,
+ aBitmapSizePixel,
+ aMtfOffsetPoint,
aOutputSizePixel,
*mpAlphaGradient );
}
@@ -328,7 +374,9 @@ namespace cppcanvas::internal
{
// no subsetting - render whole mtf
aVDev->DrawTransparent( *mpGroupMtf,
- aEmptyPoint,
+ aBitmapPoint,
+ aBitmapSizePixel,
+ aMtfOffsetPoint,
aOutputSizePixel,
*mpAlphaGradient );
}
@@ -338,7 +386,7 @@ namespace cppcanvas::internal
BitmapSharedPtr aBmp( VCLFactory::createBitmap(
mpCanvas,
aVDev->GetBitmapEx(
- aEmptyPoint,
+ aBitmapPoint,
aBitmapSizePixel ) ) );
mxBufferBitmap = aBmp->getUNOBitmap();
maLastTransformation = aTotalTransform;
@@ -362,6 +410,7 @@ namespace cppcanvas::internal
// the contained scaling, we've got to right-multiply with
// the inverse.
::basegfx::B2DHomMatrix aScaleCorrection;
+ aScaleCorrection.translate( -aMtfOffsetPoint.X(), -aMtfOffsetPoint.Y() );
aScaleCorrection.scale( 1/aScale.getX(), 1/aScale.getY() );
aTransform = aTransform * aScaleCorrection;
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index f3d2e912d0a6..898939978daa 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1499,6 +1499,11 @@ public:
const GDIMetaFile& rMtf, const Point& rPos, const Size& rSize,
const Gradient& rTransparenceGradient );
+ void DrawTransparent(
+ const GDIMetaFile& rMtf, const Point& rPos, const Size& rSize,
+ const Point& rMtfPos, const Size& rMtfSize,
+ const Gradient& rTransparenceGradient );
+
protected:
virtual void EmulateDrawTransparent( const tools::PolyPolygon& rPolyPoly, sal_uInt16 nTransparencePercent );
diff --git a/vcl/source/outdev/transparent.cxx b/vcl/source/outdev/transparent.cxx
index f26ca5439982..11f89efc7a27 100644
--- a/vcl/source/outdev/transparent.cxx
+++ b/vcl/source/outdev/transparent.cxx
@@ -557,6 +557,13 @@ void OutputDevice::DrawTransparent( const tools::PolyPolygon& rPolyPoly,
void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
const Size& rSize, const Gradient& rTransparenceGradient )
{
+ DrawTransparent( rMtf, rPos, rSize, rPos, rSize, rTransparenceGradient );
+}
+
+void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos, const Size& rSize,
+ const Point& rMtfPos, const Size& rMtfSize,
+ const Gradient& rTransparenceGradient )
+{
assert(!is_double_buffered_window());
const Color aBlack( COL_BLACK );
@@ -574,7 +581,7 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
( mnDrawMode & DrawModeFlags::NoTransparency ) )
{
const_cast<GDIMetaFile&>(rMtf).WindStart();
- const_cast<GDIMetaFile&>(rMtf).Play(*this, rPos, rSize);
+ const_cast<GDIMetaFile&>(rMtf).Play(*this, rMtfPos, rMtfSize);
const_cast<GDIMetaFile&>(rMtf).WindStart();
}
else
@@ -599,7 +606,13 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
if( xVDev->SetOutputSizePixel( aDstRect.GetSize(), true, true ) )
{
- if(GetAntialiasing() != AntialiasingFlags::NONE)
+ // tdf#150610 fix broken rendering of text meta actions
+ // Even when drawing to a VirtualDevice that has antialiasing
+ // disabled, text will still be drawn with some antialiased
+ // pixels on HiDPI displays. So, use the antialiasing enabled
+ // code to render if there are any text meta actions in the
+ // metafile.
+ if(GetAntialiasing() != AntialiasingFlags::NONE || rPos != rMtfPos || rSize != rMtfSize)
{
// #i102109#
// For MetaFile replay (see task) it may now be necessary to take
@@ -630,7 +643,7 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
// draw MetaFile to buffer
xVDev->EnableMapMode(bBufferMapModeEnabled);
const_cast<GDIMetaFile&>(rMtf).WindStart();
- const_cast<GDIMetaFile&>(rMtf).Play(*xVDev, rPos, rSize);
+ const_cast<GDIMetaFile&>(rMtf).Play(*xVDev, rMtfPos, rMtfSize);
const_cast<GDIMetaFile&>(rMtf).WindStart();
// get content bitmap from buffer
@@ -641,6 +654,11 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
// create alpha mask from gradient and get as Bitmap
xVDev->EnableMapMode(bBufferMapModeEnabled);
xVDev->SetDrawMode(DrawModeFlags::GrayGradient);
+ // Related tdf#150610 draw gradient to VirtualDevice bounds
+ // If we are here and the metafile bounds differs from the
+ // VirtualDevice bounds so that we apply the transparency
+ // gradient to any pixels drawn outside of the metafile
+ // bounds.
xVDev->DrawGradient(tools::Rectangle(rPos, rSize), rTransparenceGradient);
xVDev->SetDrawMode(DrawModeFlags::Default);
xVDev->EnableMapMode(false);
@@ -670,7 +688,7 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
// create paint bitmap
const_cast<GDIMetaFile&>(rMtf).WindStart();
- const_cast<GDIMetaFile&>(rMtf).Play(*xVDev, rPos, rSize);
+ const_cast<GDIMetaFile&>(rMtf).Play(*xVDev, rMtfPos, rMtfSize);
const_cast<GDIMetaFile&>(rMtf).WindStart();
xVDev->EnableMapMode( false );
BitmapEx aPaint = xVDev->GetBitmapEx(Point(), xVDev->GetOutputSizePixel());
@@ -678,7 +696,7 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
// create alpha mask from gradient
xVDev->SetDrawMode( DrawModeFlags::GrayGradient );
- xVDev->DrawGradient( tools::Rectangle( rPos, rSize ), rTransparenceGradient );
+ xVDev->DrawGradient( tools::Rectangle( rMtfPos, rMtfSize ), rTransparenceGradient );
xVDev->SetDrawMode( DrawModeFlags::Default );
xVDev->EnableMapMode( false );