HTML & SVG Rendering
phpdftk ships a full HTML/CSS rendering engine targeting browser print-stylesheet parity, an SVG-to-PDF translator, and a MathML renderer for math content. All three consume a shared CSS + text-shaping substrate, all three emit vector PDF (no intermediate raster).
This section documents:
Parsers (typed-tree producers)
phpdftk/html— WHATWG HTML5 parser with DOM and declarative shadow DOM (100% onhtml5lib-teststree-construction).phpdftk/svg— SVG 2 parser producing a typed tree.phpdftk/mathml— MathML Core parser producing a typed tree.phpdftk/css— CSS Syntax 3 / Values 4 / Selectors 4 / Cascade 5 implementation.phpdftk/text— UAX #14 line breaking, UAX #9 bidi, OpenType GSUB/GPOS shaping.
Renderers (PDF emitters)
- HTML to PDF — render HTML + CSS to PDF, with inline
<math>and<svg>routed through their dedicated painters. - SVG to PDF — render SVG to PDF via the geometric painter.
Cross-cutting
- Cross-browser sweep — how the cross-browser PDF oracle (WebKit + Blink + Gecko) validates output beyond the WPT harness.
- DOM settler — computed-style projection from headless browser into a serialisable DOM snapshot.
- Fonts — font discovery, embedding, and subsetting.
Current WPT pass rates
Section titled “Current WPT pass rates”In-scope pass rate against the Web Platform Tests corpus, classified per packages/wpt-harness/scope/rendering.json:
| Corpus | In-scope tests | Pass rate | Detail |
|---|---|---|---|
| mathml/ | 167 | 100.00% | MathML WPT substrate |
| svg/ | 174 | 95.40% | SVG WPT substrate |
| html/ | 584 | 95.72% | HTML WPT substrate |
| css/ | 21 270 | 65.03% | per-module breakdown in phpdftk/css |
CSS is the bulk of the remaining gap to a 100% v1 claim by 2027-01-01 (the full-spec compliance freeze). HTML, SVG, and MathML are at substrate-completion levels.
What’s in scope
Section titled “What’s in scope”- CSS 2.1 visual formatting (block-and-inline, tables, lists)
- CSS Paged Media 3 (
@page, page boxes, named pages, margin boxes) - CSS Fragmentation 4 (
break-before/after/inside, orphans/widows) - CSS Multi-column Layout 1
- CSS Flexible Box Layout 1
- CSS Grid Layout 2
- CSS Transforms 2 (2D; 3D flattened to 2D)
- Filter Effects 1 (raster filters — Phase 4C)
- CSS Custom Properties for Cascading Variables 1 (case-sensitive)
- CSS Writing Modes 4
- CSS Containment 3 (size containment with
contain-intrinsic-*) - CSS Backgrounds 4 (
background-clip: border-area) - Full Declarative Shadow DOM (slot distribution,
:host/::slotted/::part/::theme)
What’s not in scope
Section titled “What’s not in scope”- JavaScript execution.
<script>is parsed but never run. Event handlers (onclick, etc.) are dropped at paint time. The Custom Elements registry,MutationObserver/IntersectionObserverand similar runtime APIs are not implemented at any phase. Use headless Chromium (Puppeteer, Playwright) if you need scripted rendering. - Imperative
Element.attachShadow()from author script (declarative<template shadowrootmode>is supported). - Interactive features (forms, links to JavaScript, animations beyond static initial-frame).