Skip to content

[6.40] [asimage] Fix filled shapes drawn with a semi-transparent colour - #23109

Open
root-project-bot wants to merge 2 commits into
root-project:v6-40-00-patchesfrom
root-project-bot:BP_6.40_pull_23023
Open

[6.40] [asimage] Fix filled shapes drawn with a semi-transparent colour#23109
root-project-bot wants to merge 2 commits into
root-project:v6-40-00-patchesfrom
root-project-bot:BP_6.40_pull_23023

Conversation

@root-project-bot

Copy link
Copy Markdown

Backport of #23023, requested by @dpiparo. For your information @tekinertekin

libAfterImage builds a filled shape by drawing its outline into a scratch
canvas, flood-filling the interior, and only then merging the scratch into the
image. That merge already applies the brush alpha, because it hands the scratch
value to alpha_blend_point_argb32() as the blend ratio -- but the colored tool
and fill functions were scaling what they wrote by the same alpha. It was
therefore applied twice, and the value the flood fill writes came to depend on
it while the threshold that fill compares against did not.

Two failures followed whenever TASImage::DrawCircle() and friends were given a
colour that is not fully opaque. At an alpha of 0x8C or below the value written
never left the range the fill accepts, so every filled pixel was rediscovered
and ctx_flood_fill() never returned. Between 0x8D and 0xFE it did return, but
the anti-aliased outline no longer reached the threshold either, so the fill
leaked past it and covered the whole image instead of the shape.

Writing the coverage unscaled fixes both, because the threshold comparison
stops depending on the brush. Output for a fully opaque brush is unchanged:
255 * ratio / 255 == ratio, and a circle, a manual filled path and an unfilled
circle all render bit-identically before and after.

Refs root-project#23014

Assisted-by: Claude (Anthropic); the change and the test were AI-assisted,
then reviewed, measured and verified by the author.

(cherry picked from commit 2eb51d4)
Covers both ways DrawCircle() failed before the previous commit: at an alpha of
0x7F it hung, and at 0xC0 it filled the whole image rather than the circle. The
opaque case guards the common path against a regression.

Corner pixels are compared against their own values from before the draw, so
the test does not depend on how a fresh TASImage is initialised.

Refs root-project#23014

Assisted-by: Claude (Anthropic); the change and the test were AI-assisted,
then reviewed, measured and verified by the author.

(cherry picked from commit 1d28aaa)
@github-actions

Copy link
Copy Markdown

Test Results

    22 files      22 suites   3d 11h 0m 8s ⏱️
 3 866 tests  3 864 ✅ 0 💤  2 ❌
76 343 runs  76 303 ✅ 0 💤 40 ❌

For more details on these failures, see this check.

Results for commit 649e612.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants