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

Noel Grandin noel.grandin at collabora.co.uk
Tue Mar 13 14:33:14 UTC 2018


 canvas/source/vcl/impltools.cxx   |  161 ------------------------------------
 include/vcl/BitmapTools.hxx       |    7 +
 vcl/source/bitmap/BitmapTools.cxx |  167 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+), 159 deletions(-)

New commits:
commit a93d940186f65005141eea3bebdfb4c66cebe8f8
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Tue Mar 13 14:26:54 2018 +0200

    make transformBitmap code from canvas to vcl
    
    part of making ScopedWriteAccess an internal detail of vcl
    
    Change-Id: Ida03bc73fe746cde97f6fcb5cde2f066b63d92e9
    Reviewed-on: https://gerrit.libreoffice.org/51216
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/canvas/source/vcl/impltools.cxx b/canvas/source/vcl/impltools.cxx
index dd0ca8a0714b..529a0b7fdf91 100644
--- a/canvas/source/vcl/impltools.cxx
+++ b/canvas/source/vcl/impltools.cxx
@@ -42,6 +42,7 @@
 #include <vcl/bitmapex.hxx>
 #include <vcl/bitmapaccess.hxx>
 #include <vcl/canvastools.hxx>
+#include <vcl/BitmapTools.hxx>
 #include <vcl/metric.hxx>
 #include <vcl/salbtype.hxx>
 
@@ -209,8 +210,6 @@ namespace vclcanvas
             const Size                  aBmpSize( rBitmap.GetSizePixel() );
             ::basegfx::B2DRectangle     aDestRect;
 
-            bool bCopyBack( false );
-
             // calc effective transformation for bitmap
             const ::basegfx::B2DRectangle aSrcRect( 0, 0,
                                                     aBmpSize.Width(),
@@ -228,163 +227,7 @@ namespace vclcanvas
                                                         aSrcRect,
                                                         rTransform );
 
