[Libreoffice-commits] core.git: canvas/source include/vcl vcl/source

Noel Grandin noel.grandin at collabora.co.uk
Thu Feb 15 10:14:38 UTC 2018


 canvas/source/cairo/cairo_canvasbitmap.cxx |   77 ++---------------------------
 include/vcl/BitmapTools.hxx                |    8 +++
 vcl/source/bitmap/BitmapTools.cxx          |   77 +++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 71 deletions(-)

New commits:
commit 32d8a32dcf85e2cee589ee19bc72b4abf73f9681
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Wed Feb 14 14:27:12 2018 +0200

    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 at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

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: */


More information about the Libreoffice-commits mailing list