Status: Reference (current as of 2026-08-18)
When Donner's rendering of a resvg-test-suite case is correct but the upstream golden is not the right thing to compare against, the test pins Params::WithGoldenOverride("donner/svg/renderer/testdata/golden/resvg-<name>.png") so it compares against a Donner-blessed golden instead. This doc is the catalog of every such override and the reason it exists.
There are two distinct reasons an override is justified:
Custom goldens live in donner/svg/renderer/testdata/golden/resvg-<test-name>.png, named with the new (post-Great-Rename) test stem. The rationale for each is the .withReason("…") argument chained onto the override in resvg_test_suite.cc — grep the test name there to find it inline.
Naming note: these used the old a-* / e-* convention before the suite upgrade (0022). The four originally documented here mapped forward as: a-filter-013/a-filter-015 → drop-shadow-function-mm-values/drop-shadow-function-em-values (now parked, see below); e-marker-045/e-marker-051 (closed-shape / cusp marker direction) were superseded upstream and retired — the surviving marker override is orient=auto-on-M-C-C-4.
| Category | Test | Reason (withReason) |
|---|---|---|
| filters/feSpotLight | complex-transform | resvg bug: SpotLight Y |
| filters/feImage | svg | We render higher quality |
| filters/feSpecularLighting | with-fePointLight | resvg golden |
| painting/context | with-pattern-objectBoundingBox-in-use | resvg golden bakes fractional-tile rounding |
| painting/marker | orient=auto-on-M-C-C-4 | Pre-existing rendering diff (stroke/AA), not cusp-related |
| painting/marker | with-an-image-child | We (correctly) render the image child |
| painting/paint-order | on-tspan | Preserve cross-span kerning across a paint-only tspan boundary |
| text/font-size | named-value | Donner uses CSS Fonts Level 4 |
| text/font-size | named-value-without-a-parent | Donner uses CSS Fonts Level 4 |
named-value{,-without-a-parent} reflect CSS Fonts Level 4's revised handling of named font sizes (xx-small … xx-large), which differs from resvg's older table.
with-pattern-objectBoundingBox-in-use runs against a committed Donner render (resvg-with-pattern-objectBoundingBox-in-use.png), shared by both backends (TinyGolden and GeodeGolden pass at the default budget). Evidence that resvg's golden is the artifact: resvg rasterizes pattern tiles at a rounded integer pixel size, and this test's context bounding box yields a fractional 56.57px on-screen tile that resvg draws as 57px, stretching the tile period by ~0.8%. Donner repeats the tile at the exact period. A numeric grid fit confirms it: Donner's render fits an ideal diamond grid anchored at the computed context box (31.82, -116.67), 226.27² with score 1.0, while resvg's golden fits no ideal grid (best score 0.899 — its grid drifts, consistent with per-tile rounding). The integer-tile pattern goldens in the same category (with-pattern-in-use, with-pattern-and-transform-in-use, with-pattern-on-marker, whose tiles land on exact pixel sizes) match Donner exactly, isolating the discrepancy to the fractional-tile case. Revisit if resvg regenerates goldens without the rounding.
CSS Images permits an implementation-selected edge-preserving algorithm for crisp-edges; deprecated optimizeSpeed maps to that value. An alternate nearest sampling grid does not establish that the upstream reference violates the specification.
| Category | Test | Reason |
|---|---|---|
| painting/image-rendering | on-feImage | Nearest sampling at destination pixel centers |
The project reference retains all vendored reference pixels outside the image primitive. Inside, the decoded 64 x 64 RGBA source is sampled with source_index = floor((destination_index + 0.5) * 64 / destination_extent). The default filter region expands the (40, 40, 120, 120) object box by 10% on each side, producing (70, 70, 360, 360) after the 500 / 200 viewport scale. All 129,600 image-region pixels follow this independent geometric construction. The separate optimizeSpeed fixture remains classified pending reference qualification: CPU and GPU can choose adjacent source texels at exact nearest sampling ties, an allowed algorithm choice rather than missing SVG support.
These render correctly but differ from resvg because Donner's text stack (and the simple-vs-text-full split) shapes/composes differently. The golden is whichever Donner backend the test runs under.
| Category | Test | Reason |
|---|---|---|
| text/text | complex-graphemes-and-coordinates-list | Simple text can't compose combining marks |
| text/text | compound-emojis-and-coordinates-list | Emoji bitmap scaling differs from the golden |
| text/text | rotate-on-Arabic | Arabic shaping requires text-full |
| text/text | x-and-y-with-multiple-values-and-arabic-text | Arabic shaping; vertical-axis AA diff not the focus |
The text/textPath family carries the bulk of the overrides: sub-pixel character advance and anti-aliasing differences along curved baselines, which differ between the simple and text-full backends. All are .withReason("Minor char") unless noted.
| Category | Test | Reason |
|---|---|---|
| text/textPath | dy-with-tiny-coordinates | AA + minor char advance diffs (text vs text-full) |
| text/textPath | m-L-Z-path | Minor char |
| text/textPath | mixed-children-1 | AA diffs |
| text/textPath | nested | Minor char |
| text/textPath | path-with-ClosePath | Minor char |
| text/textPath | simple-case | Minor char |
| text/textPath | startOffset=-100 | Minor char |
| text/textPath | startOffset=10percent | Minor char |
| text/textPath | startOffset=30 | Minor char |
| text/textPath | startOffset=5mm | Minor char |
| text/textPath | tspan-with-absolute-position | Minor char |
| text/textPath | tspan-with-relative-position | Minor char |
| text/textPath | two-paths | Minor char |
| text/textPath | very-long-text | AA diffs |
| text/textPath | with-baseline-shift | Minor char |
| text/textPath | with-coordinates-on-text | Minor char |
| text/textPath | with-coordinates-on-textPath | Minor char |
| text/textPath | with-rotate | Minor char |
| text/textPath | with-text-anchor | (no reason string) |
| text/textPath | with-transform-on-a-referenced-path | Minor char |
| text/textPath | with-transform-outside-a-referenced-path | Minor char |
| text/textPath | with-underline | Minor char |
| text/text-decoration | indirect | (no reason string) |
Two entries (textPath/with-text-anchor, text-decoration/indirect) carry no withReason. They should either get one or migrate to a per-test threshold; the "Minor char" cluster is the precedent. Tracked in 0021.
resvg-drop-shadow-function-mm-values.png and resvg-drop-shadow-function-em-values.png are the migrated successors of the old a-filter-013 / a-filter-015 drop-shadow blur-halo cases: Donner's three-pass box-blur approximation (correct per CSS Filter Effects L1 §8 / SVG §15.9) produces a different halo shape than resvg's blur, so a Donner golden is required.
They are currently unreferenced. The filters/filter-functions category is active, with 26 of 43 files comparing on both backends and 17 explicit Triage: skips. No project-owned oracle has been accepted for the two unit-based drop-shadow cases yet. Keep both files until normative specification/browser triage decides whether each mismatch is a Donner defect, a vendored-oracle difference, or a justified project golden. Do not delete them as "orphans".
Three goldens added by #515 were never referenced by any override and were removed as dead data (recoverable from git history if a real override need surfaces):
The corresponding text/font-size tests pass against the upstream golden — only named-value{,-without-a-parent} need an override. After this cleanup the golden/ dir holds exactly 39 resvg-*.png: 37 active + the 2 parked drop-shadow goldens above.