-            Bitmap aSrcBitmap( rBitmap.GetBitmap() );
-            Bitmap aSrcAlpha;
-
-            // differentiate mask and alpha channel (on-off
-            // vs. multi-level transparency)
-            if( rBitmap.IsTransparent() )
-            {
-                if( rBitmap.IsAlpha() )
-                    aSrcAlpha = rBitmap.GetAlpha().GetBitmap();
-                else
-                    aSrcAlpha = rBitmap.GetMask();
-            }
-
-            Bitmap::ScopedReadAccess pReadAccess( aSrcBitmap );
-            Bitmap::ScopedReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ?
-                                                     aSrcAlpha.AcquireReadAccess() :
-                                                     nullptr,
-                                                     aSrcAlpha );
-
-            if( pReadAccess.get() == nullptr ||
-                (pAlphaReadAccess.get() == nullptr && rBitmap.IsTransparent()) )
-            {
-                // TODO(E2): Error handling!
-                ENSURE_OR_THROW( false,
-                                  "transformBitmap(): could not access source bitmap" );
-            }
-
-            // mapping table, to translate pAlphaReadAccess' pixel
-            // values into destination alpha values (needed e.g. for
-            // paletted 1-bit masks).
-            sal_uInt8 aAlphaMap[256];
-
-            if( rBitmap.IsTransparent() )
-            {
-                if( rBitmap.IsAlpha() )
-                {
-                    // source already has alpha channel - 1:1 mapping,
-                    // i.e. aAlphaMap[0]=0,...,aAlphaMap[255]=255.
-                    sal_uInt8  val=0;
-                    sal_uInt8* pCur=aAlphaMap;
-                    sal_uInt8* const pEnd=&aAlphaMap[256];
-                    while(pCur != pEnd)
-                        *pCur++ = val++;
-                }
-                else
-                {
-                    // mask transparency - determine used palette colors
-                    const BitmapColor& rCol0( pAlphaReadAccess->GetPaletteColor( 0 ) );
-                    const BitmapColor& rCol1( pAlphaReadAccess->GetPaletteColor( 1 ) );
-
-                    // shortcut for true luminance calculation
-                    // (assumes that palette is grey-level)
-                    aAlphaMap[0] = rCol0.GetRed();
-                    aAlphaMap[1] = rCol1.GetRed();
-                }
-            }
-            // else: mapping table is not used
-
-            const Size aDestBmpSize( ::basegfx::fround( aDestRect.getWidth() ),
-                                     ::basegfx::fround( aDestRect.getHeight() ) );
-
-            if( aDestBmpSize.Width() == 0 || aDestBmpSize.Height() == 0 )
-                return BitmapEx();
-
-            Bitmap aDstBitmap( aDestBmpSize, aSrcBitmap.GetBitCount(), &pReadAccess->GetPalette() );
-            Bitmap aDstAlpha( AlphaMask( aDestBmpSize ).GetBitmap() );
-
-            {
-                // just to be on the safe side: let the
-                // ScopedAccessors get destructed before
-                // copy-constructing the resulting bitmap. This will
-                // rule out the possibility that cached accessor data
-                // is not yet written back.
-                Bitmap::ScopedWriteAccess pWriteAccess( aDstBitmap );
-                Bitmap::ScopedWriteAccess pAlphaWriteAccess( aDstAlpha );
-
-
-                if( pWriteAccess.get() != nullptr &&
-                    pAlphaWriteAccess.get() != nullptr &&
-                    rTransform.isInvertible() )
-                {
-                    // we're doing inverse mapping here, i.e. mapping
-                    // points from the destination bitmap back to the
-                    // source
-                    ::basegfx::B2DHomMatrix aTransform( aLocalTransform );
-                    aTransform.invert();
-
-                    // for the time being, always read as ARGB
-                    for( long y=0; y<aDestBmpSize.Height(); ++y )
-                    {
-                        // differentiate mask and alpha channel (on-off
-                        // vs. multi-level transparency)
-                        if( rBitmap.IsTransparent() )
-                        {
-                            Scanline pScan = pWriteAccess->GetScanline( y );
-                            Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
-                            // Handling alpha and mask just the same...
-                            for( long x=0; x<aDestBmpSize.Width(); ++x )
-                            {
-                                ::basegfx::B2DPoint aPoint(x,y);
-                                aPoint *= aTransform;
-
-                                const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
-                                const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
-                                if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
-                                    nSrcY < 0 || nSrcY >= aBmpSize.Height() )
-                                {
-                                    pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
-                                }
-                                else
-                                {
-                                    const sal_uInt8 cAlphaIdx = pAlphaReadAccess->GetPixelIndex( nSrcY, nSrcX );
-                                    pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(aAlphaMap[ cAlphaIdx ]) );
-                                    pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY, nSrcX ) );
-                                }
-                            }
-                        }
-                        else
-                        {
-                            Scanline pScan = pWriteAccess->GetScanline( y );
-                            Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
-                            for( long x=0; x<aDestBmpSize.Width(); ++x )
-                            {
-                                ::basegfx::B2DPoint aPoint(x,y);
-                                aPoint *= aTransform;
-
-                                const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
-                                const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
-                                if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
-                                    nSrcY < 0 || nSrcY >= aBmpSize.Height() )
-                                {
-                                    pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
-                                }
-                                else
-                                {
-                                    pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(0) );
-                                    pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY,
-                                                                                         nSrcX ) );
-                                }
-                            }
-                        }
-                    }
-
-                    bCopyBack = true;
-                }
-                else
-                {
-                    // TODO(E2): Error handling!
-                    ENSURE_OR_THROW( false,
-                                      "transformBitmap(): could not access bitmap" );
-                }
-            }
-
-            if( bCopyBack )
-                return BitmapEx( aDstBitmap, AlphaMask( aDstAlpha ) );
-            else
-                return BitmapEx();
+            return vcl::bitmap::CanvasTransformBitmap(rBitmap, rTransform, aDestRect, aLocalTransform);
         }
     }
 }
diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx
index e68e203825e2..1263157b932c 100644
--- a/include/vcl/BitmapTools.hxx
+++ b/include/vcl/BitmapTools.hxx
@@ -20,6 +20,8 @@
 #endif
 #include <com/sun/star/geometry/IntegerPoint2D.hpp>
 #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
+#include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
 
 namespace vcl {
 namespace bitmap {
@@ -92,6 +94,11 @@ VCL_DLLPUBLIC BitmapEx CanvasBitmapHelperSetData( const css::uno::Sequence< sal_
                                                   const css::geometry::IntegerRectangle2D&   rect,
                                                   BitmapEx & rBitmapEx);
 
+VCL_DLLPUBLIC BitmapEx CanvasTransformBitmap( const BitmapEx& rBitmap,
+                                  const ::basegfx::B2DHomMatrix&  rTransform,
+                                  ::basegfx::B2DRectangle const & rDestRect,
+                                  ::basegfx::B2DHomMatrix const & rLocalTransform );
+
 }} // end vcl::bitmap
 
 #endif // INCLUDED_VCL_BITMAP_TOOLS_HXX
diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx
index 16816496158d..b9e0b77fd641 100644
--- a/vcl/source/bitmap/BitmapTools.cxx
+++ b/vcl/source/bitmap/BitmapTools.cxx
@@ -545,6 +545,173 @@ BitmapEx CanvasBitmapHelperSetData( const uno::Sequence< sal_Int8 >&      data,
 }
 
 
