Japanese PDFs and PDF-compatible .ai files often set text in CID fonts
with no ToUnicode map, in vertical columns, and in fonts the reader
doesn't have. They came in as outlines (or as the wrong characters).
- CID fonts without ToUnicode: the character comes from the font's CFF
charset through the standard CMaps (hayro's `embed-cmaps`); Kangxi
radicals that some generators map to are unified with their ideographs
(⿓ → 龍).
- A glyph becomes live type only when the installed font draws the same
glyph: compared by box with the font of the PDF's PostScript name, or
the closest style of its family (a variable font's named instances),
whose style the type then takes. Otherwise it keeps its outline.
- Vertical columns (WMode 1, glyphs with no horizontal advance) come back
as vertical type, letter spacing as tracking; a single upright glyph is
vertical type too. Horizontal lines get tracking from the glyph
positions the same way.
- Text in a font that isn't installed keeps its outlines (what prints),
with an editable copy in a substitute font, drawn pink, on a
non-printing layer named after the missing fonts (stroke-only glyphs
included).
- Marked content other than a layer's (spans with actual text,
artifacts) no longer ends a line of type: 篳篥・龍笛・笙 came back as
three objects when one character was in a span.
- Tests in tests_live_text.rs and tests_realtext.rs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The font database made one style per font file, so a variable font
such as Figtree[wght].ttf listed only its default instance (Light).
Faces now also yield their fvar named instances, each a style of the
family named by its subfamily name (the default instance is the face
itself; unnamed or duplicate instances are left out; axes and
instances read are capped). The system font scan reads the fvar table
beside the name table, so installed instances are listed before the
file is loaded and found by name and by PostScript name.
An instance face carries its axis settings: skrifa draws its outlines
and reads its metrics and advances at that location, harfrust shapes
with a ShaperInstance, so layout, the canvas, Create Outlines and hit
testing all use the instance. PDF export embeds it through krilla's
Font::new_variable, SVG @font-face through subsetter's
subset_with_variations: both write a static font of that instance.
Tests build a small variable font in code (test_fonts, via
write-fonts; no font file is committed) and check listing, resolving,
glyphs and advances, PDF and SVG export and damaged fvar/gvar tables;
Bahnschrift and Segoe UI Variable are checked where installed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With Convert Text to Outlines off (advanced.outlineText: false), type is
written as selectable, searchable text: each glyph in its font, embedded
as a subset with a ToUnicode map, where its outline would be (rotated,
scaled, skewed and on-path type too; gradients keep their place). Fonts
whose licence forbids embedding, or allows only whole fonts, fall back to
outlines with a warning; a subset threshold below 100% is accepted with a
warning. Laid-out glyphs now carry their glyph id and transform.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>