summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2018-03-09 15:30:53 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-03-10 12:04:19 +0100
commit676024b001340dce6c854efc3b74bdc8db1e2a3b (patch)
tree732dc17462b9b6f5316d942e39c18370894e1347 /vcl
parent5b2fc10f0cc9f15525c7723764a1feebeceb0d5e (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>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/bitmap/BitmapTools.cxx246
1 files changed, 246 insertions, 0 deletions
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: */