summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTomaž Vajngerl <quikee@gmail.com>2012-08-14 20:39:14 +0200
committerTomaž Vajngerl <quikee@gmail.com>2012-08-14 20:43:18 +0200
commit42801a0e690a63c3a94b1d8256b6c7cd64856bd2 (patch)
tree44f51e56fe12171ac95d903b8312abd899aaf08a /vcl
parente9ed269c9ec985e1f4046addfab05c1c3795da68 (diff)
Fix transparent bitmap rendering.
Convert transparent mask to 8bit-grey after scale/rotate/crop transformation. Use correct perspective at rendering. Change-Id: I80b19d7bec880b0c58709c7c5bee6199cbc815c9
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/vcl/alpha.hxx187
-rw-r--r--vcl/source/gdi/alpha.cxx57
-rw-r--r--vcl/source/gdi/bitmap3.cxx6
-rw-r--r--vcl/source/gdi/bitmapex.cxx53
4 files changed, 161 insertions, 142 deletions
diff --git a/vcl/inc/vcl/alpha.hxx b/vcl/inc/vcl/alpha.hxx
index 45eed358b053..d0ceb92b1a24 100644
--- a/vcl/inc/vcl/alpha.hxx
+++ b/vcl/inc/vcl/alpha.hxx
@@ -52,104 +52,107 @@ private:
public:
- AlphaMask();
- AlphaMask( const Bitmap& rBitmap );
- AlphaMask( const AlphaMask& rAlphaMask );
- AlphaMask( const Size& rSizePixel, sal_uInt8* pEraseTransparency = NULL );
- ~AlphaMask();
-
- AlphaMask& operator=( const Bitmap& rBitmap );
- AlphaMask& operator=( const AlphaMask& rAlphaMask )
- {
- return (AlphaMask&) Bitmap::operator=( rAlphaMask );
- }
- sal_Bool operator!() const
- {
- return Bitmap::operator!();
- }
- sal_Bool operator==( const AlphaMask& rAlphaMask ) const
- {
- return Bitmap::operator==( rAlphaMask );
- }
- sal_Bool operator!=( const AlphaMask& rAlphaMask ) const
- {
- return Bitmap::operator!=( rAlphaMask );
- }
-
- const MapMode& GetPrefMapMode() const
- {
- return Bitmap::GetPrefMapMode();
- }
- void SetPrefMapMode( const MapMode& rMapMode )
- {
- Bitmap::SetPrefMapMode( rMapMode );
- }
-
- const Size& GetPrefSize() const
- {
- return Bitmap::GetPrefSize();
- }
- void SetPrefSize( const Size& rSize )
- {
- Bitmap::SetPrefSize( rSize );
- }
-
- Size GetSizePixel() const
- {
- return Bitmap::GetSizePixel();
- }
-
- sal_uLong GetSizeBytes() const
- {
- return Bitmap::GetSizeBytes();
- }
- sal_uLong GetChecksum() const
- {
- return Bitmap::GetChecksum();
- }
-
- Bitmap GetBitmap() const;
-
- sal_Bool CopyPixel(
- const Rectangle& rRectDst,
- const Rectangle& rRectSrc,
- const AlphaMask* pAlphaSrc = NULL
- );
- sal_Bool Erase( sal_uInt8 cTransparency );
- sal_Bool Replace( const Bitmap& rMask, sal_uInt8 rReplaceTransparency );
- sal_Bool Replace(
- sal_uInt8 cSearchTransparency,
- sal_uInt8 cReplaceTransparency,
- sal_uLong nTol = 0UL
- );
-
- BitmapReadAccess* AcquireReadAccess()
- {
- return Bitmap::AcquireReadAccess();
- }
- BitmapWriteAccess* AcquireWriteAccess()
- {
- return Bitmap::AcquireWriteAccess();
- }
- void ReleaseAccess( BitmapReadAccess* pAccess );
+ AlphaMask();
+ AlphaMask( const Bitmap& rBitmap );
+ AlphaMask( const AlphaMask& rAlphaMask );
+ AlphaMask( const Size& rSizePixel, sal_uInt8* pEraseTransparency = NULL );
+ ~AlphaMask();
+
+ AlphaMask& operator=( const Bitmap& rBitmap );
+ AlphaMask& operator=( const AlphaMask& rAlphaMask )
+ {
+ return (AlphaMask&) Bitmap::operator=( rAlphaMask );
+ }
+
+ sal_Bool operator!() const
+ {
+ return Bitmap::operator!();
+ }
+
+ sal_Bool operator==( const AlphaMask& rAlphaMask ) const
+ {
+ return Bitmap::operator==( rAlphaMask );
+ }
+
+ sal_Bool operator!=( const AlphaMask& rAlphaMask ) const
+ {
+ return Bitmap::operator!=( rAlphaMask );
+ }
+
+ const MapMode& GetPrefMapMode() const
+ {
+ return Bitmap::GetPrefMapMode();
+ }
+
+ void SetPrefMapMode( const MapMode& rMapMode )
+ {
+ Bitmap::SetPrefMapMode( rMapMode );
+ }
+
+ const Size& GetPrefSize() const
+ {
+ return Bitmap::GetPrefSize();
+ }
+
+ void SetPrefSize( const Size& rSize )
+ {
+ Bitmap::SetPrefSize( rSize );
+ }
+
+ Size GetSizePixel() const
+ {
+ return Bitmap::GetSizePixel();
+ }
+
+ sal_uLong GetSizeBytes() const
+ {
+ return Bitmap::GetSizeBytes();
+ }
+ sal_uLong GetChecksum() const
+ {
+ return Bitmap::GetChecksum();
+ }
+
+ Bitmap GetBitmap() const;
+
+ sal_Bool CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
+ const AlphaMask* pAlphaSrc = NULL);
+
+ sal_Bool Erase( sal_uInt8 cTransparency );
+ sal_Bool Replace( const Bitmap& rMask, sal_uInt8 rReplaceTransparency );
+ sal_Bool Replace( sal_uInt8 cSearchTransparency, sal_uInt8 cReplaceTransparency,
+ sal_uLong nTol = 0UL );
+
+ sal_Bool Scale( const Size& rNewSize, sal_uLong nScaleFlag );
+ sal_Bool Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
+ sal_Bool ScaleCropRotate( const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
+ const Color& rFillColor, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
+
+ BitmapReadAccess* AcquireReadAccess()
+ {
+ return Bitmap::AcquireReadAccess();
+ }
+
+ BitmapWriteAccess* AcquireWriteAccess()
+ {
+ return Bitmap::AcquireWriteAccess();
+ }
+
+ void ReleaseAccess( BitmapReadAccess* pAccess );
typedef vcl::ScopedBitmapAccess< BitmapReadAccess, AlphaMask, &AlphaMask::AcquireReadAccess >
ScopedReadAccess;
typedef vcl::ScopedBitmapAccess< BitmapWriteAccess, AlphaMask, &AlphaMask::AcquireWriteAccess >
ScopedWriteAccess;
- sal_Bool Read( SvStream& rIStm, sal_Bool bFileHeader = sal_True )
- {
- return Bitmap::Read( rIStm, bFileHeader );
- }
- sal_Bool Write(
- SvStream& rOStm,
- sal_Bool bCompressed = sal_True,
- sal_Bool bFileHeader = sal_True
- ) const
- {
- return Bitmap::Write( rOStm, bCompressed, bFileHeader );
- }
+ sal_Bool Read( SvStream& rIStm, sal_Bool bFileHeader = sal_True )
+ {
+ return Bitmap::Read( rIStm, bFileHeader );
+ }
+ sal_Bool Write( SvStream& rOStm, sal_Bool bCompressed = sal_True, sal_Bool bFileHeader = sal_True ) const
+ {
+ return Bitmap::Write( rOStm, bCompressed, bFileHeader );
+ }
friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const BitmapEx& rBitmapEx );
friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, BitmapEx& rBitmapEx );
diff --git a/vcl/source/gdi/alpha.cxx b/vcl/source/gdi/alpha.cxx
index cbaf138d2d1d..0c2ad3677dee 100644
--- a/vcl/source/gdi/alpha.cxx
+++ b/vcl/source/gdi/alpha.cxx
@@ -39,8 +39,6 @@ AlphaMask::AlphaMask()
{
}
-// -----------------------------------------------------------------------------
-
AlphaMask::AlphaMask( const Bitmap& rBitmap ) :
Bitmap( rBitmap )
{
@@ -48,15 +46,11 @@ AlphaMask::AlphaMask( const Bitmap& rBitmap ) :
Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
}
-// -----------------------------------------------------------------------------
-
AlphaMask::AlphaMask( const AlphaMask& rAlphaMask ) :
Bitmap( rAlphaMask )
{
}
-// -----------------------------------------------------------------------------
-
AlphaMask::AlphaMask( const Size& rSizePixel, sal_uInt8* pEraseTransparency ) :
Bitmap( rSizePixel, 8, &Bitmap::GetGreyPalette( 256 ) )
{
@@ -64,14 +58,10 @@ AlphaMask::AlphaMask( const Size& rSizePixel, sal_uInt8* pEraseTransparency ) :
Bitmap::Erase( Color( *pEraseTransparency, *pEraseTransparency, *pEraseTransparency ) );
}
-// -----------------------------------------------------------------------------
-
AlphaMask::~AlphaMask()
{
}
-// -----------------------------------------------------------------------------
-
AlphaMask& AlphaMask::operator=( const Bitmap& rBitmap )
{
*(Bitmap*) this = rBitmap;
@@ -82,30 +72,22 @@ AlphaMask& AlphaMask::operator=( const Bitmap& rBitmap )
return *this;
}
-// -----------------------------------------------------------------------------
-
const Bitmap& AlphaMask::ImplGetBitmap() const
{
return( (const Bitmap&) *this );
}
-// -----------------------------------------------------------------------------
-
void AlphaMask::ImplSetBitmap( const Bitmap& rBitmap )
{
DBG_ASSERT( ( 8 == rBitmap.GetBitCount() ) && rBitmap.HasGreyPalette(), "AlphaMask::ImplSetBitmap: invalid bitmap" );
*(Bitmap*) this = rBitmap;
}
-// -----------------------------------------------------------------------------
-
Bitmap AlphaMask::GetBitmap() const
{
return ImplGetBitmap();
}
-// -----------------------------------------------------------------------------
-
sal_Bool AlphaMask::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
const AlphaMask* pAlphaSrc )
{
@@ -215,15 +197,11 @@ sal_Bool AlphaMask::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRect
}
-// -----------------------------------------------------------------------------
-
sal_Bool AlphaMask::Erase( sal_uInt8 cTransparency )
{
return Bitmap::Erase( Color( cTransparency, cTransparency, cTransparency ) );
}
-// -----------------------------------------------------------------------------
-
sal_Bool AlphaMask::Replace( const Bitmap& rMask, sal_uInt8 cReplaceTransparency )
{
BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
@@ -249,8 +227,6 @@ sal_Bool AlphaMask::Replace( const Bitmap& rMask, sal_uInt8 cReplaceTransparency
return bRet;
}
-// -----------------------------------------------------------------------------
-
sal_Bool AlphaMask::Replace( sal_uInt8 cSearchTransparency, sal_uInt8 cReplaceTransparency, sal_uLong
#ifdef DBG_UTIL
nTol
@@ -302,8 +278,6 @@ nTol
return bRet;
}
-// -----------------------------------------------------------------------------
-
void AlphaMask::ReleaseAccess( BitmapReadAccess* pAccess )
{
if( pAccess )
@@ -313,4 +287,35 @@ void AlphaMask::ReleaseAccess( BitmapReadAccess* pAccess )
}
}
+sal_Bool AlphaMask::Scale( const Size& rNewSize, sal_uLong nScaleFlag )
+{
+ sal_Bool bRet = Bitmap::Scale( rNewSize, nScaleFlag );
+
+ if( bRet )
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ return bRet;
+}
+
+sal_Bool AlphaMask::Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag )
+{
+ sal_Bool bRet = Bitmap::Scale( rScaleX, rScaleY, nScaleFlag );
+
+ if( bRet )
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ return bRet;
+}
+
+sal_Bool AlphaMask::ScaleCropRotate(
+ const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
+ const Color& rFillColor, sal_uLong nScaleFlag )
+{
+ sal_Bool bRet = Bitmap::ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor, nScaleFlag );
+ if( bRet )
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ return bRet;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 1ce4253509fb..a4900c6df6f2 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -2325,7 +2325,7 @@ sal_Bool Bitmap::ScaleCropRotate(
}
else
{
- bRet = ImplTransformBilinearFiltering( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor);
+ bRet = ImplTransformBilinearFiltering( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor);
}
return bRet;
@@ -2384,9 +2384,9 @@ bool Bitmap::ImplTransformAveraging( const double& rScaleX, const double& rScale
double unrotatedY = fSinAngle * x + fCosAngle * y;
if ( unrotatedX < 0
- || unrotatedX >= nScaledWidth
+ || unrotatedX > nScaledWidth
|| unrotatedY < 0
- || unrotatedY >= nScaledHeight)
+ || unrotatedY > nScaledHeight)
{
pWriteAccess->SetPixel( yOut, xOut, aFillColor );
}
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index e7df4762bfd0..5851b743dcfa 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -276,14 +276,16 @@ Bitmap BitmapEx::GetMask() const
AlphaMask BitmapEx::GetAlpha() const
{
- AlphaMask aAlpha;
-
if( IsAlpha() )
+ {
+ AlphaMask aAlpha;
aAlpha.ImplSetBitmap( aMask );
+ return aAlpha;
+ }
else
- aAlpha = aMask;
-
- return aAlpha;
+ {
+ return aMask;
+ }
}
sal_uLong BitmapEx::GetSizeBytes() const
@@ -391,47 +393,56 @@ sal_Bool BitmapEx::ScaleCropRotate(
const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel,
long nAngle10, const Color& rFillColor, sal_uLong nScaleFlag )
{
- bool bRet = false;
+ bool bReturn = false;
if( !!aBitmap )
{
- const bool bTransparentRotate = ( Color( COL_TRANSPARENT ) == rFillColor );
+ // If fill color is transpatent
+ const bool bTransparentRotation = Color( COL_TRANSPARENT ) == rFillColor;
- bool bRightAngleRotation = (nAngle10 == 0 || nAngle10 == 900 || nAngle10 == 1800 || nAngle10 == 2700);
+ // If angle is 0, 90, 180 or 270 degreees, then we don't need to create an alpha bitmap.
+ const bool bRightAngleRotation = (nAngle10 == 0 || nAngle10 == 900 || nAngle10 == 1800 || nAngle10 == 2700);
- if( !bRightAngleRotation && bTransparentRotate )
+ if( !bRightAngleRotation && bTransparentRotation )
{
if( eTransparent == TRANSPARENT_COLOR )
{
- bRet = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, aTransparentColor, nScaleFlag );
+ bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, aTransparentColor, nScaleFlag );
}
- else
+ else if( eTransparent == TRANSPARENT_NONE )
{
- bRet = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_BLACK, nScaleFlag );
- if( eTransparent == TRANSPARENT_NONE )
+ bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_BLACK, nScaleFlag );
+ if ( bReturn )
{
aMask = Bitmap( aBitmapSize, 1 );
aMask.Erase( COL_BLACK );
+ aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
eTransparent = TRANSPARENT_BITMAP;
}
-
- if( bRet && !!aMask )
+ } else {
+ bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_BLACK, nScaleFlag );
+ if( bReturn && !!aMask )
+ {
aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
+ aMask.Convert( BMP_CONVERSION_8BIT_GREYS );
+ }
}
}
else
{
- bRet = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor, nScaleFlag );
-
- if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
- aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
+ bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor, nScaleFlag );
+ if( eTransparent == TRANSPARENT_BITMAP && !!aMask )
+ {
+ bReturn = aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
+ aMask.Convert( BMP_CONVERSION_8BIT_GREYS );
+ }
}
}
- if (bRet)
+ if ( bReturn )
aBitmapSize = aBitmap.GetSizePixel();
- return bRet;
+ return bReturn;
}
sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor )