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

Noel Grandin noel.grandin at collabora.co.uk
Fri Mar 16 18:26:17 UTC 2018


 canvas/source/cairo/cairo_canvashelper.cxx |  288 ----------------------------
 include/vcl/BitmapTools.hxx                |    6 
 vcl/source/bitmap/BitmapTools.cxx          |  291 +++++++++++++++++++++++++++++
 3 files changed, 303 insertions(+), 282 deletions(-)

New commits:
commit 5b75a1697250d8b2b6003c37067f39270a5ad828
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Fri Mar 16 14:58:59 2018 +0200

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

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);
             }
         }
 
diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx
index 3a1692730393..9c347d275f4b 100644
--- a/include/vcl/BitmapTools.hxx
+++ b/include/vcl/BitmapTools.hxx
@@ -98,6 +98,12 @@ VCL_DLLPUBLIC void DrawAndClipBitmap(const Point& rPos, const Size& rSize, const
 
 VCL_DLLPUBLIC css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const & aBmpEx);
 
+/**
+ * @param data will be filled with alpha data, if xBitmap is alpha/transparent image
+ * @param bHasAlpha will be set to true if resulting surface has alpha
+ **/
+VCL_DLLPUBLIC void CanvasCairoExtractBitmapData( BitmapEx & rBmpEx, Bitmap & rBitmap, unsigned char*& data, bool& bHasAlpha );
+
 }} // end vcl::bitmap
 
 #endif // INCLUDED_VCL_BITMAP_TOOLS_HXX
diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx
index 3abd1ca537b9..816bad119e13 100644
--- a/vcl/source/bitmap/BitmapTools.cxx
+++ b/vcl/source/bitmap/BitmapTools.cxx
@@ -648,6 +648,297 @@ css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const & aBmpEx)
     return css::uno::Sequence< sal_Int8 >();
 }
 
+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;
+}
+
+
+
+/**
+ * @param data will be filled with alpha data, if xBitmap is alpha/transparent image
+ * @param bHasAlpha will be set to true if resulting surface has alpha
+ **/
+void CanvasCairoExtractBitmapData( BitmapEx & aBmpEx, Bitmap & aBitmap, unsigned char*& data, bool& bHasAlpha )
+{
+    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 );
+
+    bHasAlpha = bIsAlpha;
+
+}
+
 }} // end vcl::bitmap
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list