diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-03-09 15:30:53 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-03-10 12:04:19 +0100 |
commit | 676024b001340dce6c854efc3b74bdc8db1e2a3b (patch) | |
tree | 732dc17462b9b6f5316d942e39c18370894e1347 | |
parent | 5b2fc10f0cc9f15525c7723764a1feebeceb0d5e (diff) |
move canvas helper code into vcl
part of making BitmapWriteAccess an internal feature of vcl
Change-Id: Iee94f47e120d82a23e57342952d04e9b2792cd1a
Reviewed-on: https://gerrit.libreoffice.org/50999
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | canvas/source/vcl/canvasbitmaphelper.cxx | 257 | ||||
-rw-r--r-- | include/vcl/BitmapTools.hxx | 9 | ||||
-rw-r--r-- | vcl/source/bitmap/BitmapTools.cxx | 246 |
3 files changed, 260 insertions, 252 deletions
diff --git a/canvas/source/vcl/canvasbitmaphelper.cxx b/canvas/source/vcl/canvasbitmaphelper.cxx index 869957546498..20b823f32cc3 100644 --- a/canvas/source/vcl/canvasbitmaphelper.cxx +++ b/canvas/source/vcl/canvasbitmaphelper.cxx @@ -30,6 +30,7 @@ #include <tools/poly.hxx> #include <vcl/bitmapex.hxx> #include <vcl/bitmapaccess.hxx> +#include <vcl/BitmapTools.hxx> #include <vcl/canvastools.hxx> #include <vcl/window.hxx> @@ -205,222 +206,9 @@ namespace vclcanvas // retrieve local copies from the BitmapEx, which are later // stored back. Unfortunately, the BitmapEx does not permit // in-place modifications, as they are necessary here. - Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() ); - Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() ); - - bool bCopyBack( false ); // only copy something back, if we - // actually changed a pixel - - { - Bitmap::ScopedWriteAccess pWriteAccess( aBitmap ); - Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ? - nullptr : aAlpha.AcquireWriteAccess(), - aAlpha ); - - if( pAlphaWriteAccess.get() ) - { - DBG_ASSERT( pAlphaWriteAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal || - pAlphaWriteAccess->GetScanlineFormat() == ScanlineFormat::N8BitTcMask, - "non-8bit alpha not supported!" ); - } - - ENSURE_OR_THROW( pWriteAccess.get() != nullptr, - "Could not acquire write access to bitmap" ); - - // TODO(F1): Support more formats. - const Size aBmpSize( aBitmap.GetSizePixel() ); - - // for the time being, always read as BGRA - int nCurrPos(0); - for( long y=rect.Y1; - y<aBmpSize.Height() && y<rect.Y2; - ++y ) - { - if( pAlphaWriteAccess.get() != nullptr ) - { - switch( pWriteAccess->GetScanlineFormat() ) - { - case ScanlineFormat::N8BitPal: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - *pScan++ = static_cast<sal_uInt8>(pWriteAccess->GetBestPaletteIndex( - BitmapColor( data[ nCurrPos ], - data[ nCurrPos+1 ], - data[ nCurrPos+2 ] ) )); - - nCurrPos += 3; - - // cast to unsigned byte, for correct subtraction result - *pAScan++ = static_cast<sal_uInt8>(255 - - static_cast<sal_uInt8>(data[ nCurrPos++ ])); - } - } - break; - - case ScanlineFormat::N24BitTcBgr: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - *pScan++ = data[ nCurrPos+2 ]; - *pScan++ = data[ nCurrPos+1 ]; - *pScan++ = data[ nCurrPos ]; - - nCurrPos += 3; - - // cast to unsigned byte, for correct subtraction result - *pAScan++ = static_cast<sal_uInt8>(255 - - static_cast<sal_uInt8>(data[ nCurrPos++ ])); - } - } - break; - - case ScanlineFormat::N24BitTcRgb: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - *pScan++ = data[ nCurrPos ]; - *pScan++ = data[ nCurrPos+1 ]; - *pScan++ = data[ nCurrPos+2 ]; - - nCurrPos += 3; - - // cast to unsigned byte, for correct subtraction result - *pAScan++ = static_cast<sal_uInt8>(255 - - static_cast<sal_uInt8>(data[ nCurrPos++ ])); - } - } - break; - - default: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - pWriteAccess->SetPixelOnData( pScan, x, BitmapColor( data[ nCurrPos ], - data[ nCurrPos+1 ], - data[ nCurrPos+2 ] ) ); - nCurrPos += 3; - - // cast to unsigned byte, for correct subtraction result - pAlphaWriteAccess->SetPixelOnData( pAScan, x, - BitmapColor( - static_cast<sal_uInt8>(255 - - static_cast<sal_uInt8>(data[ nCurrPos++ ])) ) ); - } - } - break; - } - } - else - { - // TODO(Q3): This is copy'n'pasted from - // canvashelper.cxx, unify! - switch( pWriteAccess->GetScanlineFormat() ) - { - case ScanlineFormat::N8BitPal: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - *pScan++ = static_cast<sal_uInt8>(pWriteAccess->GetBestPaletteIndex( - BitmapColor( data[ nCurrPos ], - data[ nCurrPos+1 ], - data[ nCurrPos+2 ] ) )); - - nCurrPos += 4; // skip three colors, _plus_ alpha - } - } - break; - - case ScanlineFormat::N24BitTcBgr: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - *pScan++ = data[ nCurrPos+2 ]; - *pScan++ = data[ nCurrPos+1 ]; - *pScan++ = data[ nCurrPos ]; - - nCurrPos += 4; // skip three colors, _plus_ alpha - } - } - break; - - case ScanlineFormat::N24BitTcRgb: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - *pScan++ = data[ nCurrPos ]; - *pScan++ = data[ nCurrPos+1 ]; - *pScan++ = data[ nCurrPos+2 ]; - - nCurrPos += 4; // skip three colors, _plus_ alpha - } - } - break; - - default: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - - for( long x=rect.X1; - x<aBmpSize.Width() && x<rect.X2; - ++x ) - { - pWriteAccess->SetPixelOnData( pScan, x, BitmapColor( data[ nCurrPos ], - data[ nCurrPos+1 ], - data[ nCurrPos+2 ] ) ); - nCurrPos += 4; // skip three colors, _plus_ alpha - } - } - break; - } - } - - bCopyBack = true; - } - } - // copy back only here, since the BitmapAccessors must be - // destroyed beforehand - if( bCopyBack ) - { - if( aAlpha.IsEmpty() ) - setBitmap( BitmapEx( aBitmap ) ); - else - setBitmap( BitmapEx( aBitmap, - AlphaMask( aAlpha ) ) ); - } + BitmapEx newBitmap = vcl::bitmap::CanvasBitmapHelperSetData(data, rect, mpBackBuffer->getBitmapReference()); + setBitmap( newBitmap ); } void CanvasBitmapHelper::setPixel( const uno::Sequence< sal_Int8 >& color, @@ -448,44 +236,9 @@ namespace vclcanvas aRefLayout.IsMsbFirst != rLayout.IsMsbFirst, "Mismatching memory layout" ); - // retrieve local copies from the BitmapEx, which are later - // stored back. Unfortunately, the BitmapEx does not permit - // in-place modifications, as they are necessary here. - Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() ); - Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() ); - - bool bCopyBack( false ); // only copy something back, if we - // actually changed a pixel - { - Bitmap::ScopedWriteAccess pWriteAccess( aBitmap ); - Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ? - nullptr : aAlpha.AcquireWriteAccess(), - aAlpha ); - - ENSURE_OR_THROW( pWriteAccess.get() != nullptr, - "Could not acquire write access to bitmap" ); - - pWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( color[ 0 ], - color[ 1 ], - color[ 2 ] ) ); - - if( pAlphaWriteAccess.get() != nullptr ) - pAlphaWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( 255 - color[ 3 ] ) ); - - bCopyBack = true; - } - - // copy back only here, since the BitmapAccessors must be - // destroyed beforehand - if( bCopyBack ) - { - if( aAlpha.IsEmpty() ) - setBitmap( BitmapEx( aBitmap ) ); - else - setBitmap( BitmapEx( aBitmap, - AlphaMask( aAlpha ) ) ); - } + BitmapEx newBitmapEx = vcl::bitmap::CanvasBitmapHelperSetPixel(color, pos, mpBackBuffer->getBitmapReference()); + setBitmap( newBitmapEx ); } uno::Sequence< sal_Int8 > CanvasBitmapHelper::getPixel( rendering::IntegerBitmapLayout& rLayout, diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx index 51088b0fefa1..e68e203825e2 100644 --- a/include/vcl/BitmapTools.hxx +++ b/include/vcl/BitmapTools.hxx @@ -18,6 +18,8 @@ #if ENABLE_CAIRO_CANVAS #include <vcl/cairo.hxx> #endif +#include <com/sun/star/geometry/IntegerPoint2D.hpp> +#include <com/sun/star/geometry/IntegerRectangle2D.hpp> namespace vcl { namespace bitmap { @@ -83,6 +85,13 @@ BitmapEx VCL_DLLPUBLIC CreateFromData( RawBitmap && data ); VCL_DLLPUBLIC BitmapEx* CreateFromCairoSurface(Size size, cairo_surface_t* pSurface); #endif +VCL_DLLPUBLIC BitmapEx CanvasBitmapHelperSetPixel( const css::uno::Sequence< sal_Int8 >& color, + const css::geometry::IntegerPoint2D& pos, + BitmapEx & rBitmapEx ); +VCL_DLLPUBLIC BitmapEx CanvasBitmapHelperSetData( const css::uno::Sequence< sal_Int8 >& data, + const css::geometry::IntegerRectangle2D& rect, + BitmapEx & rBitmapEx); + }} // end vcl::bitmap #endif // INCLUDED_VCL_BITMAP_TOOLS_HXX diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx index beda990e5b03..16816496158d 100644 --- a/vcl/source/bitmap/BitmapTools.cxx +++ b/vcl/source/bitmap/BitmapTools.cxx @@ -29,6 +29,7 @@ #if ENABLE_CAIRO_CANVAS #include <cairo.h> #endif +#include <tools/diagnose_ex.h> using namespace css; @@ -299,6 +300,251 @@ BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface) } #endif +BitmapEx CanvasBitmapHelperSetPixel( const uno::Sequence< sal_Int8 >& color, + const geometry::IntegerPoint2D& pos, + BitmapEx & rBitmapEx ) +{ + // retrieve local copies from the BitmapEx, which are later + // stored back. Unfortunately, the BitmapEx does not permit + // in-place modifications, as they are necessary here. + Bitmap aBitmap( rBitmapEx.GetBitmap() ); + Bitmap aAlpha( rBitmapEx.GetAlpha().GetBitmap() ); + + { + Bitmap::ScopedWriteAccess pWriteAccess( aBitmap ); + Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ? + nullptr : aAlpha.AcquireWriteAccess(), + aAlpha ); + + ENSURE_OR_THROW( pWriteAccess.get() != nullptr, + "Could not acquire write access to bitmap" ); + + pWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( color[ 0 ], + color[ 1 ], + color[ 2 ] ) ); + + if( pAlphaWriteAccess.get() != nullptr ) + pAlphaWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( 255 - color[ 3 ] ) ); + } + + if( aAlpha.IsEmpty() ) + return BitmapEx( aBitmap ); + else + return BitmapEx( aBitmap, AlphaMask( aAlpha ) ); +} + +BitmapEx CanvasBitmapHelperSetData( const uno::Sequence< sal_Int8 >& data, + const geometry::IntegerRectangle2D& rect, + BitmapEx & rBitmapEx) +{ + Bitmap aBitmap( rBitmapEx.GetBitmap() ); + Bitmap aAlpha( rBitmapEx.GetAlpha().GetBitmap() ); + + { + Bitmap::ScopedWriteAccess pWriteAccess( aBitmap ); + Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ? + nullptr : aAlpha.AcquireWriteAccess(), + aAlpha ); + + if( pAlphaWriteAccess.get() ) + { + DBG_ASSERT( pAlphaWriteAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal || + pAlphaWriteAccess->GetScanlineFormat() == ScanlineFormat::N8BitTcMask, + "non-8bit alpha not supported!" ); + } + + ENSURE_OR_THROW( pWriteAccess.get() != nullptr, + "Could not acquire write access to bitmap" ); + + // TODO(F1): Support more formats. + const Size aBmpSize( aBitmap.GetSizePixel() ); + + // for the time being, always read as BGRA + int nCurrPos(0); + for( long y=rect.Y1; + y<aBmpSize.Height() && y<rect.Y2; + ++y ) + { + if( pAlphaWriteAccess.get() != nullptr ) + { + switch( pWriteAccess->GetScanlineFormat() ) + { + case ScanlineFormat::N8BitPal: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + *pScan++ = static_cast<sal_uInt8>(pWriteAccess->GetBestPaletteIndex( + BitmapColor( data[ nCurrPos ], + data[ nCurrPos+1 ], + data[ nCurrPos+2 ] ) )); + + nCurrPos += 3; + + // cast to unsigned byte, for correct subtraction result + *pAScan++ = static_cast<sal_uInt8>(255 - + static_cast<sal_uInt8>(data[ nCurrPos++ ])); + } + } + break; + + case ScanlineFormat::N24BitTcBgr: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + *pScan++ = data[ nCurrPos+2 ]; + *pScan++ = data[ nCurrPos+1 ]; + *pScan++ = data[ nCurrPos ]; + + nCurrPos += 3; + + // cast to unsigned byte, for correct subtraction result + *pAScan++ = static_cast<sal_uInt8>(255 - + static_cast<sal_uInt8>(data[ nCurrPos++ ])); + } + } + break; + + case ScanlineFormat::N24BitTcRgb: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + *pScan++ = data[ nCurrPos ]; + *pScan++ = data[ nCurrPos+1 ]; + *pScan++ = data[ nCurrPos+2 ]; + + nCurrPos += 3; + + // cast to unsigned byte, for correct subtraction result + *pAScan++ = static_cast<sal_uInt8>(255 - + static_cast<sal_uInt8>(data[ nCurrPos++ ])); + } + } + break; + + default: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + Scanline pAScan = pAlphaWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + pWriteAccess->SetPixelOnData( pScan, x, BitmapColor( data[ nCurrPos ], + data[ nCurrPos+1 ], + data[ nCurrPos+2 ] ) ); + nCurrPos += 3; + + // cast to unsigned byte, for correct subtraction result + pAlphaWriteAccess->SetPixelOnData( pAScan, x, + BitmapColor( + static_cast<sal_uInt8>(255 - + static_cast<sal_uInt8>(data[ nCurrPos++ ])) ) ); + } + } + break; + } + } + else + { + // TODO(Q3): This is copy'n'pasted from + // canvashelper.cxx, unify! + switch( pWriteAccess->GetScanlineFormat() ) + { + case ScanlineFormat::N8BitPal: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + *pScan++ = static_cast<sal_uInt8>(pWriteAccess->GetBestPaletteIndex( + BitmapColor( data[ nCurrPos ], + data[ nCurrPos+1 ], + data[ nCurrPos+2 ] ) )); + + nCurrPos += 4; // skip three colors, _plus_ alpha + } + } + break; + + case ScanlineFormat::N24BitTcBgr: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + *pScan++ = data[ nCurrPos+2 ]; + *pScan++ = data[ nCurrPos+1 ]; + *pScan++ = data[ nCurrPos ]; + + nCurrPos += 4; // skip three colors, _plus_ alpha + } + } + break; + + case ScanlineFormat::N24BitTcRgb: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + *pScan++ = data[ nCurrPos ]; + *pScan++ = data[ nCurrPos+1 ]; + *pScan++ = data[ nCurrPos+2 ]; + + nCurrPos += 4; // skip three colors, _plus_ alpha + } + } + break; + + default: + { + Scanline pScan = pWriteAccess->GetScanline( y ); + + for( long x=rect.X1; + x<aBmpSize.Width() && x<rect.X2; + ++x ) + { + pWriteAccess->SetPixelOnData( pScan, x, BitmapColor( data[ nCurrPos ], + data[ nCurrPos+1 ], + data[ nCurrPos+2 ] ) ); + nCurrPos += 4; // skip three colors, _plus_ alpha + } + } + break; + } + } + } + } + + if( aAlpha.IsEmpty() ) + return BitmapEx( aBitmap ); + else + return BitmapEx( aBitmap, AlphaMask( aAlpha ) ); +} + + }} // end vcl::bitmap /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |