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:
Noel Grandin
2025-06-26 18:54:21 +02:00
parent b2919d5b5e
commit cb20cc8c3f
3 changed files with 65 additions and 7 deletions
@@ -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
+9
View File
@@ -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);
/**
+52
View File
@@ -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 );