HTML5 分頁媒體匯入

THPDFHTMLImporter.RenderHTML5 把寬鬆的 HTML5 標記與列印 CSS 轉換成分頁的 PDF 內容,同時保留精簡的舊版 RenderHTML 路徑

CSS 長度與 importer 的 Margin、BaseFontSize、ListIndent 與 BlockSpacing 都以點為單位,因此無論 THotPDF.Resolution 設為何值,兩個 renderer 產出的頁面都一致;你在匯入前後自行繪製的部分仍使用 1/Resolution 英吋

宣告

function RenderHTML5(
  const HTML: WideString;
  const AuthorStyleSheet: WideString = '';
  MarginPt: Single = 72;
  const FontName: AnsiString = 'Arial';
  FontSize: Single = 12
): Boolean;

function HPDFRenderHTML5Document(
  Doc: THotPDF;
  const HTML: WideString;
  const AuthorStyleSheet: WideString = '';
  MarginPt: Single = 72;
  const FontName: AnsiString = 'Arial';
  FontSize: Single = 12
): Boolean;

設定檔契約

HTML5ProfileVersion 回傳 1,HTML5ProfileMilestones 則回報解析器與階層串接、分頁版面、表格與表單,以及有界資源這幾個里程碑

實測段落與方向

段落折行以目前字型的實測前進量為準,包括字型切換、粗體與斜體段、字距、詞距、明確換列與東亞字元邊界;對齊與裝飾分別套用到結果的每一列

direction: ltr、direction: rtl 與 HTML dir 屬性選擇段落方向;dir="auto" 採用第一個強字元的 Unicode 方向

在 Windows 上,雙向腳本段以 Uniscribe 解析並跨越樣式邊界重排,段內的字形塑形仍由既有 PDF 文字引擎處理;該列結束後會還原文件方向、檢視器偏好與已儲存的頁面文字狀態

行內方向覆寫、bdi 與 bdo 目前沿用段落排序並產生 hdkLayoutFallback 診斷;unicode-bidi 不在此設定檔內,腳本塑形仍依文件的塑形組態

段落斷裂

widows 與 orphans 是可繼承的正整數,預設都是 2;分頁以實測的行方框為準,而不是估計字元數

匯入器會搬移段落或調整其切分位置,讓分頁點前後都留下要求的最少列數;break-inside: avoid 會在段落放得進全新一頁時保持段落完整

當一頁放不下要求的約束時,轉譯會放寬約束讓排版繼續推進並記錄 hdkPaginationConstraint;每個頁面片段都有各自的背景與邊框

選用的斷字

hyphens: none 停用任意斷字,預設的 hyphens: manual 使用 U+00AD 或 ­;只有實際採用該斷點時才會輸出可見的連字符號

hyphens: auto 會另外以該單字與繼承的 HTML lang 值呼叫 OnHyphenate;沒有回呼時保留手動斷點並回報版面後備,因為程式庫不內建任何語言詞典

斷點位置以從單字開頭起算的 UTF-16 code unit 計數;無效、超出範圍、切在 surrogate 對中間與切在基本組合標記中的位置都會被忽略

THPDFHTMLHyphenationEvent = procedure(
  Sender: TObject;
  const WordText, Language: WideString;
  var BreakPositions: TArray<Integer>
) of object;

有界的 flex 與 grid 方框

display: flex 支援 row、row-reverse、column 與 column-reverse;列子項使用明確寬度或分攤剩餘寬度,正的 flex-grow 值決定額外空間的權重

列支援 justify-content 的 start、end、center、space-between、space-around 與 space-evenly,加上 start、end、center 與 stretch 的交叉軸對齊;column 流向支援自然的垂直排版,遇到不支援的固定高度分配或交叉軸對齊則發出診斷

display: grid 支援正的固定長度與 fr 欄軌,包括最多 64 欄的有界 repeat(n, tracks);儲存格按來源順序放置,一次填滿一列

grid-column: span N 與 grid-column-end: span N 讓子項佔據連續軌道及其間距;放不進目前列的項目會移到下一列,跨距大於軌道數則產生版面後備

flex-wrap: wrap 在下一個項目的明確寬度加上間距放不下時另起一列;每一列獨立套用 flex-grow 與 justify-content,而 row-reverse 與 RTL 只反轉各列內的位置,不會把項目搬到別列

gap 接受一或兩個長度,並可用 row-gap 與 column-gap 獨立覆寫;平行的列會留在同一頁,並在繪製前檢查

