From 16b7ec7b2e4cc4f0962513c646cb46589ff78c12 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Thu, 15 Mar 2018 09:06:49 +0200 Subject: move emf code to vcl part of making ScopedWriteAccess an internal detail of vcl Change-Id: If66de7c248d442a860508bbddf68e390983da240 Reviewed-on: https://gerrit.libreoffice.org/51309 Tested-by: Jenkins Reviewed-by: Michael Meeks --- emfio/source/reader/mtftools.cxx | 86 +------------------------------------ include/vcl/BitmapTools.hxx | 2 + vcl/source/bitmap/BitmapTools.cxx | 90 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 84 deletions(-) diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx index 458386a3494f..e231cf00ef04 100644 --- a/emfio/source/reader/mtftools.cxx +++ b/emfio/source/reader/mtftools.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1627,90 +1628,7 @@ namespace emfio BitmapEx aBmpEx( rBitmap ); if ( mbComplexClip ) { - VclPtrInstance< VirtualDevice > pVDev; - MapMode aMapMode( MapUnit::Map100thMM ); - aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) ); - const Size aOutputSizePixel( pVDev->LogicToPixel( rSize, aMapMode ) ); - const Size aSizePixel( rBitmap.GetSizePixel() ); - if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() ) - { - aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) ); - aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) ); - } - pVDev->SetMapMode( aMapMode ); - pVDev->SetOutputSizePixel( aSizePixel ); - pVDev->SetFillColor( COL_BLACK ); - const tools::PolyPolygon aClip( maClipPath.getClipPath() ); - pVDev->DrawPolyPolygon( aClip ); - const Point aEmptyPoint; - - // #i50672# Extract whole VDev content (to match size of rBitmap) - pVDev->EnableMapMode( false ); - const Bitmap aVDevMask(pVDev->GetBitmap(aEmptyPoint, aSizePixel)); - - if(aBmpEx.IsTransparent()) - { - // bitmap already uses a Mask or Alpha, we need to blend that with - // the new masking in pVDev - if(aBmpEx.IsAlpha()) - { - // need to blend in AlphaMask quality (8Bit) - AlphaMask fromVDev(aVDevMask); - AlphaMask fromBmpEx(aBmpEx.GetAlpha()); - AlphaMask::ScopedReadAccess pR(fromVDev); - AlphaMask::ScopedWriteAccess pW(fromBmpEx); - - if(pR && pW) - { - const long nWidth(std::min(pR->Width(), pW->Width())); - const long nHeight(std::min(pR->Height(), pW->Height())); - - for(long nY(0); nY < nHeight; nY++) - { - Scanline pScanlineR = pR->GetScanline( nY ); - Scanline pScanlineW = pW->GetScanline( nY ); - for(long nX(0); nX < nWidth; nX++) - { - const sal_uInt8 nIndR(pR->GetIndexFromData(pScanlineR, nX)); - const sal_uInt8 nIndW(pW->GetIndexFromData(pScanlineW, nX)); - - // these values represent transparency (0 == no, 255 == fully transparent), - // so to blend these we have to multiply the inverse (opacity) - // and re-invert the result to transparence - const sal_uInt8 nCombined(0x00ff - (((0x00ff - nIndR) * (0x00ff - nIndW)) >> 8)); - - pW->SetPixelOnData(pScanlineW, nX, BitmapColor(nCombined)); - } - } - } - - pR.reset(); - pW.reset(); - aBmpEx = BitmapEx(aBmpEx.GetBitmap(), fromBmpEx); - } - else - { - // need to blend in Mask quality (1Bit) - Bitmap aMask(aVDevMask.CreateMask(COL_WHITE)); - - if ( rBitmap.GetTransparentColor() == COL_WHITE ) - { - aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::Or ); - } - else - { - aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::And ); - } - - aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask ); - } - } - else - { - // no mask yet, create and add new mask. For better quality, use Alpha, - // this allows the drawn mask being processed with AntiAliasing (AAed) - aBmpEx = BitmapEx(rBitmap.GetBitmap(), aVDevMask); - } + vcl::bitmap::DrawAndClipBitmap(rPos, rSize, rBitmap, aBmpEx, maClipPath.getClipPath()); } if ( aBmpEx.IsTransparent() ) diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx index 7dde62788a53..6ff484a82d9c 100644 --- a/include/vcl/BitmapTools.hxx +++ b/include/vcl/BitmapTools.hxx @@ -94,6 +94,8 @@ VCL_DLLPUBLIC BitmapEx CanvasTransformBitmap( const BitmapEx& rBitmap, VCL_DLLPUBLIC void DrawAlphaBitmapAndAlphaGradient(BitmapEx & rBitmapEx, bool bFixedTransparence, float fTransparence, AlphaMask & rNewMask); +VCL_DLLPUBLIC void DrawAndClipBitmap(const Point& rPos, const Size& rSize, const BitmapEx& rBitmap, BitmapEx & aBmpEx, basegfx::B2DPolyPolygon const & rClipPath); + }} // end vcl::bitmap #endif // INCLUDED_VCL_BITMAP_TOOLS_HXX diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx index f29989b9cab2..e750a63880e5 100644 --- a/vcl/source/bitmap/BitmapTools.cxx +++ b/vcl/source/bitmap/BitmapTools.cxx @@ -26,10 +26,12 @@ #include #include #include +#include #if ENABLE_CAIRO_CANVAS #include #endif #include +#include using namespace css; @@ -537,6 +539,94 @@ void DrawAlphaBitmapAndAlphaGradient(BitmapEx & rBitmapEx, bool bFixedTransparen rBitmapEx = BitmapEx(rBitmapEx.GetBitmap(), aOldMask); } + +void DrawAndClipBitmap(const Point& rPos, const Size& rSize, const BitmapEx& rBitmap, BitmapEx & aBmpEx, basegfx::B2DPolyPolygon const & rClipPath) +{ + VclPtrInstance< VirtualDevice > pVDev; + MapMode aMapMode( MapUnit::Map100thMM ); + aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) ); + const Size aOutputSizePixel( pVDev->LogicToPixel( rSize, aMapMode ) ); + const Size aSizePixel( rBitmap.GetSizePixel() ); + if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() ) + { + aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) ); + aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) ); + } + pVDev->SetMapMode( aMapMode ); + pVDev->SetOutputSizePixel( aSizePixel ); + pVDev->SetFillColor( COL_BLACK ); + const tools::PolyPolygon aClip( rClipPath ); + pVDev->DrawPolyPolygon( aClip ); + + // #i50672# Extract whole VDev content (to match size of rBitmap) + pVDev->EnableMapMode( false ); + const Bitmap aVDevMask(pVDev->GetBitmap(Point(), aSizePixel)); + + if(aBmpEx.IsTransparent()) + { + // bitmap already uses a Mask or Alpha, we need to blend that with + // the new masking in pVDev + if(aBmpEx.IsAlpha()) + { + // need to blend in AlphaMask quality (8Bit) + AlphaMask fromVDev(aVDevMask); + AlphaMask fromBmpEx(aBmpEx.GetAlpha()); + AlphaMask::ScopedReadAccess pR(fromVDev); + AlphaMask::ScopedWriteAccess pW(fromBmpEx); + + if(pR && pW) + { + const long nWidth(std::min(pR->Width(), pW->Width())); + const long nHeight(std::min(pR->Height(), pW->Height())); + + for(long nY(0); nY < nHeight; nY++) + { + Scanline pScanlineR = pR->GetScanline( nY ); + Scanline pScanlineW = pW->GetScanline( nY ); + for(long nX(0); nX < nWidth; nX++) + { + const sal_uInt8 nIndR(pR->GetIndexFromData(pScanlineR, nX)); + const sal_uInt8 nIndW(pW->GetIndexFromData(pScanlineW, nX)); + + // these values represent transparency (0 == no, 255 == fully transparent), + // so to blend these we have to multiply the inverse (opacity) + // and re-invert the result to transparence + const sal_uInt8 nCombined(0x00ff - (((0x00ff - nIndR) * (0x00ff - nIndW)) >> 8)); + + pW->SetPixelOnData(pScanlineW, nX, BitmapColor(nCombined)); + } + } + } + + pR.reset(); + pW.reset(); + aBmpEx = BitmapEx(aBmpEx.GetBitmap(), fromBmpEx); + } + else + { + // need to blend in Mask quality (1Bit) + Bitmap aMask(aVDevMask.CreateMask(COL_WHITE)); + + if ( rBitmap.GetTransparentColor() == COL_WHITE ) + { + aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::Or ); + } + else + { + aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::And ); + } + + aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask ); + } + } + else + { + // no mask yet, create and add new mask. For better quality, use Alpha, + // this allows the drawn mask being processed with AntiAliasing (AAed) + aBmpEx = BitmapEx(rBitmap.GetBitmap(), aVDevMask); + } +} + }} // end vcl::bitmap /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit