跳到內容
getnextpdf.com

Pro 版本

Font Tools — 深入參考

本頁是 NextPDF Pro Font Tools 的合約層級參考。其介面為一個掃描器 NextPDF\Pro\FontTools\FontDesubsetter,以及兩個不可變值物件 SubsetInfoDesubsetPlan。掃描器讀取原始 PDF 位元組、回報每一個相異的 /BaseFont 項目,並標記符合 ISO 32000-2:2020 §9.9.2 子集命名慣例的項目。規劃會彙總被標記的子集,並估算還原完整字型程式所需的位元組成本。此模組僅進行分析與估算;它絕不改寫已嵌入的字型程式。本頁說明公開 API、可觀察的行為合約,以及失敗模式。

此功能隨 NextPDF Pronextpdf/pro)提供,並以 Pro 層級的授權封套啟用。未持有該授權的部署不會載入此功能的類別。比較版本並取得授權

沒有任何單功能授權旗標閘控此模組。只要安裝了 nextpdf/pro,Font Tools 類別即可使用。

符號參數預設行為回傳拋出或失敗於備註
FontDesubsetter針對原始 PDF 位元組的無狀態掃描器final;可安全跨文件重複使用
FontDesubsetter::analyzeSubsets()string $pdfData回報每一個相異的 /BaseFont 項目(無論是否為子集),並以 isSubset 標記list<SubsetInfo>當由寬度推導的子集估計值超過由名稱推導的完整計數估計值時,拋出 InvalidArgumentException位元組層級掃描;不會解碼壓縮的物件串流
FontDesubsetter::isSubsetFont()string $baseFontName比對「六個大寫字母加 +」的前綴慣例bool錨定於名稱開頭
FontDesubsetter::extractSubsetPrefix()string $baseFontName回傳六字母的子集標記string非子集名稱回傳空字串
FontDesubsetter::generateDesubsetPlan()list<SubsetInfo> $subsets收集 isSubsettrue 的項目並加總大小估計值DesubsetPlan不會拋出非子集項目會被靜默略過
SubsetInfo建構子:$fontName$baseFont$subsetGlyphCount$fullGlyphCount$isSubset$encoding單一 /BaseFont 項目的不可變描述字符數為負、或子集數超過完整數時拋出 InvalidArgumentExceptionfinal readonly;所有屬性皆為 public
SubsetInfo::subsetPrefix()fontName 擷取六字母標記string非子集、或 + 不在第六位時回傳空字串
SubsetInfo::coveragePercent()子集佔完整字符集的比例位於 [0.0, 100.0]floatfullGlyphCount0 時回傳 0.0
DesubsetPlan建構子:list<SubsetInfo> $targetsint $estimatedSizeIncrease不可變的去子集規劃final readonly;所有屬性皆為 public
DesubsetPlan::count()目標字型的數量int等於 targets 的長度
DesubsetPlan::totalGlyphsNeeded()所有目標缺少字符的總和int每個目標 fullGlyphCount - subsetGlyphCount 的總和
public function analyzeSubsets(string $pdfData): array
public function isSubsetFont(string $baseFontName): bool
public function extractSubsetPrefix(string $baseFontName): string
public function generateDesubsetPlan(array $subsets): DesubsetPlan
public function __construct(
public string $fontName,
public string $baseFont,
public int $subsetGlyphCount,
public int $fullGlyphCount,
public bool $isSubset,
public string $encoding,
)
public function subsetPrefix(): string
public function coveragePercent(): float
public function __construct(
public array $targets,
public int $estimatedSizeIncrease,
) {}
public function count(): int
public function totalGlyphsNeeded(): int

analyzeSubsets() 以位元組層級的模式比對,從原始位元組中擷取 /BaseFont 名稱權杖。重複的名稱會合併為單一項目;順序依首次出現為準。每一個相異名稱都會產生一個 SubsetInfo,無論其是否為子集。當名稱以恰好六個大寫 ASCII 字母後接 + 開頭時,即為子集,這是 §9.9.2 的慣例。對子集名稱而言,baseFont 是移除七個字元前綴後的名稱。對一般名稱而言,baseFont 等於 fontName。每一個相異的子集名稱都會回報為其自身的項目,符合 §9.9.2 將子集視為獨立實體的指引。

