From 40caa4e66c97219b4e9902c9e7dcfd2ae3629a93 Mon Sep 17 00:00:00 2001 From: hhh2210 Date: Tue, 30 Jun 2026 19:46:12 +0800 Subject: [PATCH 1/2] pdf_io: generate ToUnicode CMap for fonts exposing only a (0,4) cmap subtable `otf_create_ToUnicode_stream()` probes a fixed list of cmap (platform, encoding) pairs when building a ToUnicode CMap for a TrueType/OpenType-backed CID font. The list was missing (platform 0 = Unicode, encoding 4 = Unicode 2.0+, full repertoire), so fonts whose *only* cmap subtable is (0,4) got no ToUnicode CMap at all. Text set in such fonts then renders correctly but is not extractable / searchable / copy-pasteable from the resulting PDF. This affects real-world fonts: several macOS system CJK fonts ship a single (0,4) format-12 subtable, e.g. STHeiti and STXihei. A Chinese thesis compiled with tectonic produced a PDF whose bold/heading text (set in STHeiti) could not be extracted, which breaks copy-paste and plagiarism-check workflows. Upstream dvipdfm-x already carries the { 0, 4 } entry in this table; this change brings tectonic's vendored copy in line with it. Verified on a real Chinese thesis: extractable CJK characters went from 23957 to 26918, exactly matching the xelatex (TeX Live 2026) output, and the STHeiti/STXihei font objects now carry /ToUnicode. --- crates/pdf_io/pdf_io/dpx-tt_cmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/pdf_io/pdf_io/dpx-tt_cmap.c b/crates/pdf_io/pdf_io/dpx-tt_cmap.c index e85599a3e..1a5330697 100644 --- a/crates/pdf_io/pdf_io/dpx-tt_cmap.c +++ b/crates/pdf_io/pdf_io/dpx-tt_cmap.c @@ -1047,6 +1047,7 @@ typedef struct { static cmap_plat_enc_rec cmap_plat_encs[] = { { 3, 10 }, { 0, 3 }, + { 0, 4 }, { 0, 0 }, { 3, 1 }, { 0, 1 } From ff0d87d327b03028f7d298beefe06a091feebd3f Mon Sep 17 00:00:00 2001 From: hhh2210 Date: Tue, 30 Jun 2026 20:16:53 +0800 Subject: [PATCH 2/2] pdf_io: add (0,4) to cidtype2.c known_encodings (other half of macOS 0-4 cmap support) Companion to the previous commit. Upstream dvipdfm-x fixed "support some TrueType fonts in macOS which use 0-4 cmap" (texjporg, 2022-06-15, Clerk Ma) by touching *two* files: tt_cmap.c (ToUnicode probe list) and cidtype2.c (the CID-keyed embedding cmap probe list, `known_encodings[]`). tectonic's vendored copy was missing both halves. This adds the matching { 0, 4 } entry to `known_encodings[]` and bumps KNOWN_ENCODINGS_MAX 9 -> 10, so the CID-keyed CIDFontType2 embedding path (used outside the XeTeX glyph-by-GID route, e.g. CID-keyed fontmap usage) can also find the cmap of macOS fonts whose only subtable is (platform 0, encoding 4). index 10 > WIN_UCS_INDEX_MAX (1), so it is handled exactly like the upstream change (non-Windows-UCS, via find_tocode_cmap with the UCS names). Verbatim match of upstream. --- crates/pdf_io/pdf_io/dpx-cidtype2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/pdf_io/pdf_io/dpx-cidtype2.c b/crates/pdf_io/pdf_io/dpx-cidtype2.c index 5f1ec842b..76bb24fd0 100644 --- a/crates/pdf_io/pdf_io/dpx-cidtype2.c +++ b/crates/pdf_io/pdf_io/dpx-cidtype2.c @@ -147,7 +147,7 @@ validate_name (char *fontname, int len) */ #define WIN_UCS_INDEX_MAX 1 -#define KNOWN_ENCODINGS_MAX 9 +#define KNOWN_ENCODINGS_MAX 10 static struct { unsigned short platform; @@ -164,6 +164,7 @@ static struct {TT_MAC, TT_MAC_TRADITIONAL_CHINESE, {"B5pc", NULL}}, {TT_MAC, TT_MAC_SIMPLIFIED_CHINESE, {"GBpc-EUC", NULL}}, {TT_MAC, TT_MAC_KOREAN, {"KSCpc-EUC", NULL}}, + {0, 4, {"UCSms-UCS4", "UCSms-UCS2", "UCS4", "UCS2", NULL}}, {0, 0, {NULL}} };