+BitmapEx CanvasTransformBitmap( const BitmapEx&                 rBitmap,
+                                const ::basegfx::B2DHomMatrix&  rTransform,
+                                ::basegfx::B2DRectangle const & rDestRect,
+                                ::basegfx::B2DHomMatrix const & rLocalTransform )
+{
+    bool bCopyBack( false );
+    const Size aBmpSize( rBitmap.GetSizePixel() );
+    Bitmap aSrcBitmap( rBitmap.GetBitmap() );
+    Bitmap aSrcAlpha;
+
+    // differentiate mask and alpha channel (on-off
+    // vs. multi-level transparency)
+    if( rBitmap.IsTransparent() )
+    {
+        if( rBitmap.IsAlpha() )
+            aSrcAlpha = rBitmap.GetAlpha().GetBitmap();
+        else
+            aSrcAlpha = rBitmap.GetMask();
+    }
+
+    Bitmap::ScopedReadAccess pReadAccess( aSrcBitmap );
+    Bitmap::ScopedReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ?
+                                             aSrcAlpha.AcquireReadAccess() :
+                                             nullptr,
+                                             aSrcAlpha );
+
+    if( pReadAccess.get() == nullptr ||
+        (pAlphaReadAccess.get() == nullptr && rBitmap.IsTransparent()) )
+    {
+        // TODO(E2): Error handling!
+        ENSURE_OR_THROW( false,
+                          "transformBitmap(): could not access source bitmap" );
+    }
+
+    // mapping table, to translate pAlphaReadAccess' pixel
+    // values into destination alpha values (needed e.g. for
+    // paletted 1-bit masks).
+    sal_uInt8 aAlphaMap[256];
+
+    if( rBitmap.IsTransparent() )
+    {
+        if( rBitmap.IsAlpha() )
+        {
+            // source already has alpha channel - 1:1 mapping,
+            // i.e. aAlphaMap[0]=0,...,aAlphaMap[255]=255.
+            sal_uInt8  val=0;
+            sal_uInt8* pCur=aAlphaMap;
+            sal_uInt8* const pEnd=&aAlphaMap[256];
+            while(pCur != pEnd)
+                *pCur++ = val++;
+        }
+        else
+        {
+            // mask transparency - determine used palette colors
+            const BitmapColor& rCol0( pAlphaReadAccess->GetPaletteColor( 0 ) );
+            const BitmapColor& rCol1( pAlphaReadAccess->GetPaletteColor( 1 ) );
+
+            // shortcut for true luminance calculation
+            // (assumes that palette is grey-level)
+            aAlphaMap[0] = rCol0.GetRed();
+            aAlphaMap[1] = rCol1.GetRed();
+        }
+    }
+    // else: mapping table is not used
+
+    const Size aDestBmpSize( ::basegfx::fround( rDestRect.getWidth() ),
+                             ::basegfx::fround( rDestRect.getHeight() ) );
+
+    if( aDestBmpSize.Width() == 0 || aDestBmpSize.Height() == 0 )
+        return BitmapEx();
+
+    Bitmap aDstBitmap( aDestBmpSize, aSrcBitmap.GetBitCount(), &pReadAccess->GetPalette() );
+    Bitmap aDstAlpha( AlphaMask( aDestBmpSize ).GetBitmap() );
+
+    {
+        // just to be on the safe side: let the
+        // ScopedAccessors get destructed before
+        // copy-constructing the resulting bitmap. This will
+        // rule out the possibility that cached accessor data
+        // is not yet written back.
+        Bitmap::ScopedWriteAccess pWriteAccess( aDstBitmap );
+        Bitmap::ScopedWriteAccess pAlphaWriteAccess( aDstAlpha );
+
+
+        if( pWriteAccess.get() != nullptr &&
+            pAlphaWriteAccess.get() != nullptr &&
+            rTransform.isInvertible() )
+        {
+            // we're doing inverse mapping here, i.e. mapping
+            // points from the destination bitmap back to the
+            // source
+            ::basegfx::B2DHomMatrix aTransform( rLocalTransform );
+            aTransform.invert();
+
+            // for the time being, always read as ARGB
+            for( long y=0; y<aDestBmpSize.Height(); ++y )
+            {
+                // differentiate mask and alpha channel (on-off
+                // vs. multi-level transparency)
+                if( rBitmap.IsTransparent() )
+                {
+                    Scanline pScan = pWriteAccess->GetScanline( y );
+                    Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
+                    // Handling alpha and mask just the same...
+                    for( long x=0; x<aDestBmpSize.Width(); ++x )
+                    {
+                        ::basegfx::B2DPoint aPoint(x,y);
+                        aPoint *= aTransform;
+
+                        const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
+                        const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
+                        if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+                            nSrcY < 0 || nSrcY >= aBmpSize.Height() )
+                        {
+                            pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
+                        }
+                        else
+                        {
+                            const sal_uInt8 cAlphaIdx = pAlphaReadAccess->GetPixelIndex( nSrcY, nSrcX );
+                            pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(aAlphaMap[ cAlphaIdx ]) );
+                            pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY, nSrcX ) );
+                        }
+                    }
+                }
+                else
+                {
+                    Scanline pScan = pWriteAccess->GetScanline( y );
+                    Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
+                    for( long x=0; x<aDestBmpSize.Width(); ++x )
+                    {
+                        ::basegfx::B2DPoint aPoint(x,y);
+                        aPoint *= aTransform;
+
+                        const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
+                        const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
+                        if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+                            nSrcY < 0 || nSrcY >= aBmpSize.Height() )
+                        {
+                            pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
+                        }
+                        else
+                        {
+                            pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(0) );
+                            pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY,
+                                                                                 nSrcX ) );
+                        }
+                    }
+                }
+            }
+
+            bCopyBack = true;
+        }
+        else
+        {
+            // TODO(E2): Error handling!
+            ENSURE_OR_THROW( false,
+                              "transformBitmap(): could not access bitmap" );
+        }
+    }
+
+    if( bCopyBack )
+        return BitmapEx( aDstBitmap, AlphaMask( aDstAlpha ) );
+    else
+        return BitmapEx();
+}
+
+
 }} // end vcl::bitmap
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list