|
automatic shaping pipeline 将 OpenType GSUB engine 从 capability-only 查询表面提升为 producer-side 功能,在文本输出到 PDF content streams 时自动应用。调用方通过 typed set(ShapingFeatures: THPDFShapingFeatures)启用特定 GSUB features,HotPDF 负责运行正确替换、将 substitute glyphs 标记进嵌入字体子集,并输出 accessibility 所需的 ToUnicode CMap reverse-mapping entries
Opt-in framework (v2.119.59 / Phase 8a)
新增的枚举和属性控制文本输出期间运行哪些自动替换:
type
THPDFShapingFeature = (
sfArabicGSUB, // font-defined 'rlig' (Required Ligatures) for Arabic
sfStandardLigatures, // Latin 'liga' (ff / fi / fl / ffi / ffl / sft / st)
sfContextualLigatures,// Latin 'clig' (contextual ligatures)
sfContextualAlternates,// 'rclt' (Required Contextual Alternates)
sfIndicShaping); // Devanagari Repha + pre-base I-matra reorder
THPDFShapingFeatures = set of THPDFShapingFeature;
property ShapingFeatures: THPDFShapingFeatures read ... write ...;
默认值为 [](空集合),为依赖 v2.119.32-58 static post-pass shaper 的调用方保持逐字节相同输出。设置一个或多个标志会让 engine 对对应 feature 进入 automatic mode
sfArabicGSUB - Phase 8c.2 (v2.119.63)
设置 sfArabicGSUB 时,HotPDF 把逻辑 Arabic run 映射为基础 glyph ID,在每个字母选定的连接位置应用注册字体的 positional init、medi、fina、isol lookup,然后对塑形后的 run 应用 rlig、calt 和 rclt。没有 Unicode codepoint 的 substitute glyphs 经 synthetic-codepoint 路径输出并带 ToUnicode 反向映射,因此上下文 Arabic glyph 不在 cmap 中的字体仍能正确嵌入和复制
设置 sfArabicGSUB 会隐式绕过 Arabic 的 v2.85.0 static 4-position shaper;如果调用方需要静态 shaper 继续处理字体 GSUB 未声明的 codepoints,应保持 sfArabicGSUB 关闭
sfStandardLigatures / sfContextualLigatures - Phase 8b (v2.119.65)
设置 sfStandardLigatures 时,会使用字体的 liga feature 自动折叠 Latin Standard Ligatures。ApplyLatinLigatureRefinement 面向 Alphabetic Presentation Forms block(U+FB00-FB4F),通常是 FB00 ff、FB01 fi、FB02 fl、FB03 ffi、FB04 ffl、FB05 long-s + t、FB06 st。sfContextualLigatures 为字体 clig feature 添加第二个 pass。两个 pass 使用与 sfArabicGSUB 相同的 reverse-cmap 机制,并输出 7 个新的 ToUnicode CMap reverse-mapping entries(FB00-FB06),使消费端阅读器复制 / 粘贴时可将 ligature 解析回源字母
sfContextualAlternates - GSUB 'rclt' (v2.119.66)
设置 sfContextualAlternates 时,会应用字体的 rclt(Required Contextual Alternates)feature。ApplyArabicGSUBContextualRefinement 使用 v2.119.47 ApplyContextualSubst 入口,并处理可变长度 N-to-M 输出;只有每个 replacement GID 都能通过 reverse cmap 到达时才提交替换。Reverse cmap 范围扩展到 FB00-FDFF + FE70-FEFF,以覆盖 Latin + Arabic + Hebrew Presentation Forms
rclt 的典型使用者:字体经 GSUB 而非 Unicode Presentation Forms 码点驱动位置塑形时的阿拉伯文 init / medi / fina / isol;某些拉丁文序列消歧规则;以及字体设计者注册为 rclt 的 Indic 塑形 feature(pres / blws / psts / half / pstf / cjct)
sfIndicShaping - Phase 8e (v2.119.67)
设置 sfIndicShaping 时,v2.119.55 Devanagari capability ApplyDevanagariReorder 会从手动方法提升为三个 BuildUnicode*FieldContent 辅助函数内部自动应用的 pre-pass。Devanagari runs 会将 Repha(cluster 开头的 Ra + Halant)移到 post-base 位置,并将 pre-base I-matra(U+093F)移到 cluster base consonant 之前,使消费端阅读器的 GSUB engine 按正确渲染顺序获取 syllable。其他 Indic reorders(above-base / below-base matra、conjunct formation)仍由字体 GSUB 处理
Advance-query support (v2.119.64 / Phase 8c.5)
配套 API 暴露缓存的 /W em-fraction,使调用方在输出 GSUB-substituted glyphs 时能正确计算 word-wrap:
function GetCodepointAdvance(CP: Cardinal): Single;
返回 CP 对应 cmap-resolved glyph 的 hmtx-derived advance width,并以 em 分数表示。同一版本还修复了 CodeUnitAdvance,使 Arabic Presentation Forms(U+FB50-FDFF + U+FE70-FEFF)分类为 NARROW 而非 WIDE;v2.65 前 heuristic fallback 对此分类错误
典型工作流 (full Arabic auto-shaping)
PDF.RegisterUnicodeTTF('NotoArab', 'NotoSansArabic-Regular.ttf');
PDF.ShapingFeatures :=
[sfArabicGSUB, // font-defined 'rlig'
sfContextualAlternates]; // 'rclt' (positional shaping in GSUB-driven fonts)
PDF.SetGSUBScript('arab');
PDF.BeginDoc;
PDF.CurrentPage.SetFont('NotoArab', [], 14);
PDF.CurrentPage.RtLTextOut(100, 700, 0,
UnicodeString(#$0628#$0633#$0645#$0020#$0627#$0644#$0644#$0647));
PDF.EndDoc;
典型工作流 (Latin standard ligatures + Devanagari reorder)
PDF.RegisterUnicodeTTF('NotoSans', 'NotoSans-Regular.ttf');
PDF.RegisterUnicodeTTF('NotoDeva', 'NotoSansDevanagari-Regular.ttf');
PDF.ShapingFeatures :=
[sfStandardLigatures, // FB00-FB06 Latin liga
sfContextualLigatures, // + clig
sfIndicShaping]; // Devanagari Repha + I-matra reorder
Phase 8 roadmap closure
Phase 8a(v2.119.59)opt-in 框架 + Arabic 能力;Phase 8b(v2.119.65)Latin 标准连字;Phase 8c.1(v2.119.60)Allah;Phase 8c.2(v2.119.63)GID 级 GSUBrlig;Phase 8c.3(v2.119.61)ToUnicode 反向映射;Phase 8c.4(v2.119.62)Bismillah;Phase 8c.5(v2.119.64)advance 查询 + heuristic 修复;Phase 8c.6(v2.119.68)PUA 合成码点输出;Phase 8d 已并入 8c 子阶段;Phase 8e(v2.119.67)Devanagari 自动重排。v2.119.68 起,Phase 8 能力矩阵已闭合;后续细化(更多 Indic 脚本、OpenType GPOS 定位、BiDi 解析)在独立路线图条目中跟踪
Scope and limitations
该 opt-in pipeline 有意在 static post-pass shaper 之上增量工作;现有调用方除非 opt in,否则行为不变。默认 [] 集合是字节稳定回归的安全选择。没有所请求 GSUB feature tables 的字体会产生安全 no-op 输出,不会应用替换,也不会抛出异常
当前塑形 API 映射
当前管线已经不是仅替换路径:sfKerning 会应用 GPOS 成对字距,sfMarkPositioning会应用 Mark-to-Base 和 Mark-to-Mark 偏移,sfMarkToLigature 应用 Mark-to-Ligature 放置,sfCursiveAttachment 应用 cursive 进出锚点对齐,sfTibetanShaping 会应用 Tibetan GSUB 塑形,sfMongolianShaping 会应用 Mongolian 位置形式,sfIndicGSUB 会在音节重排后应用 Indic GSUB 特性链。参见 ShapingFeatures、GPOS methods 和 Indic shaping methods
近期新增 sfLocalizedForms、经 ApplyGSUBContextualFeature 的 calt经 ApplyGSUBContextualFeature 的上下文替换、上下文与纵向 GPOS 字距、原生 Arabic GSUB 上下文 glyph 输出,以及 N'Ko、Adlam、Thai/Lao、Hebrew 和 Javanese 路径。参见 script shaping preprocess methods
另请参阅: OpenType GSUB Substitution Engine, Arabic / Persian / Urdu 塑形支持, Syriac / Mongolian / Devanagari Shaping, THotPDF.AssignSyntheticCodepointForGID, CFF / OpenType Font Subsetting
|