宣告式版面 DOM

HPDFLayoutDOM 在 THPDFLayoutElement、MeasureLayoutElement、PlaceLayoutElement、所屬溢位片段與 ImmediateFlushLayout 之上建置可重用的文件元件

文件與區段組合

Document := THPDFDOMDocument.Create;
Renderer := THPDFDOMRenderer.Create;
try
  Section := Document.AddSection;
  Section.PageWidth := 595.28;
  Section.PageHeight := 841.89;
  Section.Header := THPDFDOMText.Create('Quarterly report');
  Section.Footer := THPDFDOMText.Create('Confidential');
  Section.Body.Style.Padding := 12;
  Section.Body.Style.Spacing := 8;
  Section.Body.AddText(BodyText, 'Narrative');

  PDF.OutputStream := Output;
  PDF.ImmediateFlushLayout := True;
  Statistics := Renderer.Render(Document, PDF);
finally
  Renderer.Free;
  Document.Free;
end;

THPDFDOMDocument 擁有其區段、每個 THPDFDOMSection 擁有其本體、頁首、頁尾與樣式,而每個堆疊或容器都擁有附加到它的元件

THPDFDOMRenderer.Render 啟動與結束目標文件、為每個新區段建立新頁面、在接續頁面上重複區段傢飾,並傳回頁面、放置、分割、傢飾、結構、標記內容、工件與最大接續統計

在呼叫 Render 之前設定所有的 THotPDF 輸出、壓縮、遵循、圖層與立即清除選項

GenerateStructure 預設為 True,因此轉譯器也會建置支援接續的邏輯結構樹,並在目標沒有語言時使用 THPDFDOMDocument.Language

元件

所有元件都公開穩定的 Name、Path、Style、Clone、Measure、Draw 與 Split 契約,加上語意角色、語言、替代文字、取代文字、擴充文字與工件覆寫

頂層本體遍歷是線性的,且不複製元件;文字與表格接續保留範圍或列切片中繼資料,而不複製完整的內容樹

樣式繼承

THPDFDOMStyle 透過其父鏈解析字型名稱、大小、樣式、文字色彩、背景、邊框、內距、間距與行高

區段樣式是其本體與傢飾的父、堆疊或容器樣式是其子項的父,而表格樣式會流過列到儲存格

只有明確指派的值會覆寫父;Clear 移除本地指派與父連結,而 Assign 在不複製擁有權或血統的情況下複製本地指派

深度超過 64 層的父鏈會作為循環或無界而遭到拒絕

可重用的元件工廠

THPDFDOMComponentFactory 是一個匿名函式,每次呼叫都建立一個呼叫端所屬的 THPDFDOMComponent 執行個體

Document.RegisterComponent('notice',
  function: THPDFDOMComponent
  begin
    Result := THPDFDOMContainer.Create(
      THPDFDOMText.Create('Reusable notice'));
  end);

Section.Body.Add(Document.CreateComponent('notice'));

工廠名稱是大小寫不敏感且唯一的、每個呼叫都必須傳回新的元件執行個體,而接收容器在 Add 之後取得擁有權

當一個宣告的元件必須在多個擁有權位置重用時,請使用 SetHeaderClone、SetFooterClone 或 Clone

重複頁首表格

Table := THPDFDOMTable.Create('Orders');
Table.AddColumn(1);
Table.AddColumn(3);
Header := Table.AddRow(18, True);
Header[0].Text := 'ID';
Header[1].Text := 'Description';

Row := Table.AddRow(22);
Row[0].Text := '1001';
Row[1].Text := 'Bounded streaming layout';
Section.Body.Add(Table);

頁首列必須連續且位於內文列之前、正的欄權重分割可用寬度,而列高是明確的正值

當 RepeatHeaders 為真時,分割需要所有前導頁首列加上至少一個內文列的位置,防止只有頁首的接續頁面

分頁與失敗界限

轉譯器會先針對剩餘的本體矩形重新量測每個元件、在可能時把無法分割的最小片段移到新頁面,並把每個有效的分割委派給 PlaceLayoutElement

無法容納空內文頁面的元素會以穩定的元素路徑提高例外,而不會靜默捨棄內容

MaximumContinuationDepth 預設為 100,000,並約束反覆傳回不進展接續的格式錯誤元件

區段頁面維度必須為正、邊界與傢飾間距不能為負,而頁首加頁尾的幾何必須留下正的本體矩形

C++Builder

std::unique_ptr<THPDFDOMDocument> document(new THPDFDOMDocument());
THPDFDOMSection* section = document->AddSection();
section->Header = new THPDFDOMText(L"Report", "Header");
section->Body->AddText(L"Declarative content", "BodyText");

std::unique_ptr<THPDFDOMRenderer> renderer(new THPDFDOMRenderer());
THPDFDOMRenderStatistics statistics =
    renderer->Render(document.get(), pdf.get());

產生的 HPDFLayoutDOM.hpp 匯出相同的文件、樣式、元件、表格、區段、轉譯器與統計介面

相關 API