跳到內容
getnextpdf.com

穩定性: 實驗性

CJK 直書支援

可選擇啟用的預覽。 直書排版器預設為關閉。當它關閉時,引擎會完全如同以往一樣橫排算繪——位元組完全相同。只為那些需要真正直書行的文件將它開啟,並驗證結果。

HTML 算繪器為 CSS 書寫模式 writing-mode: vertical-lrwriting-mode: vertical-rl 加入了一個真正的直書行排版器。當排版器開啟時,字符會由上往下堆疊,逐字符的位置取自字型的真實垂直度量(vheavmtx 表),一如 ISO 32000-2 §9.7.5 中所述的 PDF 直書模型。兩種垂直區塊流動方向均受支援。

Terminal window
composer require nextpdf/core:^3

此排版器隨核心套件一起出貨。CssFeatureFlags::$layoutVerticalComposer 這項選擇性啟用為 @since 6.1.0。引擎版本維持不變;此功能是附加性的且預設為關閉。

直書排版只在 layoutVerticalLrlayoutVerticalComposer 兩者皆設定時才會開啟。在它們開啟的情況下,一段 vertical-lrvertical-rl 文字會排版為一條真正的直書行:每個字符依其取自字型 vhea/vmtx 度量的垂直前進量放置,且 UAX #50 標示為直立的字符會保持直立。vertical-lr 由左往右排列各欄;vertical-rl 由右往左排列各欄。

這有別於 以 cmap 感知編碼排版 CJK 文字 中所記載的 cmap 感知編碼門面,後者證明了編碼路徑,但其本身並不驅動一個直書書寫模式。本頁記載的是書寫模式選擇性啟用所啟用的、配置端的排版器。

Fail-closed 邊界——何時排版,以及它在其他情況下會做什麼

標題為「Fail-closed 邊界——何時排版,以及它在其他情況下會做什麼」的區段

此排版器在設計上是保守的。只有當一段文字中的每一個字符都是 UAX #50 直立、具有真實垂直度量,文字內沒有開啟的連結,且該段文字為單一欄時,它才會將該段文字直書排版。當其中任一條件不成立時——旗標關閉,或一段文字無法被忠實排版——引擎會退回橫排配置,並發出一個與模式相符的延後診斷:

  • 對一段無法排版的 vertical-lr 文字發出 HTML_WRITING_MODE_LR_DEFERRED
  • 對一段無法排版的 vertical-rl 文字發出 HTML_WRITING_MODE_RL_DEFERRED

每個診斷都帶有一個 reason,因此延後是可觀察且可解釋的,絕不會是把作者要求直排的文字默默橫排算繪。

以下情況不在目前切片的範圍內,並已追蹤以供後續處理:

  • 直書文字內被旋轉(非直立)的字符。
  • 多欄直書換行。
  • 直書連結矩形(直書文字內的一個連結會使該段文字延後)。
  • 測試語料庫中沒有隨附具垂直度量的 CJK 字型固定樣本,因此視覺交叉檢查是被追蹤的,而非由一個隨附的黃金樣本斷言。
符號位置角色
CssFeatureFlags::$layoutVerticalComposersrc/Html/CssFeatureFlags.php直書行排版器的選擇性啟用旗標(預設 false)。
CssFeatureFlags::$layoutVerticalLrsrc/Html/CssFeatureFlags.phpvertical-lr 的閘門;兩者都必須開啟才能排版。
Config::withCssFeatureFlags(CssFeatureFlags $flags): selfsrc/Core/Config.php將旗標集合附加到文件設定上。

延後診斷碼 HTML_WRITING_MODE_LR_DEFERREDHTML_WRITING_MODE_RL_DEFERRED 會透過算繪結果的諮詢通道浮現。

<?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(
layoutVerticalLr: true,
layoutVerticalComposer: true,
));
$doc = Document::createStandalone($config);
$doc->addPage();
$doc->writeHtml(
'<div style="writing-mode: vertical-rl; font-family: NotoSerifJP;">'
. '日本語の縦書き'
. '</div>',
);
$doc->save(__DIR__ . '/vertical.pdf');

一段無法被忠實排版的文字會橫排算繪,並加入一個帶有 reasonHTML_WRITING_MODE_RL_DEFERRED 諮詢。在把直書輸出當作最終結果之前,請檢查諮詢通道。

透過 DocumentFactory 註冊一個帶有真實垂直度量的字型,讓排版器能讀取 vhea/vmtx,然後讓文件選擇進入該排版器。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;
use NextPDF\Core\DocumentFactory;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Html\Css\CssFeatureFlags;
use NextPDF\Typography\FontRegistry;
$fontRegistry = new FontRegistry();
$fontRegistry->register('/path/to/NotoSerifJP-Regular.otf', alias: 'NotoSerifJP');
$config = (new Config())->withCssFeatureFlags(new CssFeatureFlags(
layoutVerticalLr: true,
layoutVerticalComposer: true,
));
$factory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));
$doc = $factory->create($config);
$doc->setLanguage('ja');
$doc->addPage();
$doc->writeHtml(
'<div style="writing-mode: vertical-rl; font-family: NotoSerifJP;">'
. '縦書きの本文。'
. '</div>',
);
$doc->save($out);
  • 兩個旗標都是必要的。 排版器需要 layoutVerticalLrlayoutVerticalComposer。任一個關閉時,該段文字都會橫排算繪。
  • 真實垂直度量是必要的。 一個沒有 vhea/vmtx 的字型無法驅動排版器;該段文字會延後為橫排配置。
  • 延後是可觀察的。 一段無法排版的文字會發出帶有 reasonHTML_WRITING_MODE_LR_DEFERRED / HTML_WRITING_MODE_RL_DEFERRED。它絕不會默默地橫向算繪。
  • 此路徑不主張任何一致性。 直書排版是一項配置能力;它並非對所產生檔案的 PDF/UA-2 或 PDF/A-4 一致性陳述。是否一致由檢查器決定。

排版會在該段文字上加入一次逐字符的垂直前進量查找,時間複雜度與字符數呈線性。預算(wall_ms: 2000peak_mb: 128)遵循 CJK 設定檔,因為具垂直度量的字型很大,且主要成本在於字型處理,而非排版這一遍。

排版器從已註冊、已驗證的字型讀取垂直度量。它不會開啟新的輸入通道。字型檔案仍是不受信任的二進位輸入,由排版層的既有驗證處理。已排版的文字是被算繪的,而不是被解譯的。

陳述規範條款
直書使用 CIDFont 的垂直字符度量進行放置。ISO 32000-2§9.7.5
writing-mode: vertical-lr / vertical-rl 設定區塊流動方向。W3C CSS Writing Modes Level 3§3
逐字符的直立方向遵循 Unicode 的 vertical-orientation 屬性。Unicode UAX #50Vertical Orientation

這是一個單欄直立直書子集的預覽實作,帶有上述有文件記載的 fail-closed 邊界。NextPDF 不斷言此路徑的輸出符合任何設定檔;是否一致由檢查器判定。未重現任何規範文字。