[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