稳定性: 实验性
复杂文字塑形支持
可选启用的预览。 复杂文字塑形默认关闭。当它关闭时,引擎会经由既有的码点到 cmap 路径渲染——与不带该特性的构建字节完全一致。只在你拥有 libharfbuzz 和一种具备塑形能力的字体时才开启它,并验证结果。
HTML 渲染器为藏文与蒙古文新增了一个可选启用的复杂文字塑形器。当塑形器开启时,一段被检测到的、在范围内的藏文或蒙古文文段会经由 libharfbuzz 塑形,并作为 Identity-H 字形码发出。该塑形器覆盖 TrueType 与 CFF/OTTO 字面中的水平藏文(含折行),以及自上而下(TTB)排布的竖排蒙古文。
composer require nextpdf/core:^3该塑形器随核心包一起分发。CssFeatureFlags::$complexTextShaping 这个可选开关是 @since 6.1.0。标志开启时,libharfbuzz 是一项运行时要求——塑形器经由 PHP 的 FFI 扩展调入 libharfbuzz。当标志关闭时,该库没有 libharfbuzz 依赖。
概念总览
标题为“概念总览”的章节复杂文字会按上下文重排、替换并重新定位字形。一个朴素的码点到字形映射会把它们渲染得明显错误。塑形器把一段在范围内的文段交给 libharfbuzz,由它应用字体的 OpenType 塑形表,引擎再把所得字形序列作为一个采用 Identity-H 编码的复合 Type 0 字体发出(ISO 32000-2 §9.7.4——所示字符串是两字节 CID)。
范围是刻意限定的。塑形器识别藏文与蒙古文文段并对其塑形;它不主张通用的复杂文字覆盖。水平藏文在 TrueType 与 CFF/OTTO 字面中被塑形,并带折行。蒙古文被竖排塑形,自上而下。
Fail-closed 边界——硬性且带类型
标题为“Fail-closed 边界——硬性且带类型”的章节塑形器绝不会把未塑形的、视觉上破损的字形作为回退发出。一段无法被忠实塑形的文段会改为抛出一个带类型的异常:
ComplexScriptShapingException——该文段无法被忠实塑形:字体缺少所需字形(会导致出现.notdef)、一个 CFF 字面被要求在竖排路径中塑形、文段包含一个链接,或一列蒙古文需要折行(一个超出范围的情形)。HarfBuzzUnavailableException——标志开启,但运行时无法经由 FFI 触达 libharfbuzz。
当标志关闭时,一段在范围内的文段会经由既有的码点到 cmap 路径渲染。这是一项有文档记录的限制,而非一项塑形主张:关闭路径不应用 OpenType 塑形,因此不保证上下文字形。不要把关闭路径的输出描述为“已塑形”。
诚实性边界——客观等价,而非美学认可
标题为“诚实性边界——客观等价,而非美学认可”的章节塑形保真度是针对 HarfBuzz 客观验证的:所发出的字形标识符、簇映射与字形位置,与 HarfBuzz 参考输出相匹配(字形、簇与位置等价)。一次母语者美学审阅——判断结果对流利读者读起来是否自然——是一项被跟踪的发布后续工作。NextPDF 在此 API 或这些文档中不作任何语言质量主张。客观等价被断言;美学质量不被断言。
API 接口
标题为“API 接口”的章节| 符号 | 位置 | 角色 |
|---|---|---|
CssFeatureFlags::$complexTextShaping | src/Html/CssFeatureFlags.php | 藏文/蒙古文塑形器的可选启用标志(默认 false)。 |
Config::withCssFeatureFlags(CssFeatureFlags $flags): self | src/Core/Config.php | 把标志集附加到一份文档配置上。 |
ComplexScriptShapingException | src/Font/Shaper/ComplexScriptShapingException.php | 当一段在范围内的文段无法被忠实塑形时抛出。 |
HarfBuzzUnavailableException | src/Font/Shaper/HarfBuzzUnavailableException.php | 当标志开启但 libharfbuzz 不可用时抛出。 |
代码范例——快速上手
标题为“代码范例——快速上手”的章节<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;use NextPDF\Html\Css\CssFeatureFlags;
$config = (new Config())->withCssFeatureFlags( new CssFeatureFlags(complexTextShaping: true),);
$doc = Document::createStandalone($config);$doc->addPage();$doc->writeHtml( '<div style="font-family: NotoSerifTibetan;">བོད་སྐད་</div>',);$doc->save(__DIR__ . '/tibetan.pdf');代码范例——正式环境
标题为“代码范例——正式环境”的章节注册一种具备塑形能力的字体,接入塑形器,并显式处理这两种带类型的失败模式。要么是一次忠实的渲染,要么是一个清晰的异常——绝不是一段被沉默破损的字形。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\DocumentFactory;use NextPDF\Exception\ComplexScriptShapingException;use NextPDF\Exception\HarfBuzzUnavailableException;use NextPDF\Graphics\ImageRegistry;use NextPDF\Html\Css\CssFeatureFlags;use NextPDF\Typography\FontRegistry;
$fontRegistry = new FontRegistry();$fontRegistry->register('/path/to/NotoSerifTibetan-Regular.ttf', alias: 'NotoSerifTibetan');
$config = (new Config())->withCssFeatureFlags( new CssFeatureFlags(complexTextShaping: true),);
$factory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));$doc = $factory->create($config);$doc->setLanguage('bo');$doc->addPage();
try { $doc->writeHtml('<div style="font-family: NotoSerifTibetan;">བོད་སྐད་</div>');} catch (HarfBuzzUnavailableException $e) { // The flag is on but libharfbuzz is not reachable. Install it, or turn the // flag off to fall back to the unshaped cmap path. throw $e;} catch (ComplexScriptShapingException $e) { // The run cannot be shaped faithfully (missing glyphs, link in run, // out-of-scope case). Fix the font or the content; do not ship broken glyphs. throw $e;}
$doc->save($out);边界情况与陷阱
标题为“边界情况与陷阱”的章节- 开启时 libharfbuzz 必需。 标志开启而 libharfbuzz 缺失时,引擎会抛出
HarfBuzzUnavailableException。它不会沉默降级。 - 关闭不等于“已塑形”。 标志关闭时,一段在范围内的文段会经由 cmap 路径渲染,不应用 OpenType 塑形。这是一项有文档记录的限制;不要把它称为已塑形输出。
- 范围是藏文与蒙古文。 其他复杂文字不在此切片范围内。
- 文段中的链接会 fail closed。 一段包含链接注释的文段会抛出
ComplexScriptShapingException,因为链接矩形无法跟随被塑形的重排。 - 不作语言质量主张。 与 HarfBuzz 的等价被断言;母语者美学质量是一项被跟踪的后续工作,且不被主张。
塑形会为每段在范围内的文段增加一次 libharfbuzz 调用,加上字形发出过程,在字形数上呈线性。该预算(wall_ms: 2000、peak_mb: 128)遵循 CJK/复杂文字配置文件,因为塑形字体很大,字体处理主导成本。
安全性注意事项
标题为“安全性注意事项”的章节启用塑形器会引入一次进入 libharfbuzz(一个原生库)的 FFI 调用。字体文件在抵达塑形器之前,仍然是由排版层既有校验处理的不受信任二进制输入。塑形器消费的是已注册、已验证的字面。把终端用户提供的字体的来源当作不受信任来对待,并从可信来源置备 libharfbuzz。
符合性
标题为“符合性”的章节| 主张 | 标准 | 条款 |
|---|---|---|
| 被塑形的文段作为复合 Type 0 字体中的 Identity-H 两字节 CID 发出。 | ISO 32000-2 | §9.7.4 |
| 塑形器应用字体的 OpenType 字形替换与定位。 | OpenType Specification | GSUB / GPOS |
| 簇的形成遵循藏文与蒙古文的文字属性。 | Unicode Standard Annex | Tibetan and Mongolian |
这是一个范围限定于藏文与蒙古文的预览实现,针对客观 HarfBuzz 等价进行了验证。它不作任何语言质量主张,也不为所产出文件断言任何端到端 PDF 符合性。未重制任何标准原文。