[Libreoffice-commits] .: Branch 'libreoffice-3-5' - 2 commits - vcl/source
Caolán McNamara
caolan at kemper.freedesktop.org
Thu Apr 5 08:10:07 PDT 2012
vcl/source/gdi/outdev2.cxx | 84 ++++++++++++++++++++++++---------------------
1 file changed, 45 insertions(+), 39 deletions(-)
New commits:
commit 7a9ea6e5696af0816651675d8f7538198cdce4da
Author: Muthu Subramanian <sumuthu at suse.com>
Date: Thu Mar 29 16:08:56 2012 +0530
n714787: Duplicate code removal.
(cherry picked from commit 27d9df17c13b22aed7d9194d9dfcf7980b632b3c)
Signed-off-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx
index 23a7952..2b2e375 100644
--- a/vcl/source/gdi/outdev2.cxx
+++ b/vcl/source/gdi/outdev2.cxx
@@ -1623,6 +1623,36 @@ namespace
(int)nDstAlpha*nDestColor*nSourceAlpha/255 ) / (int)nResAlpha : 0;
return sal_uInt8( c );
}
+
+inline BitmapColor lcl_AlphaBlend( int nX, int nY,
+ const long nMapX,
+ const long nMapY,
+ BitmapReadAccess* pP,
+ BitmapReadAccess* pA,
+ BitmapReadAccess* pB,
+ BitmapWriteAccess* pAlphaW,
+ sal_uInt8& nResAlpha )
+{
+ BitmapColor aDstCol,aSrcCol;
+ aSrcCol = pP->GetColor( nMapY, nMapX );
+ aDstCol = pB->GetColor( nY, nX );
+
+ // vcl stores transparency, not alpha - invert it
+ const sal_uInt8 nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
+ const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
+
+ // Perform porter-duff compositing 'over' operation
+ //
+ // Co = Cs + Cd*(1-As)
+ // Ad = As + Ad*(1-As)
+ nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255;
+
+ aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
+ aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
+ aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
+
+ return aDstCol;
+}
}
// ------------------------------------------------------------------------
@@ -1638,9 +1668,10 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp,
const long* pMapX,
const long* pMapY )
{
- BitmapColor aDstCol,aSrcCol;
+ BitmapColor aDstCol;
Bitmap res;
int nX, nY;
+ sal_uInt8 nResAlpha;
OSL_ENSURE(mpAlphaVDev,
"ImplBlendWithAlpha(): call me only with valid alpha VDev!" );
@@ -1673,22 +1704,7 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp,
const long nMapX = pMapX[ nX ];
const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];
- aSrcCol = pP->GetColor( nMapY, nMapX );
- aDstCol = pB->GetColor( nY, nX );
-
- // vcl stores transparency, not alpha - invert it
- const sal_uInt8 nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
- const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
-
- // Perform porter-duff compositing 'over' operation
- //
- // Co = Cs + Cd*(1-As)
- // Ad = As + Ad*(1-As)
- const sal_uInt8 nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255;
-
- aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
- aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
- aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
+ aDstCol = lcl_AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha );
aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] +
nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] +
@@ -1719,23 +1735,7 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp,
for( nX = 0; nX < nDstWidth; nX++ )
{
const long nMapX = pMapX[ nX ];
-
- aSrcCol = pP->GetColor( nMapY, nMapX );
- aDstCol = pB->GetColor( nY, nX );
-
- // vcl stores transparency, not alpha - invert it
- const sal_uInt8 nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
- const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
-
- // Perform porter-duff compositing 'over' operation
- //
- // Co = Cs + Cd*(1-As)
- // Ad = As + Ad*(1-As)
- const sal_uInt8 nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255;
-
- aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
- aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
- aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
+ aDstCol = lcl_AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha );
pB->SetPixel( nY, nX, aDstCol );
pAlphaW->SetPixel( nY, nX, Color(255L-nResAlpha, 255L-nResAlpha, 255L-nResAlpha) );
commit 821362c208cb519d41cba09260694846bddfc080
Author: Thorsten Behrens <tbehrens at suse.com>
Date: Tue Mar 27 02:54:42 2012 +0200
Fix vcl alpha blending n#714787
The way alpha compositing took place in vcl's alpha vdev was subtly
wrong - it was supposed to implement porter-duff 'over', but didn't.
This is now fixed also for cases where the source surface contains
alpha, and needs to blend correctly into fully-transparent
background.
For reference: http://en.wikipedia.org/wiki/Alpha_compositing
(cherry picked from commit 06c16e1e26a0137a0048085cdf1c7758d3ac96cd)
Signed-off-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx
index d8d847e..23a7952 100644
--- a/vcl/source/gdi/outdev2.cxx
+++ b/vcl/source/gdi/outdev2.cxx
@@ -1614,11 +1614,14 @@ void OutputDevice::DrawPixel( const Polygon& rPts, const Color& rColor )
namespace
{
- sal_uInt8 lcl_calcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceOpaq, const sal_uInt8 nDestColor )
+ // Co = Cs + Cd*(1-As) premultiplied alpha -or-
+ // Co = (AsCs + AdCd*(1-As)) / Ao
+ inline sal_uInt8 lcl_calcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceAlpha,
+ const sal_uInt8 nDstAlpha, const sal_uInt8 nResAlpha, const sal_uInt8 nDestColor )
{
- int c = ( (int)nDestColor * ( 255 - nSourceOpaq ) )
- + (int)nSourceOpaq * (int)nSourceColor;
- return sal_uInt8( c / 255 );
+ int c = nResAlpha ? ( (int)nSourceAlpha*nSourceColor + (int)nDstAlpha*nDestColor -
+ (int)nDstAlpha*nDestColor*nSourceAlpha/255 ) / (int)nResAlpha : 0;
+ return sal_uInt8( c );
}
}
@@ -1672,27 +1675,29 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp,
aSrcCol = pP->GetColor( nMapY, nMapX );
aDstCol = pB->GetColor( nY, nX );
- const sal_uInt8 nSrcOpaq = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
- const sal_uInt8 nDstOpaq = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
- aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) );
- aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) );
- aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) );
+ // vcl stores transparency, not alpha - invert it
+ const sal_uInt8 nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
+ const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
+
+ // Perform porter-duff compositing 'over' operation
+ //
+ // Co = Cs + Cd*(1-As)
+ // Ad = As + Ad*(1-As)
+ const sal_uInt8 nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255;
+
+ aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
+ aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
+ aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] +
nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] +
nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) );
pW->SetPixel( nY, nX, aIndex );
- // Have to perform the compositing 'algebra' in
- // the inverse alpha space (with 255 meaning
- // opaque), otherwise, transitivity is not
- // achieved.
- const sal_uInt8 nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (sal_uInt8)nDstOpaq, nSrcOpaq );
-
- aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] +
- nVCLGLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] +
- nVCLBLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] ) );
+ aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] +
+ nVCLGLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] +
+ nVCLBLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] ) );
pAlphaW->SetPixel( nY, nX, aIndex );
}
}
@@ -1717,22 +1722,23 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp,
aSrcCol = pP->GetColor( nMapY, nMapX );
aDstCol = pB->GetColor( nY, nX );
- const sal_uInt8 nSrcOpaq = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
- const sal_uInt8 nDstOpaq = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
- aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) );
- aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) );
- aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) );
+ // vcl stores transparency, not alpha - invert it
+ const sal_uInt8 nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
+ const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
- pB->SetPixel( nY, nX, aDstCol );
+ // Perform porter-duff compositing 'over' operation
+ //
+ // Co = Cs + Cd*(1-As)
+ // Ad = As + Ad*(1-As)
+ const sal_uInt8 nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255;
- // Have to perform the compositing 'algebra' in
- // the inverse alpha space (with 255 meaning
- // opaque), otherwise, transitivity is not
- // achieved.
- const sal_uInt8 nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (sal_uInt8)nDstOpaq, nSrcOpaq );
+ aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
+ aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
+ aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
- pAlphaW->SetPixel( nY, nX, Color(nSrcAlpha, nSrcAlpha, nSrcAlpha) );
+ pB->SetPixel( nY, nX, aDstCol );
+ pAlphaW->SetPixel( nY, nX, Color(255L-nResAlpha, 255L-nResAlpha, 255L-nResAlpha) );
}
}
}
More information about the Libreoffice-commits
mailing list