summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2018-02-14 14:27:12 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-02-15 11:14:12 +0100
commit32d8a32dcf85e2cee589ee19bc72b4abf73f9681 (patch)
tree2840137415e3c707133003e8ae3617cd1793432e
parentabcd7825101afb9ef9ff93932f8e1bd7c3bb91bb (diff)
move cairo surface code from canvas to BitmapTools
part of making Bitmap an implementation detail of vcl/ Change-Id: Ic4b8d114a8091041374a083b3b7ca2fa68757ab1 Reviewed-on: https://gerrit.libreoffice.org/49719 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--canvas/source/cairo/cairo_canvasbitmap.cxx77
-rw-r--r--include/vcl/BitmapTools.hxx8
-rw-r--r--vcl/source/bitmap/BitmapTools.cxx77
3 files changed, 91 insertions, 71 deletions
diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx
index 7894e2e978e2..27ce9af37758 100644
--- a/canvas/source/cairo/cairo_canvasbitmap.cxx
+++ b/canvas/source/cairo/cairo_canvasbitmap.cxx
@@ -22,7 +22,7 @@
#include <cppuhelper/supportsservice.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/bitmapex.hxx>
-#include <vcl/bitmapaccess.hxx>
+#include <vcl/BitmapTools.hxx>
#include <canvas/canvastools.hxx>
@@ -118,77 +118,12 @@ namespace cairocanvas
if ( !mbHasAlpha )
break;
- ::Size aSize( maSize.getX(), maSize.getY() );
- // FIXME: if we could teach VCL/ about cairo handles, life could
- // be significantly better here perhaps.
- cairo_surface_t *pPixels;
- pPixels = cairo_image_surface_create( CAIRO_FORMAT_ARGB32,
- aSize.Width(), aSize.Height() );
- cairo_t *pCairo = cairo_create( pPixels );
- if( !pPixels || !pCairo || cairo_status(pCairo) != CAIRO_STATUS_SUCCESS )
- break;
+ BitmapEx* pBitmapEx = vcl::bitmap::CreateFromCairoSurface(
+ ::Size( maSize.getX(), maSize.getY() ),
+ getSurface()->getCairoSurface().get());
+ if (pBitmapEx)
+ aRV <<= reinterpret_cast<sal_Int64>( pBitmapEx );
- // suck ourselves from the X server to this buffer so then we can fiddle with
- // Alpha to turn it into the ultra-lame vcl required format and then push it
- // all back again later at vast expense [ urgh ]
- cairo_set_source_surface( pCairo, getSurface()->getCairoSurface().get(), 0, 0 );
- cairo_set_operator( pCairo, CAIRO_OPERATOR_SOURCE );
- cairo_paint( pCairo );
-
- ::Bitmap aRGB( aSize, 24 );
- ::AlphaMask aMask( aSize );
-
- BitmapWriteAccess *pRGBWrite( aRGB.AcquireWriteAccess() );
- if( pRGBWrite )
- {
- BitmapWriteAccess *pMaskWrite( aMask.AcquireWriteAccess() );
- if( pMaskWrite )
- {
- cairo_surface_flush(pPixels);
- unsigned char *pSrc = cairo_image_surface_get_data( pPixels );
- unsigned int nStride = cairo_image_surface_get_stride( pPixels );
- for( unsigned long y = 0; y < static_cast<unsigned long>(aSize.Height()); y++ )
- {
- sal_uInt32 *pPix = reinterpret_cast<sal_uInt32 *>(pSrc + nStride * y);
- for( unsigned long x = 0; x < static_cast<unsigned long>(aSize.Width()); x++ )
- {
-#if defined OSL_BIGENDIAN
- sal_uInt8 nB = (*pPix >> 24);
- sal_uInt8 nG = (*pPix >> 16) & 0xff;
- sal_uInt8 nR = (*pPix >> 8) & 0xff;
- sal_uInt8 nAlpha = *pPix & 0xff;
-#else
- sal_uInt8 nAlpha = (*pPix >> 24);
- sal_uInt8 nR = (*pPix >> 16) & 0xff;
- sal_uInt8 nG = (*pPix >> 8) & 0xff;
- sal_uInt8 nB = *pPix & 0xff;
-#endif
- if( nAlpha != 0 && nAlpha != 255 )
- {
- // Cairo uses pre-multiplied alpha - we do not => re-multiply
- nR = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nR) * 255) / nAlpha, 0, 255 ));
- nG = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nG) * 255) / nAlpha, 0, 255 ));
- nB = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nB) * 255) / nAlpha, 0, 255 ));
- }
- pRGBWrite->SetPixel( y, x, BitmapColor( nR, nG, nB ) );
- pMaskWrite->SetPixelIndex( y, x, 255 - nAlpha );
- pPix++;
- }
- }
- aMask.ReleaseAccess( pMaskWrite );
- }
- ::Bitmap::ReleaseAccess( pRGBWrite );
- }
-
- // ignore potential errors above. will get caller a
- // uniformely white bitmap, but not that there would
- // be error handling in calling code ...
- ::BitmapEx *pBitmapEx = new ::BitmapEx( aRGB, aMask );
-
- cairo_destroy( pCairo );
- cairo_surface_destroy( pPixels );
-
- aRV <<= reinterpret_cast<sal_Int64>( pBitmapEx );
break;
}
case 1:
diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx
index f2cf5512dc6f..4caafb3545e4 100644
--- a/include/vcl/BitmapTools.hxx
+++ b/include/vcl/BitmapTools.hxx
@@ -10,10 +10,14 @@
#ifndef INCLUDED_VCL_BITMAP_TOOLS_HXX
#define INCLUDED_VCL_BITMAP_TOOLS_HXX
+#include <config_cairo_canvas.h>
#include <vcl/bitmapex.hxx>
#include <vcl/ImageTree.hxx>
#include <vcl/salbtype.hxx>
#include <tools/stream.hxx>
+#if ENABLE_CAIRO_CANVAS
+#include <vcl/cairo.hxx>
+#endif
namespace vcl {
namespace bitmap {
@@ -66,6 +70,10 @@ BitmapEx VCL_DLLPUBLIC CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth,
BitmapEx VCL_DLLPUBLIC CreateFromData( RawBitmap && data );
+#if ENABLE_CAIRO_CANVAS
+VCL_DLLPUBLIC BitmapEx* CreateFromCairoSurface(Size size, cairo_surface_t* pSurface);
+#endif
+
}} // end vcl::bitmap
#endif // INCLUDED_VCL_BITMAP_TOOLS_HXX
diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx
index 87c6b64fb56a..ee0aef4f1f67 100644
--- a/vcl/source/bitmap/BitmapTools.cxx
+++ b/vcl/source/bitmap/BitmapTools.cxx
@@ -26,6 +26,9 @@
#include <vcl/svapp.hxx>
#include <vcl/salbtype.hxx>
#include <vcl/bitmapaccess.hxx>
+#if ENABLE_CAIRO_CANVAS
+#include <cairo.h>
+#endif
using namespace css;
@@ -199,6 +202,80 @@ BitmapEx CreateFromData( RawBitmap&& rawBitmap )
return aBmp;
}
+#if ENABLE_CAIRO_CANVAS
+BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface)
+{
+ // FIXME: if we could teach VCL/ about cairo handles, life could
+ // be significantly better here perhaps.
+ cairo_surface_t *pPixels = cairo_image_surface_create( CAIRO_FORMAT_ARGB32,
+ aSize.Width(), aSize.Height() );
+ cairo_t *pCairo = cairo_create( pPixels );
+ if( !pPixels || !pCairo || cairo_status(pCairo) != CAIRO_STATUS_SUCCESS )
+ return nullptr;
+
+ // suck ourselves from the X server to this buffer so then we can fiddle with
+ // Alpha to turn it into the ultra-lame vcl required format and then push it
+ // all back again later at vast expense [ urgh ]
+ cairo_set_source_surface( pCairo, pSurface, 0, 0 );
+ cairo_set_operator( pCairo, CAIRO_OPERATOR_SOURCE );
+ cairo_paint( pCairo );
+
+ ::Bitmap aRGB( aSize, 24 );
+ ::AlphaMask aMask( aSize );
+
+ Bitmap::ScopedWriteAccess pRGBWrite(aRGB);
+ assert(pRGBWrite);
+ if (!pRGBWrite)
+ return nullptr;
+
+ AlphaMask::ScopedWriteAccess pMaskWrite(aMask);
+ assert(pMaskWrite);
+ if (!pMaskWrite)
+ return nullptr;
+
+ cairo_surface_flush(pPixels);
+ unsigned char *pSrc = cairo_image_surface_get_data( pPixels );
+ unsigned int nStride = cairo_image_surface_get_stride( pPixels );
+ for( unsigned long y = 0; y < static_cast<unsigned long>(aSize.Height()); y++ )
+ {
+ sal_uInt32 *pPix = reinterpret_cast<sal_uInt32 *>(pSrc + nStride * y);
+ for( unsigned long x = 0; x < static_cast<unsigned long>(aSize.Width()); x++ )
+ {
+#if defined OSL_BIGENDIAN
+ sal_uInt8 nB = (*pPix >> 24);
+ sal_uInt8 nG = (*pPix >> 16) & 0xff;
+ sal_uInt8 nR = (*pPix >> 8) & 0xff;
+ sal_uInt8 nAlpha = *pPix & 0xff;
+#else
+ sal_uInt8 nAlpha = (*pPix >> 24);
+ sal_uInt8 nR = (*pPix >> 16) & 0xff;
+ sal_uInt8 nG = (*pPix >> 8) & 0xff;
+ sal_uInt8 nB = *pPix & 0xff;
+#endif
+ if( nAlpha != 0 && nAlpha != 255 )
+ {
+ // Cairo uses pre-multiplied alpha - we do not => re-multiply
+ nR = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nR) * 255) / nAlpha, 0, 255 ));
+ nG = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nG) * 255) / nAlpha, 0, 255 ));
+ nB = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nB) * 255) / nAlpha, 0, 255 ));
+ }
+ pRGBWrite->SetPixel( y, x, BitmapColor( nR, nG, nB ) );
+ pMaskWrite->SetPixelIndex( y, x, 255 - nAlpha );
+ pPix++;
+ }
+ }
+
+ // ignore potential errors above. will get caller a
+ // uniformly white bitmap, but not that there would
+ // be error handling in calling code ...
+ ::BitmapEx *pBitmapEx = new ::BitmapEx( aRGB, aMask );
+
+ cairo_destroy( pCairo );
+ cairo_surface_destroy( pPixels );
+ return pBitmapEx;
+}
+#endif
+
}} // end vcl::bitmap
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */