Skip to content

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% on html5lib-tests tree-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.

In-scope pass rate against the Web Platform Tests corpus, classified per packages/wpt-harness/scope/rendering.json:

CorpusIn-scope testsPass rateDetail
mathml/167100.00%MathML WPT substrate
svg/17495.40%SVG WPT substrate
html/58495.72%HTML WPT substrate
css/21 27065.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.

  • 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)
  • JavaScript execution. <script> is parsed but never run. Event handlers (onclick, etc.) are dropped at paint time. The Custom Elements registry, MutationObserver/IntersectionObserver and 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).