線性化:Fast Web View 輸出
線性化 PDF,也就是 Fast Web View,會透過特定布局,讓讀取端能在檔案其餘部分尚未抵達前先顯示第一頁。第一頁的物件、其交叉參照子區段,以及用來定位其他每一頁的提示表,都會放在檔案前段。NextPDF 會以確定性方式輸出這套布局:相同文件在每一台主機上都會產生相同的位元組,且結果可通過 qpdf --check-linearization 檢查。
線性化是一項 Core 功能。你可以在 Document 上啟用;引擎會處理三趟布局、線性化參數字典與提示表。讀取端的 LinearizationView 會剖析已完成檔案的線性化字典,讓傳輸層(transport)不必重新實作這套格式,就能規畫傳遞。
composer require nextpdf/core:^3概念總覽
標題為「概念總覽」的區段標準 PDF 會把交叉參照表放在檔案最尾端,因此讀取端必須先取得檔案尾段,才能解析(resolve)任何物件。線性化 PDF 會把檔案重新排列成兩個部分。第一部分包含線性化參數字典、第一頁,以及頁面偏移提示表。第二部分包含其餘各頁。支援 Fast Web View 的讀取端可以先從第一部分繪製第一頁,再利用提示表,在位元組持續抵達時直接定位到後續任何一頁——ISO 32000-2 Annex F。
NextPDF 提供兩種後端(backend)。預設的 v2 後端是三趟線性化器,會產生符合 ISO 32000-2 Annex F 的輸出,包含符合規範的頁面偏移提示表,且其 /L 長度會精確等於檔案的位元組長度。保留舊版 v1 後端,是為了與 v2 之前產生的文件維持位元組相容;它會輸出不符規範的 Annex F 參數,而且只有明確選用時才會啟用。新的開發工作應使用預設後端。
確定性是一項嚴格保證。檔案識別碼會從內容摘要推導而來,而不是取自隨機來源,因此 enableLinearization() 是文件的純函式。正是這一點讓黃金位元組測試(golden byte tests)能夠鎖定輸出,也讓下游能實作內容定址快取或穩定的 ETag。
啟用線性化
標題為「啟用線性化」的區段<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Core\Document;
$document = Document::createStandalone();$document->writeHtml('<h1>Quarterly report</h1>');$document->enableLinearization();
// Deterministic: the same document always produces the same bytes.$pdf = $document->output();預設後端是 v2。若要改用舊版 v1 後端,請先呼叫 useLegacyLinearizer()(兩種順序皆可):
$document->useLegacyLinearizer();$document->enableLinearization();從組態設定啟用
標題為「從組態設定啟用」的區段你也可以透過 Config 以宣告式方式啟用。這項設定會在建構文件時套用,適合一開始就固定好傳遞格式、且不想針對每份文件逐一呼叫方法的管線:
use NextPDF\Core\Config;use NextPDF\Core\Document;
$config = (new Config())->withLinearization();$document = Document::createStandalone($config);$document->writeHtml('<h1>Quarterly report</h1>');
$pdf = $document->output(); // linearized outputwithLinearization() 與其他 Config 選項一樣,預設為關閉。傳入 false 可讓這個選擇更明確。以這種方式建構的文件會走相同的 enableLinearization() 路徑,因此下方的規範守衛同樣適用。
規範互動關係
標題為「規範互動關係」的區段線性化可與標記式(tagged)及封存(archival)設定檔搭配使用,但會與那些使前置提示表或位元組範圍簽章失效的功能互斥。
| 功能 | 互動關係 |
|---|---|
| PDF/A、PDF/UA 設定檔 | 可搭配使用。v2 會保留物件編號,因此結構與標籤參照仍然有效。 |
| 加密(AES-256、AES-GCM、公開金鑰) | 互斥。 提示串流(hint stream)會以明文輸出,因此引擎會拒絕這個組合。 |
| PAdES 簽章 | 互斥。 重新線性化會改寫位元組偏移,並破壞簽章的 /ByteRange。 |
| 增量更新 | 在單次建構中互斥。 |
這道守衛是雙向的,且不受呼叫順序影響:要求對已標記為線性化的文件加密(或簽章)會擲出例外;將已加密(或已簽章)的文件標記為線性化也會擲出例外。兩者都會擲出 InvalidConfigException。
use NextPDF\Exception\InvalidConfigException;
$document->setEncryption('user-pw', 'owner-pw'); // (userPassword, ownerPassword)
try { $document->enableLinearization(); // rejected — encryption is already configured} catch (InvalidConfigException $e) { // Linearization and encryption cannot be combined on one document.}讀取線性化檔案
標題為「讀取線性化檔案」的區段LinearizationView 會剖析已完成 PDF 前段的線性化參數字典。它是傳輸層規畫傳遞時唯一受支援的綁定點;呼叫端不需要自行重新實作字典剖析。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Writer\Linearization\LinearizationView;
$view = LinearizationView::fromPdf($pdf);
if ($view->isLinearized) { // Plan, e.g., a first-page byte range from the parsed dictionary fields: // file length, first-page object number, main cross-reference offset, // hint-table offset and length, first-page end offset, page count. $firstPageEnd = $view->firstPageEndOffset;}API 介面
標題為「API 介面」的區段| 型別 | 種類 | 主要成員 | 穩定性 | 自版本 |
|---|---|---|---|---|
Document | 類別 | enableLinearization(): static、useLegacyLinearizer(): static | 穩定 | 3.2.0 |
Config | 類別 | withLinearization(bool $linearize = true): self | 穩定 | 6.1.0 |
LinearizationView | 類別 | fromPdf(string): self、lengthMatches(int): bool、公開的唯讀字典欄位 | 穩定 | 3.2.0 |
enableLinearization() 會在加密或 PAdES 簽章已設定時擲出 InvalidConfigException。對於不含任何線性化字典的文件,LinearizationView::fromPdf() 會回傳一個 isLinearized 旗標為 false 的檢視。
- 線性化文件無法同時被加密,也無法使用 PAdES 簽章。每次建構只能擇一。
- 舊版 v1 後端會輸出不符規範的 Annex F 參數,只是為了與較舊的輸出維持位元組相容而存在。規範守衛是針對 v2 執行的。
- Fast Web View 是一種傳遞最佳化,而非安全性或驗證功能;它不會改變已繪製的頁面內容。