summaryrefslogtreecommitdiff
path: root/canvas
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2018-03-16 14:58:59 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-03-16 19:25:48 +0100
commit5b75a1697250d8b2b6003c37067f39270a5ad828 (patch)
tree14d1fddc6f14707c64c220ee738e25567037de18 /canvas
parent92dc87cbac74c1be260534b5e38088c44515a47b (diff)
move cairo extract bitmap code from canvas to vcl
part of making GetMask/GetAlpha an internal detail of vcl Change-Id: I45c2e9fdae08d7f444a64e8e04a6f65bb525cbd1 Reviewed-on: https://gerrit.libreoffice.org/51417 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'canvas')
-rw-r--r--canvas/source/cairo/cairo_canvashelper.cxx288
1 files changed, 6 insertions, 282 deletions
diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx
index bba59a15c475..2ed3d0472c04 100644
--- a/canvas/source/cairo/cairo_canvashelper.cxx
+++ b/canvas/source/cairo/cairo_canvashelper.cxx
@@ -48,6 +48,7 @@
#include <tools/diagnose_ex.h>
#include <vcl/bitmapex.hxx>
#include <vcl/bitmapaccess.hxx>
+#include <vcl/BitmapTools.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/virdev.hxx>
@@ -328,71 +329,6 @@ namespace cairocanvas
return ::BitmapEx();
}
- static sal_uInt8 lcl_GetColor(BitmapColor const& rColor)
- {
- sal_uInt8 nTemp(0);
- if (rColor.IsIndex())
- {
- nTemp = rColor.GetIndex();
- }
- else
- {
- nTemp = rColor.GetBlue();
- // greyscale expected here, or what would non-grey colors mean?
- assert(rColor.GetRed() == nTemp && rColor.GetGreen() == nTemp);
- }
- return nTemp;
- }
-
- static bool readAlpha( BitmapReadAccess const * pAlphaReadAcc, long nY, const long nWidth, unsigned char* data, long nOff )
- {
- bool bIsAlpha = false;
- long nX;
- int nAlpha;
- Scanline pReadScan;
-
- nOff += 3;
-
- switch( pAlphaReadAcc->GetScanlineFormat() )
- {
- case ScanlineFormat::N8BitTcMask:
- pReadScan = pAlphaReadAcc->GetScanline( nY );
- for( nX = 0; nX < nWidth; nX++ )
- {
- nAlpha = data[ nOff ] = 255 - ( *pReadScan++ );
- if( nAlpha != 255 )
- bIsAlpha = true;
- nOff += 4;
- }
- break;
- case ScanlineFormat::N8BitPal:
- pReadScan = pAlphaReadAcc->GetScanline( nY );
- for( nX = 0; nX < nWidth; nX++ )
- {
- BitmapColor const& rColor(
- pAlphaReadAcc->GetPaletteColor(*pReadScan));
- pReadScan++;
- nAlpha = data[ nOff ] = 255 - lcl_GetColor(rColor);
- if( nAlpha != 255 )
- bIsAlpha = true;
- nOff += 4;
- }
- break;
- default:
- SAL_INFO( "canvas.cairo", "fallback to GetColor for alpha - slow, format: " << static_cast<int>(pAlphaReadAcc->GetScanlineFormat()) );
- for( nX = 0; nX < nWidth; nX++ )
- {
- nAlpha = data[ nOff ] = 255 - pAlphaReadAcc->GetColor( nY, nX ).GetIndex();
- if( nAlpha != 255 )
- bIsAlpha = true;
- nOff += 4;
- }
- }
-
- return bIsAlpha;
- }
-
-
/** surfaceFromXBitmap Create a surface from XBitmap
* @param xBitmap bitmap image that will be used for the surface
* @param rDevice reference to the device into which we want to draw
@@ -427,232 +363,20 @@ namespace cairocanvas
if( !pSurface )
{
- AlphaMask aAlpha = aBmpEx.GetAlpha();
-
- ::BitmapReadAccess* pBitmapReadAcc = aBitmap.AcquireReadAccess();
- ::BitmapReadAccess* pAlphaReadAcc = nullptr;
- const long nWidth = pBitmapReadAcc->Width();
- const long nHeight = pBitmapReadAcc->Height();
- long nX, nY;
- bool bIsAlpha = false;
-
- if( aBmpEx.IsTransparent() || aBmpEx.IsAlpha() )
- pAlphaReadAcc = aAlpha.AcquireReadAccess();
-
- data = static_cast<unsigned char*>(malloc( nWidth*nHeight*4 ));
-
- long nOff = 0;
- ::Color aColor;
- unsigned int nAlpha = 255;
-
- for( nY = 0; nY < nHeight; nY++ )
- {
- ::Scanline pReadScan;
-
- switch( pBitmapReadAcc->GetScanlineFormat() )
- {
- case ScanlineFormat::N8BitPal:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
-#endif
- aColor = pBitmapReadAcc->GetPaletteColor(*pReadScan++).GetColor();
-
-#ifdef OSL_BIGENDIAN
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetRed() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetGreen() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetBlue() ) )/255 );
-#else
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetBlue() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetGreen() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetRed() ) )/255 );
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N24BitTcBgr:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff ];
- else
- nAlpha = data[ nOff ] = 255;
- data[ nOff + 3 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff + 2 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff + 1 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- nOff += 4;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N24BitTcRgb:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
- pReadScan += 3;
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N32BitTcBgra:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
- pReadScan += 4;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- pReadScan++;
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N32BitTcRgba:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff ++ ];
- else
- nAlpha = data[ nOff ++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- pReadScan++;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
- pReadScan += 4;
- nOff++;
-#endif
- }
- break;
- default:
- SAL_INFO( "canvas.cairo", "fallback to GetColor - slow, format: " << static_cast<int>(pBitmapReadAcc->GetScanlineFormat()) );
-
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
- aColor = pBitmapReadAcc->GetColor( nY, nX ).GetColor();
-
- // cairo need premultiplied color values
- // TODO(rodo) handle endianness
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetRed() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetGreen() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetBlue() )/255 );
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetBlue() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetGreen() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetRed() )/255 );
- nOff ++;
-#endif
- }
- }
- }
-
- ::Bitmap::ReleaseAccess( pBitmapReadAcc );
- if( pAlphaReadAcc )
- aAlpha.ReleaseAccess( pAlphaReadAcc );
+ vcl::bitmap::CanvasCairoExtractBitmapData(aBmpEx, aBitmap, data, bHasAlpha);
+ const long nWidth = aBmpEx.GetPrefSize().Width();
+ const long nHeight = aBmpEx.GetPrefSize().Height();
SurfaceSharedPtr pImageSurface = rSurfaceProvider->getOutputDevice()->CreateSurface(
CairoSurfaceSharedPtr(
cairo_image_surface_create_for_data(
data,
- bIsAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
+ bHasAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
nWidth, nHeight, nWidth*4 ),
&cairo_surface_destroy) );
pSurface = pImageSurface;
- bHasAlpha = bIsAlpha;
-
- SAL_INFO( "canvas.cairo","image: " << nWidth << " x " << nHeight << " alpha: " << bIsAlpha << " alphaRead " << std::hex << pAlphaReadAcc);
+ SAL_INFO( "canvas.cairo","image: " << nWidth << " x " << nHeight << " alpha: " << bHasAlpha);
}
}