跳转到内容
getnextpdf.com

稳定性: 实验性

复杂文字塑形支持

可选启用的预览。 复杂文字塑形默认关闭。当它关闭时,引擎会经由既有的码点到 cmap 路径渲染——与不带该特性的构建字节完全一致。只在你拥有 libharfbuzz 和一种具备塑形能力的字体时才开启它,并验证结果。

HTML 渲染器为藏文与蒙古文新增了一个可选启用的复杂文字塑形器。当塑形器开启时,一段被检测到的、在范围内的藏文或蒙古文文段会经由 libharfbuzz 塑形,并作为 Identity-H 字形码发出。该塑形器覆盖 TrueType 与 CFF/OTTO 字面中的水平藏文(含折行),以及自上而下(TTB)排布的竖排蒙古文。

Terminal window
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 字面中被塑形,并带折行。蒙古文被竖排塑形,自上而下。

塑形器绝不会把未塑形的、视觉上破损的字形作为回退发出。一段无法被忠实塑形的文段会改为抛出一个带类型的异常:

  • ComplexScriptShapingException——该文段无法被忠实塑形:字体缺少所需字形(会导致出现 .notdef)、一个 CFF 字面被要求在竖排路径中塑形、文段包含一个链接,或一列蒙古文需要折行(一个超出范围的情形)。
  • HarfBuzzUnavailableException——标志开启,但运行时无法经由 FFI 触达 libharfbuzz。

当标志关闭时,一段在范围内的文段会经由既有的码点到 cmap 路径渲染。这是一项有文档记录的限制,而非一项塑形主张:关闭路径不应用 OpenType 塑形,因此不保证上下文字形。不要把关闭路径的输出描述为“已塑形”。

诚实性边界——客观等价,而非美学认可

标题为“诚实性边界——客观等价,而非美学认可”的章节

塑形保真度是针对 HarfBuzz 客观验证的:所发出的字形标识符、簇映射与字形位置,与 HarfBuzz 参考输出相匹配(字形、簇与位置等价)。一次母语者美学审阅——判断结果对流利读者读起来是否自然——是一项被跟踪的发布后续工作。NextPDF 在此 API 或这些文档中不作任何语言质量主张。客观等价被断言;美学质量不被断言。

符号位置角色
CssFeatureFlags::$complexTextShapingsrc/Html/CssFeatureFlags.php藏文/蒙古文塑形器的可选启用标志(默认 false)。
Config::withCssFeatureFlags(CssFeatureFlags $flags): selfsrc/Core/Config.php把标志集附加到一份文档配置上。
ComplexScriptShapingExceptionsrc/Font/Shaper/ComplexScriptShapingException.php当一段在范围内的文段无法被忠实塑形时抛出。
HarfBuzzUnavailableExceptionsrc/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: 2000peak_mb: 128)遵循 CJK/复杂文字配置文件,因为塑形字体很大,字体处理主导成本。

启用塑形器会引入一次进入 libharfbuzz(一个原生库)的 FFI 调用。字体文件在抵达塑形器之前,仍然是由排版层既有校验处理的不受信任二进制输入。塑形器消费的是已注册、已验证的字面。把终端用户提供的字体的来源当作不受信任来对待,并从可信来源置备 libharfbuzz。

主张标准条款
被塑形的文段作为复合 Type 0 字体中的 Identity-H 两字节 CID 发出。ISO 32000-2§9.7.4
塑形器应用字体的 OpenType 字形替换与定位。OpenType SpecificationGSUB / GPOS
簇的形成遵循藏文与蒙古文的文字属性。Unicode Standard AnnexTibetan and Mongolian

这是一个范围限定于藏文与蒙古文的预览实现,针对客观 HarfBuzz 等价进行了验证。它不作任何语言质量主张,也不为所产出文件断言任何端到端 PDF 符合性。未重制任何标准原文。