Repository navigation
fix(svg): a gradient takes its stops, and what it does not set, from the gradient its href names - #481
Merged
Conversation
…the gradient its href names A gradient may name another with `href` or `xlink:href`, and takes from it what it does not set itself, and its stops where it has none of its own, at any depth (SVG 1.1, 13.2.2). An editor writes a drawing's colours once, as a gradient of stops alone, and each gradient that uses them as a line with a reference to it. `SvgView` read a gradient's own attributes and children and nothing else: such a gradient had no stops, and what it filled was not drawn. The crane down the left of the CSS Zen Garden's 219, a 59 KB drawing every path of which is filled so, was missing whole. A gradient is now read with the ones it takes after, each once, so two that name each other end. `gradientTransform` is read too, which the same files carry, in the bounding box's space where that is the gradient's units. A linear gradient's line goes where the matrix takes its lines of one colour, which is where the matrix takes its ends only while it keeps right angles. A radial gradient's centre goes with the matrix and its radius with the matrix's scale, and one a matrix stretches stays a circle, of the same area, since a context's radial gradient is one. Two tests hold the chain, a radial gradient taking a linear one's stops, stops of its own winning and a loop, and a moved, a stretched and a turned line and a scaled circle. Each fails without the part it is for. docs/svg.md lists both.
Owner
Author
sidorares
pushed a commit
that referenced
this pull request
Sep 30, 2026
🤖 I have created a release *beep* *boop* --- ## [8.17.2](v8.17.1...v8.17.2) (2026-09-30) ### Bug Fixes * **svg:** a gradient takes its stops, and what it does not set, from the gradient its href names ([#481](#481)) ([9db8108](9db8108)) * **text:** a font weight between two of the hundreds goes to fontconfig on its own scale, so 450 in Arial is the regular and not the bold ([#480](#480)) ([3973b42](3973b42)) * **text:** a variable font is instantiated out of a WOFF or a WOFF2, where the first weight off the file's default threw ([#479](#479)) ([b009cdd](b009cdd)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
sidorares
added a commit
that referenced
this pull request
Oct 1, 2026
…old, where it drew nothing (#497) A `<switch>` renders the first of its child elements whose conditional processing attributes hold, and none of the rest. `SvgView` had no case for it, read it as a shape, found no geometry and drew nothing under it. The CSS Zen Garden's 219 wraps the ring of three of its footer icons in one, a single plain `<path>` inside a `<switch transform="matrix(…)">`, and those icons came out as their inner glyph alone. A switch is now a group of one: its own transform and opacity apply as a `<g>`'s do, and it draws the first child that holds. That child is drawn as it says, so one that is `display: none` is chosen and draws nothing, as SVG 2 has it and browsers do. The attributes are read on every element, as SVG 1.1, 5.8 asks, and the paint scan walks the same way, so `paintKind` counts only the chosen child. `requiredExtensions` never holds, since none is supported: that is the Illustrator export, its own data in a `foreignObject` behind Adobe's extension and the drawing after it. `requiredFeatures` holds unless it names a feature drawn nothing of here, `foreignObject` above all, so a draw.io label draws as the `<text>` written after it for renderers without one; browsers, which dropped the attribute, take the `foreignObject`. `systemLanguage` matches a new `languages` option, `navigator.languages` or the runtime's locale by default, a tag matching another narrowed or widened by a subtag. Gradients that take their stops through `xlink:href`, the other gap found on 219, were fixed in #481 and released in 8.17.3. Five mock tests and a pixel test cover it, each failing without the fix. docs/svg.md gains a section on conditional processing. 219's footer.svg at half size, master on the left, this branch on the right, rendered headless into a pixmap through XQuartz: <img width="572" alt="footer.svg before and after" src="https://github.com/user-attachments/assets/403cae6b-9884-409b-b139-6be5fa166a8f" />
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.

A gradient may name another with
hreforxlink:href, and takes from itwhat it does not set itself, and its stops where it has none of its own, at
any depth (SVG 1.1, 13.2.2). An editor writes a drawing's colours once, as
a gradient of stops alone, and each gradient that uses them as a line with
a reference to it.
SvgViewread a gradient's own attributes and childrenand nothing else: such a gradient had no stops, and what it filled was not
drawn. The crane down the left of the CSS Zen Garden's 219, a 59 KB drawing
every path of which is filled so, was missing whole.
A gradient is now read with the ones it takes after, each once, so two that
name each other end.
gradientTransformis read too, which the same filescarry, in the bounding box's space where that is the gradient's units. A
linear gradient's line goes where the matrix takes its lines of one colour,
which is where the matrix takes its ends only while it keeps right angles.
A radial gradient's centre goes with the matrix and its radius with the
matrix's scale, and one a matrix stretches stays a circle, of the same
area, since a context's radial gradient is one.
Two tests hold the chain, a radial gradient taking a linear one's stops,
stops of its own winning and a loop, and a moved, a stretched and a turned
line and a scaled circle. Each fails without the part it is for.
docs/svg.md lists both.