跳到內容
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 一致性。未重現任何規範文字。