Styles: overlays keep anti-aliased edges clean (#416)

Cause: the interior styles were blended over the layer body with the
content's coverage folded into their opacity. On an edge pixel at 50 %
coverage a Gradient or Color Overlay went over the half-transparent body
as a half-transparent layer, so the result kept a quarter of the layer's
own fill and its alpha rose to 0.75: a light rim (the white fill
showing through) on styled text.

Fix: blend_clipped composites the interior styles (Gradient Overlay,
Color Overlay, Satin, Inner Glow, Inner Shadow and the inside of
Stroke) onto the layer within its shape: the body is divided by the
content coverage, blended with the style at its own opacity, and
multiplied back, so the alpha is kept and an edge pixel mixes the style
with the layer's colour inside the shape only, as a clipped layer does.
Fill Opacity and Blend Interior Styles as Group behave as before.

Tests: tests_styles::overlays_leave_antialiased_edges_clean (a masked
square with half-covered edge columns; Color Overlay, Gradient Overlay
and an inside Stroke now match a plain layer of the overlay colour;
Color Overlay's edge was 0.41 red against 0.23 before).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
bflatasticandClaude Opus 5.5 committed 2026-10-09 23:17:32 +07:00
1 parent 88e2e6470a
commit 36ef45077a
4 files changed
+112 -22

No files matched your search

+3 -2
View File
@@ -207,8 +207,9 @@ switches that don't change pixels (Audio, Lock, Shy, Hide Shy Layers: `Switches:
**Layer styles** (Layer ▸ Layer Styles; `crates/render/src/styles.rs`) render in layer space and
may grow the layer's bounds. Drop Shadow and Outer Glow become separate passes composited below the
layer with their own blend modes; the interior styles, Stroke and Bevel and Emboss are baked into
the layer body. Layer opacity fades the whole stack; Knockout and the R/G/B channel switches apply
at composite time. Styled pixels are cached separately from the layer content, so editing a style
the layer body. Interior styles are clipped to the layer: they blend onto its colour inside its
shape and keep its alpha, so an anti-aliased edge mixes the style and the background only. Layer
opacity fades the whole stack; Knockout and the R/G/B channel switches apply at composite time. Styled pixels are cached separately from the layer content, so editing a style
reuses the cached source/masks/effects. Global Light is one setting per comp, mirrored into every
layer's Blending Options and kept in step after each edit.
+4
View File
@@ -408,6 +408,10 @@ Fixes from measured reports:
- Glyphs that touch or overlap ("ff") are drawn as one outline, so no light seam shows where
their anti-aliased edges meet (#415). Characters of other colours, with Blur, or under an
Inter-Character Blending mode are still composited one by one.
- Interior layer styles (Gradient / Color Overlay, Satin, Inner Glow, Inner Shadow, the inside of
Stroke) blend onto the layer's colour inside its alpha, so an anti-aliased edge no longer shows
a rim of the layer's own fill (#416). Not yet: Inner Bevel still shades an anti-aliased edge
over the layer's own colour.
## Update: plug-ins and extensions as in After Effects; ease presets become a ScriptUI panel