平行子項支援帶行內樣式的文字區塊、可遞迴巢狀並具 padding、邊框與背景的普通區塊容器、巢狀 flex 與 grid 容器、影像,以及靜態或原生表單控制項

影像使用回呼提供或 data URI 位元組,未指定高度時保留其原始長寬比,且每個 DOM 節點只解碼一次;preflight 與後備重用同一張快取影像,不會再消耗一次資源請求

所有子方框都在任何平行列繪製之前完成量測,因此不支援或過大的內容會後備到垂直頁面流動,不會重繪已畫過的列;巢狀規劃以 64 層為界,並計入既有的版面操作預算

沒有明確寬度的折天子項佔滿一整列;平行子項內的表格與清單、flex basis 與 shrink、wrap-reverse、內在軌道尺寸、grid 列軌與列跨距,以及明確的 grid 放置都不在此設定檔內,會產生可觀察的診斷

不支援的 CSS 診斷

Diagnostics 暴露含 Kind、Subject、Value 與 MessageText 的記錄;轉譯期間 OnDiagnostic 收到同樣的資訊

未知屬性、不支援的值、不支援的選擇器與不支援的 at-rule 會在產生診斷後被忽略,包括那些整條規則沒被用到的宣告;偽類選擇器會被略過,而不是當成普通類型選擇器處理

StrictCSS 預設關閉,開啟後遇到診斷會引發 EHPDFHTMLUnsupportedCSS;此時先前內容可能已經輸出,需要全有或全無匯入的呼叫端請改用獨立文件

MaxDiagnostics 預設 256,約束保留的記錄數;達到儲存上限後 DiagnosticCount 與回呼遞送仍可觀察,非正數的上限則停用記錄儲存

有界資源

除非 OnResource 提供其位元組,否則外部樣式表、影像與 @font-face 字型都被停用,因此 HTML 匯入絕不會隱式開啟檔案或網路連線

@font-face 支援單一 url(...) 來源、選用的 format('truetype') 或 format('opentype')、家族別名、normal 或 italic 樣式,以及 normal、bold、400 或 700 字重;font-display 接受標準政策,因為離線匯入是同步載入資源

字型必須是可內嵌的 TrueType 或 OpenType sfnt 資源,帶最長 31 字元的 ASCII Windows 家族名稱;WOFF、字型集合、local(...)、可變字型描述元與來源清單都會產生診斷

被接受的字型會在 Windows 上私下註冊於處理程序記憶體,所有權屬於文件直到文件銷毀,所以在 EndDoc 前釋放匯入器不會讓延遲的字型內嵌失效

data: 資源與回呼結果共用 MaxResources、MaxResourceBytes 與 MaxTotalResourceBytes 上限

MaxDecodedImageBytes 預設 128 MiB,以每像素 4 位元組獨立約束已解碼影像快取;BMP 與 PNG 的尺寸會在解碼前檢查,每張被接受的圖片在保留前也會檢查

MaxDOMNodes、MaxCSSRules 與 MaxLayoutOperations 分別約束解析、階層串接建構與版面工作

THPDFHTMLResourceEvent = procedure(
  Sender: TObject;
  const URI: WideString;
  ResourceKind: THPDFHTMLResourceKind;
  var Data: TBytes;
  var ContentType: string;
  var Handled: Boolean
) of object;

統計

THPDFHTMLImportStatistics 回報設定檔版本、已解析節點、CSS 規則、版面操作、分頁、表格、表單控制項、資源要求、被接受與被拒絕的載入、被接受的資源位元組、實測文字列、已斷字列、診斷、flex 容器與 grid 容器

OnLineLayout 在實際 PDF 文字輸出之後收到該列的零基頁面與段落行索引、原點、實測寬高、邏輯文字、方向與斷字旗標

每次 RenderHTML5 呼叫都會重設統計記錄,違反預算則引發 EHPDFHTMLImportBudget

範例

Importer := THPDFHTMLImporter.Create(Doc);
try
  Importer.CreateAcroForms := True;
  Importer.MaxResources := 16;
  Importer.RenderHTML5(
    '<style>@page { margin: 36pt } ' +
    'table { width: 100% }</style>' +
    '<h1>Invoice</h1>' +
    '<table><tr><td>Total</td><td>42</td></tr></table>' +
    '<input name="approved" type="checkbox">'
  );
finally
  Importer.Free;
end;

另請參閱:THPDFPage.TextOutHTML、宣告式版面 DOM、AcroForm 支援