tdf#166715 speed up transparent fill operation (II)
second attempt at landing this, first attempt failed because I did not realise that this is an "extra" transparency on top of any transparency the image might already have. Dramatically speeds up rendering on most backends (the cairo drawinglayer renderer already has an optimised path here). Change-Id: I9da67767a9aa6418eaed478ed2de7710183d53ad Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187053 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
@@ -553,13 +553,6 @@ void VclProcessor2D::RenderFillGraphicPrimitive2D(
|
||||
return;
|
||||
}
|
||||
|
||||
if (rFillBitmapCandidate.hasTransparency())
|
||||
{
|
||||
// cannot handle yet, use decomposition
|
||||
process(rFillBitmapCandidate);
|
||||
return;
|
||||
}
|
||||
|
||||
bool bPrimitiveAccepted = RenderFillGraphicPrimitive2DImpl(rFillBitmapCandidate);
|
||||
|
||||
if (!bPrimitiveAccepted)
|
||||
@@ -649,6 +642,10 @@ bool VclProcessor2D::RenderFillGraphicPrimitive2DImpl(
|
||||
aBitmapEx.Scale(aNeededBitmapSizePixel, BmpScaleFlag::Interpolate);
|
||||
}
|
||||
|
||||
if (rFillBitmapCandidate.hasTransparency())
|
||||
aBitmapEx.BlendAlpha(
|
||||
static_cast<sal_uInt8>(255 - (rFillBitmapCandidate.getTransparency() * 255)));
|
||||
|
||||
if (maBColorModifierStack.count())
|
||||
{
|
||||
// when color modifier, apply to bitmap
|
||||
|
||||
@@ -434,8 +434,17 @@ public:
|
||||
|
||||
SAL_DLLPRIVATE void ChangeColorAlpha( sal_uInt8 cIndexFrom, sal_Int8 nAlphaTo );
|
||||
|
||||
/**
|
||||
* Adds a constant value to the alpha layer
|
||||
*/
|
||||
SAL_DLLPRIVATE void AdjustTransparency( sal_uInt8 cTrans );
|
||||
|
||||
/**
|
||||
* Blends, i.e. multiplies the alpha layer with the new alpha value.
|
||||
*/
|
||||
void BlendAlpha( sal_uInt8 nAlpha );
|
||||
|
||||
|
||||
void CombineMaskOr(Color maskColor, sal_uInt8 nTol);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1375,6 +1375,58 @@ void BitmapEx::AdjustTransparency(sal_uInt8 cTrans)
|
||||
*this = BitmapEx( GetBitmap(), aAlpha );
|
||||
}
|
||||
|
||||
void BitmapEx::BlendAlpha(sal_uInt8 nAlpha)
|
||||
{
|
||||
AlphaMask aAlpha;
|
||||
|
||||
if (!IsAlpha())
|
||||
{
|
||||
sal_uInt8 cTrans = 255 - nAlpha;
|
||||
aAlpha = AlphaMask(GetSizePixel(), &cTrans);
|
||||
}
|
||||
else
|
||||
{
|
||||
aAlpha = GetAlphaMask();
|
||||
BitmapScopedWriteAccess pA(aAlpha);
|
||||
assert(pA);
|
||||
|
||||
if( !pA )
|
||||
return;
|
||||
|
||||
const tools::Long nWidth = pA->Width(), nHeight = pA->Height();
|
||||
|
||||
if( pA->GetScanlineFormat() == ScanlineFormat::N8BitPal )
|
||||
{
|
||||
for( tools::Long nY = 0; nY < nHeight; nY++ )
|
||||
{
|
||||
Scanline pAScan = pA->GetScanline( nY );
|
||||
|
||||
for( tools::Long nX = 0; nX < nWidth; nX++ )
|
||||
{
|
||||
sal_uInt8 nNewAlpha = static_cast<sal_Int32>(nAlpha) * (*pAScan) / 255;
|
||||
*pAScan++ = nNewAlpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BitmapColor aAlphaValue( 0 );
|
||||
|
||||
for( tools::Long nY = 0; nY < nHeight; nY++ )
|
||||
{
|
||||
Scanline pScanline = pA->GetScanline( nY );
|
||||
for( tools::Long nX = 0; nX < nWidth; nX++ )
|
||||
{
|
||||
sal_uInt8 nNewAlpha = static_cast<sal_Int32>(nAlpha) * (pA->GetIndexFromData( pScanline, nX )) / 255;
|
||||
aAlphaValue.SetIndex( nNewAlpha );
|
||||
pA->SetPixelOnData( pScanline, nX, aAlphaValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*this = BitmapEx( GetBitmap(), aAlpha );
|
||||
}
|
||||
|
||||
void BitmapEx::CombineMaskOr(Color maskColor, sal_uInt8 nTol)
|
||||
{
|
||||
AlphaMask aNewMask = maBitmap.CreateAlphaMask( maskColor, nTol );
|
||||
|
||||
Reference in New Issue
Block a user