examples: add multiple_fonts POC — single CJK OTC, per-language glyph variants, subsetting - #283
Open
kyasu1 wants to merge 2 commits into
Open
examples: add multiple_fonts POC — single CJK OTC, per-language glyph variants, subsetting#283kyasu1 wants to merge 2 commits into
kyasu1 wants to merge 2 commits into
Conversation
Demonstrates rendering multiple faces pulled from a single OTC (Source Han Serif) on one page, per-language Han-unified glyph variants (U+66DC), and subset_fonts size reduction. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
Author
Face order in the OTC's name table is JA/KR/SC/TC, not JA/KR/TC/SC — verified per-face via fontTools. The texts array had TC and SC swapped relative to font_groups, so each ran with the other's font. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Owner
|
Hmm yeah, I'll see if there's anything I could use for the GUI use case. Interesting, I didn't realize it was this mature already. |
Owner
|
I would just download the font file on-the-fly in the example from a URL. I mean, it's an example, doesn't affect the main codebase |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
This adds a new example,
examples/multiple_fonts.rs, as a proof of conceptfor three things printpdf can do with CJK text that are easy to get wrong:
Rendering multiple faces from one OTC on the same page. Source Han Serif
ships as a "Super OTC" — a single OpenType Collection (
SourceHanSerif.ttc,~155 MiB) containing all 4 CJK regions (JA/KR/TC/SC) across 7 weights each
(28 faces total, per the
ttcfheader). The example loads each face itneeds by index via
ParsedFont::from_bytes(bytes, font_index, ..),registers them all with
doc.add_font, and switches between them withOp::SetFontwhile laying out a single page — demonstrating how printpdflets a document mix several faces pulled out of one collection, rather
than requiring one font file per face/language.
Han-unified glyphs render per language, not per codepoint. U+66DC (曜)
is a textbook case of Han unification: the same Unicode codepoint is drawn
with subtly different strokes in Japanese, Korean, Traditional Chinese, and
Simplified Chinese fonts. The example demonstrates the low-level mechanism
printpdf exposes to get the correct regional glyph today: load the
language-specific face from the collection (via
font_index) and switchOp::SetFontper run.Font subsetting keeps output size proportional to used glyphs, not to
the source font. With
PdfSaveOptions::subset_fonts = true, theresulting PDF is ~1.81 MiB against a ~155.1 MiB source font collection —
about 85x smaller (~1.2% of the original), even though the document draws
from 28 different sub-faces across 4 scripts.
Non-goals
printpdf only exposes the primitive: given a
font_index, load that faceand let the caller switch fonts per text run. It does not — and should
not — decide which face to use for a given language or script. That
decision (detecting the run's language/script and picking the matching face
out of a collection, resolving Unicode variation sequences, etc.) belongs in
a higher-level text-shaping/layout library, e.g.
azul-layout, sitting aboveprintpdf. This example exists to prove the low-level primitive works, not to
propose printpdf grow automatic language-aware font selection.
Changes
examples/multiple_fonts.rs(new): builds the demo document describedabove and writes
multiple_fonts.pdf.Cargo.toml: register themultiple_fontsexample target.A note for @fschutt
This is a POC, so whether/how to merge it is entirely your call.
The one thing worth deciding up front:
SourceHanSerif.ttc(~155 MiB) isnot included in this PR — it's over GitHub's 100 MB per-file push limit,
so it can't be added as a normal blob. Right now that means
examples/multiple_fonts.rswon't compile out of the box (theinclude_bytes!target doesn't exist) unless the file is placed locallyfirst, downloaded from source.typekit.com/source-han-serif.
Options, roughly in order of effort:
.ttc/.otf(loses the "one file, all4 languages × 7 weights" part of the demo)
default
cargo build --examples/CI matrix, documenting how to fetch thefont to run it locally
Happy to implement whichever direction you'd prefer, or drop the example if
it's not worth the tradeoff.
Test plan
cargo run --example multiple_fontssucceeds and writesmultiple_fonts.pdffont name/weight label and body text
are visibly distinct across JA/KR/TC/SC
(subsetting working as expected)