PDF reference

How PDF fonts work

Nearly every frustrating thing a PDF does with text — a font that changes on edit, characters that copy out as nonsense, a document that looks different on someone else’s screen — comes back to how PDF handles fonts. It is a genuinely unusual design, and it is unusual for a reason.

Free — no signupNo watermarkNothing to installYour layout preserved

The short answer

A PDF font is an object on the page that carries a font program, an encoding that maps byte codes to glyphs, and a width table for positioning. Fonts may be embedded in full, embedded as a subset of the characters used, or merely named — which is why the same PDF can render differently on different machines.

Glyphs are drawn by index, not by letterEncoding maps codes to glyphsToUnicode maps glyphs back to textEmbedded, subset, or named-onlyWidths are stored per glyph

What is actually inside a PDF font

A PDF does not store your page as words in a typeface. It stores an instruction to draw glyph number 47 from font object /F3 at a fixed coordinate, and a separate table that maps those glyph numbers back to characters. Text and its meaning are two different things in the file, held together by a mapping that can be missing, wrong, or partial. Once that is clear, every font symptom stops being mysterious.

The parts of a font object

The font program

The actual outlines, in one of a few formats: Type 1 (the original PostScript format, now rare), TrueType, or CFF/Type 1C inside an OpenType wrapper. This is the part that gets embedded — or does not.

The encoding

A table mapping the byte codes in the content stream to glyphs in the font program. Simple fonts use one byte per character with an encoding like WinAnsi; composite (Type 0 / CID) fonts use multi-byte codes and a CMap, which is how a PDF carries thousands of glyphs.

ToUnicode

A second, optional map that goes the other way: glyph back to the character it represents. It is what makes text copyable and searchable. Nothing renders differently when it is missing or wrong — the page looks perfect and the text copies out as gibberish.

The width table

Each glyph’s advance width, in thousandths of the text size. The viewer uses these to know where the next glyph goes. It is why a substituted font with different widths visibly changes spacing even when the letterforms look similar.

The font descriptor

Metadata about the face — weight, italic angle, whether it is serif, its bounding box, its flags. When a font is not embedded, this is all a viewer has to choose a substitute from.

Type 3 fonts

The odd one out: a font whose glyphs are small content streams rather than outlines. Some generators produce them, and they behave differently enough that most tools treat them as a special case.

How to inspect the fonts in your own file

1

List the fonts in the file

Run your PDF through the free PDF Font Checker. It reports each font by name along with its type, its encoding, and whether a ToUnicode map is present.

2

Check the embedding status

The PDF Font Embed Checker separates the three states that matter: fully embedded, subset-embedded (the name will carry a six-letter tag and a plus sign, like ABCDEF+Helvetica), and referenced by name only.

3

Test the ToUnicode map

Open the PDF and copy a line of text into a plain text field. If what you paste does not match what you see on screen, the ToUnicode map is missing or wrong — a rendering-perfect file with unusable text.

4

Compare against another machine

A font that is only referenced will be substituted by whatever the reader picks. Opening the same file on a second device is the fastest way to find out whether your document depends on fonts it does not carry.

Embedded, subset, or referenced

The three states a font can be in inside a PDF, and what each one costs you.

 What the file carriesWhat can go wrong
Fully embeddedThe complete font programNothing — but the file is larger
Subset-embeddedOnly the glyphs the document usesNew characters have no glyph to draw
Referenced by nameA name and a descriptorThe reader substitutes; layout can shift
Standard 14A name only, by specificationRenderers supply metric-compatible faces
Type 3Glyphs as content streamsHandled as a special case by most tools

The "standard 14" — Helvetica, Times, Courier, Symbol and ZapfDingbats in their variants — are the historical exception: PDF assumed every viewer would have metric-compatible equivalents, so they were never required to be embedded.

Where the model breaks down

A glyph index is not a character

The number in the content stream identifies a shape in a font program, nothing more. Two files can draw the identical word with entirely different numbers. This is why text extraction depends on ToUnicode and not on reading the drawing instructions.

Private-use codes are common

Some producers map glyphs into the Unicode private-use area, often at an F000 offset. Text drawn that way renders correctly and copies out as unassigned codepoints, which is one of the most common causes of a PDF whose text looks fine and extracts as junk.

A subset cannot be extended

You cannot add a glyph to an embedded subset that never contained it. Anything needing a character outside the subset has to bring a new font program into the file.

What this means in practice

Embed everything you will ever send outside

Full embedding costs kilobytes and removes an entire category of "it looked different on their screen" problems. It is the single highest-value setting in any PDF export dialog.

Judge a PDF’s text by copying it, not by reading it

Rendering proves the glyphs and their positions are right. Only copying proves the ToUnicode map is right, and only the second one matters for search, accessibility and extraction.

Expect the subset tag on almost everything

ABCDEF+FontName is the norm, not a warning sign. It only becomes relevant when you need a character the document never used.

Widths matter more than shapes

A substitute with correct letterforms and wrong widths looks worse than the reverse, because every subsequent glyph on the line lands in the wrong place.

Frequently asked questions

  • As drawing instructions, not as words. The content stream says which font object to use, what size, where on the page, and then which glyph codes to draw. The meaning of those codes lives in the font’s encoding, and their mapping back to real characters lives in an optional ToUnicode table. That separation is why a PDF can render a page perfectly and still be unable to tell you what it says.

  • The file carries the font program itself — the actual glyph outlines — so any viewer draws the page with exactly the typeface the author used. A non-embedded font is only named, leaving the viewer to find something similar on the local system, which is where cross-machine differences come from.

  • Subsetting embeds only the glyphs the document actually uses. A typeface may carry thousands of glyphs while a three-page invoice uses eighty, so embedding the whole face wastes most of the file. It is the right default, and it is invisible until you try to add a character the document never contained.

  • Encoding runs forwards: it turns the byte codes in the content stream into glyphs so the page can be drawn. ToUnicode runs backwards: it turns those glyphs into characters so the text can be copied, searched or read aloud. A PDF needs the first to look right and the second to be usable.

  • A Type 0, or composite, font uses multi-byte codes and a CMap to address a large glyph set — necessary for Chinese, Japanese, Korean and any document with more than 256 distinct glyphs from one face. The descendant CIDFont holds the actual program and widths. Simple fonts, by contrast, are limited to single-byte codes.

  • Helvetica, Times, Courier (each in regular, bold, italic and bold-italic), Symbol and ZapfDingbats. The PDF specification assumed every viewer would have metric-compatible equivalents, so these were allowed to be referenced rather than embedded. Modern practice is to embed anyway, because "metric-compatible" is a weaker guarantee than "identical".

  • Because the ToUnicode map is missing, incomplete or wrong — often with glyphs mapped into the Unicode private-use area. The page renders correctly because rendering only needs the encoding and the outlines. Copying needs the reverse map, and nothing on screen tells you it is broken until you paste.

  • Yes, more than the letterforms do. The width table tells the viewer how far to advance after each glyph. Substituting a face with different widths shifts every character after the first, so lines end in the wrong place, spacing looks uneven and text can run into the next column.