Typography, world scripts, vector graphics, mathematics, forms and annotations — gathered in one document to put a PDF engine through its paces.
A PDF reader is judged in the first second. The page appears, and either the letters sit on it the way the author intended or they do not. Every kerning pair, every ligature and every soft gradient is a small promise the file makes and the renderer must keep.
This document collects those promises in one place. It was written for the people who build PdfCraft, as a single file to open after every change: if all of it still looks right, the change is probably safe. It is also, we hope, pleasant to read on its own.
Nothing here is exotic. Each feature is something ordinary documents use every day — an invoice with a form field, a thesis full of equations, a contract with comments in the margin, a brochure with a translucent photograph laid over a tinted panel. What is unusual is only that they are all together, and that each page says plainly what it is testing.
The layout is authored in HTML and printed by a browser; the interactive parts are then written into the file by hand, object by object. That split mirrors the real world, where most PDFs are produced by one program and amended by several others.
Two justified columns with automatic hyphenation, old-style figures, a drop cap and a pull quote — the everyday machinery of a well-made page.
Long before there were screens, a page of type was a negotiation between the width of a column and the length of the words that had to fill it. The compositor adjusted spaces, divided a word at a sensible syllable, and occasionally rewrote a line so the paragraph would lie flat. Justified text asks for exactly that care, and a renderer must honour the spacing it was given.1
A PDF does not reflow. Every glyph has already been placed by the program that wrote the file, and the reader’s job is to reproduce those positions faithfully at any zoom. That sounds simple until one remembers that a single line may mix three fonts, a ligature standing in for two letters, and a hyphen that exists only because the line happened to break there in 1994 or 2026.
Old-style figures, like the ones in this paragraph’s 1,280 characters and 36 lines, rise and fall with the lowercase so that numbers do not shout. Ligatures such as fi, fl and ffi in words like officially, affluent and afflicted join letters that would otherwise collide.2
Hyphenation is where browsers and word processors differ most. Chrome consults the system’s hyphenation dictionaries when a paragraph declares its language and asks for automatic hyphens, which is why the words in these columns occasionally divide across lines. The result is a more even texture, with fewer rivers of white running down the column.
Columns introduce their own questions: where to break, whether a heading may sit at the foot of one, and how a quotation spanning both should interrupt the flow. Here the pull quote spans the full measure and the text resumes beneath it, balanced between the two columns.
Small text matters too. Notes, captions and legal lines are often set at seven or eight points, where hinting, stem darkening and subpixel positioning decide whether a reader squints. The footnotes below are set at seven and a half points in the same face as the body.3
Finally, notice the drop cap that opens this chapter. It is an ordinary letter, floated and enlarged, with the first line set in small capitals. A renderer need do nothing special for it, which is precisely the point: most typographic richness in a PDF is just careful placement of ordinary glyphs.
1 Word spacing in PDF is usually baked into glyph positions rather than expressed with the word-spacing operator, so readers rarely need to stretch anything themselves.
2 In a PDF a ligature is a single glyph; text extraction relies on the font’s ToUnicode map to recover the letters it represents.
3 Try zooming to 400 percent here: well-rendered small text stays crisp and evenly weighted.
Each row shows the same text with a feature off, then on. The glyphs differ; the underlying characters do not.
| Tag | Feature | Off | On |
|---|---|---|---|
| liga | Standard ligatures | office fluffy fjord | office fluffy fjord |
| dlig | Discretionary ligatures | Asterisk & strict | Asterisk & strict |
| smcp | Small capitals | Printed in Boston | Printed in Boston |
| onum | Old-style figures | Since 1885: 3,467,920 | Since 1885: 3,467,920 |
| frac | Fractions | 1/2 cup, 3/4 inch, 7/8 | 1/2 cup, 3/4 inch, 7/8 |
| swsh | Swash capitals | The Quiet River | The Quiet River |
| ss01 | Stylistic set 1 | a 1 4 6 9 G ? | a 1 4 6 9 G ? |
| kern | Kerning | AVATAR Type Wave | AVATAR Type Wave |
| tnum | Tabular figures | 1111 / 8888 | 1111 / 8888 |
System UI · a single variable font file supplies every weight; the PDF embeds each instance as its own subset.
Effects that become transparency groups, soft masks, clipping paths and transformed text objects once they reach PDF.
SVG textPath · each glyph is positioned and rotated individually along a cubic Bézier, filled with a gradient.
A short greeting — roughly, “every letter deserves a good home” — in writing systems that need bidirectional layout, contextual shaping, reordering and vertical setting.
The word كتاب means “book”, and ספר does too — the bidi algorithm keeps each run in its own direction while the sentence stays left-to-right, even across numbers like ٣٤٥ and 345.
Noto Color Emoji (OFL) · colour bitmap glyphs that Chrome places into the PDF as images.
Equations written in MathML Core and laid out by the browser: stretchy delimiters, radicals, large operators, scripts and matrices.
A PDF page maps user space to device space with a matrix , so a point lands at . With one point equal to inch, a Letter page measures points, and a 300 dpi raster of it holds roughly pixels.
Nine small plates, each exercising one piece of the PDF imaging model.
Layered waves · five-stop shading, 50% overlay in multiply mode, dashed stroke over the top.
Charts drawn as SVG and a striped table. All figures are illustrative sample data, not measurements.
Pages per second, by document type
Illustrative sample data · higher is better
Renderer conformance over releases
Illustrative sample data · % of test pages matching reference
| Feature | PDF object | Produced by | Page | Status |
|---|---|---|---|---|
| Embedded font subsets | /FontFile2, /FontFile3 | Chrome | all | Present |
| Tagged structure | /StructTreeRoot | Chrome | all | Present |
| Axial & radial shadings | /ShadingType 2, 3 | Chrome | 6 | Present |
| Blend modes | /ExtGState /BM | Chrome | 6 | Present |
| Bookmarks | /Outlines | Chrome, xtask | — | Present |
| Page labels | /PageLabels | xtask | — | Present |
| Optional content | /OCProperties | xtask | 9, 10 | Two layers |
| Annotations | /Annots with /AP | xtask | 1, 9, 10 | Present |
| Form fields | /AcroForm | xtask | 10 | Present |
| File attachments | /EmbeddedFiles | xtask | — | Present |
| Digital signature | /FT /Sig | xtask | 10 | Unsigned |
A monospaced listing with syntax colouring, and the raster that it describes.
1// Escape-time rendering of Seahorse Valley into an RGB buffer. 2fn mandelbrot(width: u32, height: u32) -> Vec<u8> { 3 let mut rgb = Vec::with_capacity((width * height * 3) as usize); 4 for py in 0..height { 5 for px in 0..width { 6 let c = (CX + SPAN * (px as f64 / width as f64 - 0.5), 7 CY - SPAN * (py as f64 / height as f64 - 0.5)); 8 let (mut z, mut n) = ((0.0, 0.0), 0); 9 while n < MAX_ITER && z.0 * z.0 + z.1 * z.1 <= 4.0 { 10 z = (z.0 * z.0 - z.1 * z.1 + c.0, 2.0 * z.0 * z.1 + c.1); 11 n += 1; 12 } 13 rgb.extend_from_slice(&palette(n)); // smooth colour ramp 14 } 15 } 16 rgb 17}
The image at left is computed by the xtask each time the showcase is built, encoded as PNG and handed to Chrome, which embeds it as an image XObject. Nothing is downloaded and no third-party artwork is involved, so the file stays reproducible and free to redistribute.
At 60 dpi the fractal edge looks smooth; zoom in and the individual pixels appear, a useful check that the viewer switches from filtered to nearest-neighbour sampling at the right moment.
Every annotation on this page was added after printing, each with its own appearance stream, author, date and unique name.
Reviewers rarely rewrite a document; they highlight the phrase that matters, underline a claim that needs a source, and strike out a redundant word before moving on.
A wavy line says check the spelling here, while a caret marks where text should be inserted.
Sticky notes carry threaded replies, and a free-text box writes directly on the page. The paperclip holds an attached file that can be saved from the comment itself.