Repository navigation
Optimize clipped layers - #1158
Merged
Merged
Conversation
Groups whose content is much larger than their clip path, as produced by illustration tools: clip via `use`, subpixel clip on content larger than the canvas, clip partially outside the canvas or outside the content, scaled and mirrored clip transforms, nested clipped groups and `clipPathUnits=objectBoundingBox`. Reference images rendered with the current renderer.
…-generated) A clipped group gets a layer sized to its whole content, then the clip mask is applied to that whole layer. When the clip path is much smaller than the content (common in files exported from illustration tools, which wrap shapes in <clipPath><use/></clipPath>), most of that work is thrown away, and its cost grows with the layer area. This shrinks the layer to the intersection with the clip path bounds (expanded by 2px, like group layers), only for simple cases: clip paths made of paths (possibly wrapped in plain groups, as <use> produces), without nested clip path, mask, filter or text, and without rotation or skew. Other cases keep the current behaviour. On a synthetic file (100 groups whose content covers the canvas, each clipped to a 40x40 square), rendering time drops from 0.96 s to 0.018 s at 1000 px and from 31.7 s to 0.44 s at 4000 px. Because the layer origin moves, floating-point rounding changes the anti-aliasing of a few edge pixels inside the clipped content. Two of the new clip-path tests are affected (28 and 5 pixels, by at most 16/255 per channel); their reference images are updated. Disclosure: this change was written end to end by an LLM (Claude), as an exploration. It is published as inspiration only, not as a contribution, per the Linebender LLM contribution policy.
LaurenzV
force-pushed
the
clip-path-layer-bounds
branch
from
October 17, 2026 12:28
eb5a037 to
a540913
Compare
Collaborator
|
Thank you, huge improvement! I applied two tweaks:
|
Collaborator
|
Ah sorry, I realized that the additional tests were requested by @RazrFalcon. But as mentioned we already have plenty of tests and there isn't much magic in this fix, so I think it should be fine. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix for #1146
A clipped group's layer was the size of its whole content, even when the clip path only lets a small part through. This shrinks the layer to the clip path bounds (+2 px for anti-aliasing).
It only applies to simple cases: a clip path made of paths only, no mask or filter, and no rotation or skew.
Adds 8 clip-path tests, with reference images rendered on
main. In 2 of them, the moved layer origin changes the anti-aliasing of a few edge pixels (at most 28 pixels, at most 16/255 per channel). Those 2 references are updated in the fix commit. All existing tests still render exactly as before.Written by an LLM (Claude opus 5.5), per the Linebender LLM policy.