WPT Compliance Gallery
phpdftk renders HTML and SVG to PDF, and we verify it against the Web Platform Tests reftest corpus — the same suite the browser engines are held to. This gallery puts the raw test, our render, and the WPT reference next to each other so you can judge compliance visually, not just from a pass-rate number.
Each cell is one test: our render as a thumbnail, a pass/fail badge, and the
pixel absolute-error (AE) against the reference. Click a cell to open the
side-by-side detail view with the full renders and a link to the upstream
test source. Filter by verdict, AE band, cluster, or test flag
(ahem font, image, script).
How the gallery is generated
Section titled “How the gallery is generated”scripts/build-wpt-gallery.php walks a --filter glob slice of the corpus
and, per test:
- renders our output (test → PDF → PNG) through the real harness pipeline,
- locates and renders the WPT reference (sibling
-ref.*or<link rel="match">), the same way the pass-rate harness does, - scores the pair with ImageMagick (
compare -metric AE, honoring the test’s<meta name="fuzzy">tolerance), - downscales thumbnails and records a manifest row.
# one cluster, reftests only, 30-test capphp scripts/build-wpt-gallery.php --filter='css/css-backgrounds/background-*' \ --only-reftests --limit=30
# the full corpus, sharded across CI runnersphp scripts/build-wpt-gallery.php --filter='css/**' --shard=3/16Output lands in docs/generated/wpt-gallery/ (gitignored): a manifest.json
plus img/<slug>.{ours,ref}.png full renders and .thumb.png thumbnails.
Resolution and the rounding rule
Section titled “Resolution and the rounding rule”The renderer emits 1 CSS pixel as 1 PDF point, and never rounds a
coordinate: ContentStream::num() formats every real at %.10f, so
layout geometry reaches the page at full precision. That makes the
rasteriser the pipeline’s only rounding site, and it settles two
questions.
How big a device pixel is. A point is 1/72”, so Rasteriser
renders at 72 dpi and one CSS pixel becomes exactly one device
pixel — the geometry WPT reftests are authored against. Sampling
denser would cancel for the reftest comparison itself, since both
sides scale together, but it does not cancel for a fixture’s
<meta name="fuzzy"> totalPixels budget: that is an absolute count
of differing pixels, and at 96 dpi each one was being asked to cover
(96/72)² = 1.78× the pixels its author allowed for.
Which device pixel an edge belongs to. Ghostscript expands path
fills by half a device pixel before scan-converting them, so a
re … f paints every pixel it touches, while shadings, image XObjects
and glyphs are resolved at the pixel centre. An edge in the upper
half of a pixel therefore lands in one column when a rectangle draws
it and the next column right when a gradient, an image or a glyph
draws it. A reftest reaches the same picture down two different paint
paths by construction — a gradient with a hard stop against the solid
blocks of its reference — so the disagreement surfaces as a
whole-colour seam one pixel wide and fails an exact-match comparison.
The rasteriser zeroes the fill adjustment (0 0 .setfilladjust2), so
the whole pipeline rounds one way: pixel centre.
The cost is dropout protection. A fill thinner than a device pixel that clears every pixel centre now paints nothing. At one device pixel per CSS pixel anything a full CSS pixel wide or wider always covers exactly one centre whatever its sub-pixel phase, so the exposure is limited to explicitly sub-pixel rules.
Manifest schema (v1)
Section titled “Manifest schema (v1)”{ "schema": 1, "generatedAt": "2026-07-30T12:00:00+00:00", "filter": "css/css-backgrounds/background-*", "shard": "3/16", "count": 30, "summary": { "pass": 23, "fail": 7, "noRef": 0, "renderError": 0, "unknown": 0 }, "tests": [ { "testId": "css/css-backgrounds/background-clip-content-box-001", "source": "css/css-backgrounds/background-clip-content-box-001.html", "assert": "…the <meta name=assert> text…", "ours": "img/…ours.png", "oursThumb": "img/…ours.thumb.png", "reference": "img/…ref.png", "referenceThumb": "img/…ref.thumb.png", "referenceSource": "css/css-backgrounds/…-ref.html", "engines": {}, "verdict": "pass", "ae": { "reference": 0.0011 }, "flags": ["image"] } ]}The engines map is reserved for the cross-browser oracle (Blink / Gecko /
WebKit print-to-PDF), which the detail view will surface as extra columns in a
later phase.