對每一個字型,掃描器會在 /BaseFont 出現處之後搜尋一個有界的位元組視窗。視窗中的 /Encoding 名稱項目優先。若無,則回報視窗中的 Identity-HIdentity-V 子字串。兩者皆無時,該項目回報 Unknown。存放於字典中、或需透過間接參照取得的編碼值會回報 Unknown

兩個字符數皆為估計值。subsetGlyphCount 由字型項目附近可見的寬度陣列推導:CIDFont 的 /W 陣列大致上每個寬度三元組產生一個字符,簡單字型的 /Widths 陣列則每個數值項目產生一個字符。當視窗中兩種陣列皆不可見時,會套用一個固定的小型預設值。當無法為視窗搜尋重新定位 /BaseFont 出現處時,計數為 0fullGlyphCount 由家族名稱啟發式推導:一張知名 Latin 家族的表、一組 CJK 家族名稱指標,其餘則採通用下限。已嵌入的字型程式絕不會被解析。特定的表、視窗大小與常數屬於實作細節,不會公開,且可能在不同版本間變動。

generateDesubsetPlan() 會將輸入過濾為 isSubsettrue 的項目。每個目標會將其缺少字符數乘以固定的「平均每字符位元組數」常數,計入 estimatedSizeIncrease。此規劃是供容量決策使用的推估,而非實測的差異量。執行規劃(改寫字型程式)不在此模組範圍內。

整個介面是其輸入的純函式。相同的位元組產生相同的結果。沒有任何隨機性、網路呼叫或檔案系統存取。

  • SubsetInfo 建構會拒絕無效狀態:字符數為負、或子集數超過完整數,皆會拋出 InvalidArgumentException
  • analyzeSubsets() 在一種特例中可能傳播該例外:某字型的名稱符合已知家族,但其可見的寬度陣列所得的子集估計值大於該家族的完整計數數字。
  • 偵測作用於位元組表示。序列化於壓縮物件串流內的 /BaseFont 項目不可見;請在掃描前先解壓縮這些串流。
  • /BaseFont 鍵與值之間以「單一空格以外」的空白分隔的項目仍會被偵測到,但逐字型的視窗搜尋無法重新定位它們。此類項目回報編碼 Unknown 與子集字符數 0
  • 使用 # 逸出位元組的 PDF 名稱會以原始逸出形式回報;逸出不會被解碼。
  • 重複的 /BaseFont 名稱會合併為單一項目。共用同一名稱的兩個相異字型物件,對此掃描器而言無法區分。
  • generateDesubsetPlan() 對非子集輸入絕不失敗;isSubset 設為 false 的項目只會被排除於 targets 之外。
  • 所有計數與 estimatedSizeIncrease 皆為啟發式值。請勿將其視為實測值;僅供分流與容量規劃使用。
  • 此模組不進行任何密碼學運算,因此沒有 FIPS 模式特有的行為。
主張標準條款
子集偵測符合子集命名慣例:在 BaseFont 值前加上六個大寫字母後接 + 的標記。ISO 32000-2:2020§9.9.2
每一個相異的子集名稱都會獨立回報,遵循將多個子集視為個別實體的建議。ISO 32000-2:2020§9.9.2

所有條款皆為改寫;NextPDF 不重製規範性文字。這些是能力聲明,而非認證。NextPDF 未持有任何認證,亦不授予任何認證。此模組主張其能偵測命名慣例並具決定性回報;它不主張字符數或大小估計值的準確性。

  • composer require nextpdf/pro:^3 安裝。自 nextpdf/pro 1.9.0 起提供;目前為 nextpdf/pro 3.1.0。
  • FontDesubsetter 為無狀態。建構一次即可跨文件與各項工作重複使用。
  • 當子集涵蓋率重要時,請將解壓縮後的位元組餵給 analyzeSubsets();否則封裝於物件串流中的字型字典會被遺漏。
  • 在採取行動前,請依 SubsetInfo::isSubset 分支;結果清單為了盤點目的刻意納入非子集字型。
  • 在取得完整字型程式之前,請使用 DesubsetPlan::totalGlyphsNeeded()estimatedSizeIncrease 判斷去子集是否值得付出檔案大小的成本。
  • 掃描的時間複雜度與輸入長度呈線性,並帶有逐字型的有界視窗搜尋。此模組不儲存任何內容,也不發出任何遙測。

本頁僅記載外部可觀察的行為與受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表、runbook 檔名與工單前綴皆不在範圍內。