Loading…
Loading…
A live HTML-to-PDF preview is normally a browser rendering the same markup beside a PDF produced somewhere else. Two engines, two answers, and you find out which one was lying after you export. The playground is built the other way round: there is one layout pass, and the two pictures are two ways of drawing it.
The engine has two exports. render() returns PDF bytes. scene() returns the display list those bytes are written from — the same box tree, the same fragmentation, the same shaped glyph runs, plus the page furniture: running headers, page counters, footnotes, repeated table headers. The canvas paints that list. It is not a rendering of your HTML; it is a rendering of your PDF.
Measured on the paged-report template, canvas against the file it downloads, rasterised to the same size: the page-number band differs on 0.03% of pixels, the whole page on 1.6% — all of it anti-aliasing, because two rasterisers never agree on an edge pixel. The geometry underneath is one measurement.
The engine is compiled to WebAssembly and loaded into a worker, once, with the four font faces it falls back on. After that a page lays out in single-digit milliseconds on the machine you are reading this on. There is no render endpoint behind the playground, which is also why it keeps working with the network off.
Every document you make here carries a faint watermark across the middle of the page. Nothing is written into the running header or footer: those belong to the document, and a header saying something its author did not write is a worse artefact than an honest mark.
Template is HTML and CSS as a whole document. Paged-media CSS works: @page size and margins, named pages of different sizes, forced breaks, position: running() headers, counter(page), float: footnote.
Data is a JSON object; {{ variable }} and {% for %} are filled from it before layout, with the filters the server template renderer has — currency, date, number_format, slice.
Options is what the engine is told about the sheet. These are defaults, not overrides: a document that declares its own @page owns its pages, including named ones of different sizes.
The honest answer is a test run, not a feature list. The engine goes through the Web Platform Tests — the reftest corpus browsers are judged by — and every verdict is published, failures included. Today: 89.96% of 19,554 judged tests, out of 23,994 in the corpus.
Not a public one yet. The render endpoint exists — the editor uses it — but it is not documented or authenticated for outside callers, so we do not advertise it as a product. Opening it is the next thing on the engine roadmap: HTML and CSS in, tagged PDF out, with the PDF/UA and PDF/A switches exposed. What the engine is, and where it is going.
Not writing the HTML yourself? The visual editor lays documents out on a page, imports an existing PDF and gives it back editable — and renders with this same engine. Open the editor.