diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-03-13 14:26:54 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-03-13 15:32:42 +0100 |
commit | a93d940186f65005141eea3bebdfb4c66cebe8f8 (patch) | |
tree | 5af8b2fcffbe8f9ed35226d7fbda3719b9209903 /canvas/source | |
parent | 9d81a7ae6da283e0daa299177abd55b09d10964f (diff) |
make transformBitmap code from canvas to vcl
part of making ScopedWriteAccess an internal detail of vcl
Change-Id: Ida03bc73fe746cde97f6fcb5cde2f066b63d92e9
Reviewed-on: https://gerrit.libreoffice.org/51216
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'canvas/source')
-rw-r--r-- | canvas/source/vcl/impltools.cxx | 161 |
1 files changed, 2 insertions, 159 deletions
diff --git a/canvas/source/vcl/impltools.cxx b/canvas/source/vcl/impltools.cxx index dd0ca8a0714b..529a0b7fdf91 100644 --- a/canvas/source/vcl/impltools.cxx +++ b/canvas/source/vcl/impltools.cxx @@ -42,6 +42,7 @@ #include <vcl/bitmapex.hxx> #include <vcl/bitmapaccess.hxx> #include <vcl/canvastools.hxx> +#include <vcl/BitmapTools.hxx> #include <vcl/metric.hxx> #include <vcl/salbtype.hxx> @@ -209,8 +210,6 @@ namespace vclcanvas const Size aBmpSize( rBitmap.GetSizePixel() ); ::basegfx::B2DRectangle aDestRect; - bool bCopyBack( false ); - // calc effective transformation for bitmap const ::basegfx::B2DRectangle aSrcRect( 0, 0, aBmpSize.Width(), @@ -228,163 +227,7 @@ namespace vclcanvas aSrcRect, rTransform ); - Bitmap aSrcBitmap( rBitmap.GetBitmap() ); - Bitmap aSrcAlpha; - - // differentiate mask and alpha channel (on-off - // vs. multi-level transparency) - if( rBitmap.IsTransparent() ) - { - if( rBitmap.IsAlpha() ) - aSrcAlpha = rBitmap.GetAlpha().GetBitmap(); - else - aSrcAlpha = rBitmap.GetMask(); - } - - Bitmap::ScopedReadAccess pReadAccess( aSrcBitmap ); - Bitmap::ScopedReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ? - aSrcAlpha.AcquireReadAccess() : - nullptr, - aSrcAlpha ); - - if( pReadAccess.get() == nullptr || - (pAlphaReadAccess.get() == nullptr && rBitmap.IsTransparent()) ) - { - // TODO(E2): Error handling! - ENSURE_OR_THROW( false, - "transformBitmap(): could not access source bitmap" ); - } - - // mapping table, to translate pAlphaReadAccess' pixel - // values into destination alpha values (needed e.g. for - // paletted 1-bit masks). - sal_uInt8 aAlphaMap[256]; - - if( rBitmap.IsTransparent() ) - { - if( rBitmap.IsAlpha() ) - { - // source already has alpha channel - 1:1 mapping, - // i.e. aAlphaMap[0]=0,...,aAlphaMap[255]=255. - sal_uInt8 val=0; - sal_uInt8* pCur=aAlphaMap; - sal_uInt8* const pEnd=&aAlphaMap[256]; - while(pCur != pEnd) - *pCur++ = val++; - } - else - { - // mask transparency - determine used palette colors - const BitmapColor& rCol0( pAlphaReadAccess->GetPaletteColor( 0 ) ); - const BitmapColor& rCol1( pAlphaReadAccess->GetPaletteColor( 1 ) ); - - // shortcut for true luminance calculation - // (assumes that palette is grey-level) - aAlphaMap[0] = rCol0.GetRed(); - aAlphaMap[1] = rCol1.GetRed(); - } - } - // else: mapping table is not used - - const Size aDestBmpSize( ::basegfx::fround( aDestRect.getWidth() ), - ::basegfx::fround( aDestRect.getHeight() ) ); - - if( aDestBmpSize.Width() == 0 || aDestBmpSize.Height() == 0 ) - return BitmapEx(); - - Bitmap aDstBitmap( aDestBmpSize, aSrcBitmap.GetBitCount(), &pReadAccess->GetPalette() ); - Bitmap aDstAlpha( AlphaMask( aDestBmpSize ).GetBitmap() ); - - { - // just to be on the safe side: let the - // ScopedAccessors get destructed before - // copy-constructing the resulting bitmap. This will - // rule out the possibility that cached accessor data - // is not yet written back. - Bitmap::ScopedWriteAccess pWriteAccess( aDstBitmap ); - Bitmap::ScopedWriteAccess pAlphaWriteAccess( aDstAlpha ); - - - if( pWriteAccess.get() != nullptr && - pAlphaWriteAccess.get() != nullptr && - rTransform.isInvertible() ) - { - // we're doing inverse mapping here, i.e. mapping - // points from the destination bitmap back to the - // source - ::basegfx::B2DHomMatrix aTransform( aLocalTransform ); - aTransform.invert(); - - // for the time being, always read as ARGB - for( long y=0; y<aDestBmpSize.Height(); ++y ) - { - // differentiate mask and alpha channel (on-off - // vs. multi-level transparency) - if( rBitmap.IsTransparent() ) - { - Scanline pScan = pWriteAccess->GetScanline( y ); - Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y ); - // Handling alpha and mask just the same... - for( long x=0; x<aDestBmpSize.Width(); ++x ) - { - ::basegfx::B2DPoint aPoint(x,y); - aPoint *= aTransform; - - const int nSrcX( ::basegfx::fround( aPoint.getX() ) ); - const int nSrcY( ::basegfx::fround( aPoint.getY() ) ); - if( nSrcX < 0 || nSrcX >= aBmpSize.Width() || - nSrcY < 0 || nSrcY >= aBmpSize.Height() ) - { - pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) ); - } - else - { - const sal_uInt8 cAlphaIdx = pAlphaReadAccess->GetPixelIndex( nSrcY, nSrcX ); - pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(aAlphaMap[ cAlphaIdx ]) ); - pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY, nSrcX ) ); - } - } - } - else - { - Scanline pScan = pWriteAccess->GetScanline( y ); - Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y ); - for( long x=0; x<aDestBmpSize.Width(); ++x ) - { - ::basegfx::B2DPoint aPoint(x,y); - aPoint *= aTransform; - - const int nSrcX( ::basegfx::fround( aPoint.getX() ) ); - const int nSrcY( ::basegfx::fround( aPoint.getY() ) ); - if( nSrcX < 0 || nSrcX >= aBmpSize.Width() || - nSrcY < 0 || nSrcY >= aBmpSize.Height() ) - { - pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) ); - } - else - { - pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(0) ); - pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY, - nSrcX ) ); - } - } - } - } - - bCopyBack = true; - } - else - { - // TODO(E2): Error handling! - ENSURE_OR_THROW( false, - "transformBitmap(): could not access bitmap" ); - } - } - - if( bCopyBack ) - return BitmapEx( aDstBitmap, AlphaMask( aDstAlpha ) ); - else - return BitmapEx(); + return vcl::bitmap::CanvasTransformBitmap(rBitmap, rTransform, aDestRect, aLocalTransform); } } } |