HTML5 Paged-Media Import

THPDFHTMLImporter.RenderHTML5 converts tolerant HTML5 markup and print CSS into paginated PDF content while preserving the compact legacy RenderHTML path

Lungimile CSS și Margin, BaseFontSize, ListIndent și BlockSpacing ale importer-ului sunt în puncte, astfel încât ambele randere produc aceeași pagină indiferent de valoarea lui THotPDF.Resolution; desenul propriu dinainte și după import continuă să folosească 1/Resolution inch

Declarație

function RenderHTML5(
  const HTML: WideString;
  const AuthorStyleSheet: WideString = ''
): Boolean;

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

Profile contract

HTML5ProfileVersion returnează 1, iar HTML5ProfileMilestones raportează parser și cascadă, layout paginat, tabele și formulare, plus resurse mărginite

Paragrafe măsurate și direcție

Paragrafele se încadrează folosind avansurile măsurate ale fontului curent, inclusiv schimbările de font, rulurile bold și italic, spațierea literelor, spațierea cuvintelor, întreruperile explicite de linie și granițele de caractere est-asiatice; alinierea și decorarea se aplică separat fiecărei linii rezultate

direction: ltr, direction: rtl și atributul HTML dir selectează direcția paragrafului; dir="auto" folosește direcția Unicode a primului caracter puternic

Pe Windows, rulurile de scripturi bidirecționale sunt rezolvate cu Uniscribe și reordonate peste granițele de stil, în timp ce motorul existent de text PDF se ocupă de shaping-ul glifelor în interiorul fiecărei rulări; direcția documentului, preferințele de vizualizator și starea salvată a textului paginii sunt restaurate după linie

Suprascrierile inline de direcție, bdi și bdo folosesc în prezent ordonarea paragrafului și produc un diagnostic hdkLayoutFallback; unicode-bidi este în afara acestui profil, iar shaping-ul scripturilor urmează în continuare configurația de shaping a documentului

Fragmentarea paragrafelor

widows și orphans sunt întregi pozitivi moșteniți, amândouă cu valoarea implicită 2; paginarea folosește casetele de linie măsurate, nu un număr estimat de caractere

Importatorul mută un paragraf sau își ajustează împărțirea astfel încât să lase numărul minim cerut de linii înainte și după o întrerupere de pagină; break-inside: avoid ține un paragraf împreună când încape pe o pagină nouă

Când o pagină nu poate susține constrângerea cerută, randarea face progres relaxând constrângerea și înregistrând hdkPaginationConstraint; fiecare fragment de pagină primește propriul fundal și chenar

Despărțire opțională a cuvintelor

hyphens: none suprimă întreruperile discreționare, iar valoarea implicită hyphens: manual folosește U+00AD sau ­; o liniuță de despărțire vizibilă este emisă doar când întreruperea selectată este folosită

hyphens: auto apelează în plus OnHyphenate cu cuvântul și valoarea HTML lang moștenită; fără un callback păstrează întreruperile manuale și raportează un fallback de layout, deoarece nicio dictare de limbă nu este inclusă în bibliotecă

Pozițiile de întrerupere numără unități de cod UTF-16 de la începutul cuvântului; pozițiile invalide, în afara intervalului, care taie perechi surrogate și cele care taie semne combinate de bază sunt ignorate

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

Casete flex și grid mărginite

display: flex suportă row, row-reverse, column și column-reverse; copiii de rând folosesc lățimi explicite sau partajează lățimea rămasă, iar valorile pozitive flex-grow cântăresc spațiul suplimentar

Rândurile suportă justify-content start, end, center, space-between, space-around și space-evenly, plus alinierea pe axa încrucișată start, end, center și stretch; fluxul de coloane suportă așezare verticală naturală și emite un diagnostic pentru distribuirea nesuportată pe înălțime fixă sau pentru alinierea pe axa încrucișată

display: grid suportă piste de coloane pozitive cu lungime fixă și fr, inclusiv repeat(n, tracks) mărginit cu până la 64 de coloane; celulele sunt plasate în ordinea sursei, umplând câte un rând o dată

grid-column: span N și grid-column-end: span N permit unui copil să ocupe piste consecutive și golurile dintre ele; un element care nu încape în rândul curent trece pe rândul următor, iar span-urile mai mari decât numărul de piste produc un fallback de layout

flex-wrap: wrap pornește o linie nouă când lățimea explicită și golul următorului element nu încape; fiecare linie aplică independent flex-grow și justify-content, în timp ce row-reverse și RTL inversează pozițiile în interiorul fiecărei linii, fără a muta elemente între linii

gap acceptă una sau două lungimi, cu suprascrieri independente row-gap și column-gap; rândurile paralele rămân pe o singură pagină și sunt verificate înainte de pictare

Copiii paraleli suportă blocuri de text cu stilizare inline, containere obișnuite recursiv imbricate cu padding, chenare și fundaluri, containere flex și grid imbricate, imagini și controale de formular statice sau native

Imaginile folosesc bytes furnizate prin callback sau URI-uri de date, își păstrează raportul de aspect intrinsec când nu se specifică o înălțime și sunt decodate o singură dată per nod DOM; preflight-ul și fallback-ul reutilizează aceeași imagine din cache fără a consuma o altă cerere de resursă

Toate casetele copil sunt măsurate înainte ca orice rând paralel să fie pictat, astfel încât conținutul nesuportat sau supradimensionat cade pe fluxul vertical al paginii fără a repeta rândurile pictate anterior; planificarea imbricată este mărginită la 64 de niveluri și consumă bugetul existent de operații de layout

Copiii care se încadrează, fără lățime explicită, ocupă o linie completă; tabelele și listele din interiorul copiilor paraleli, flex-basis și shrink, wrap-reverse, dimensionarea intrinsecă a pistelor, pistele și span-urile de rând grid și plasarea grid explicită rămân în afara acestui profil și produc diagnostice observabile

Diagnostice CSS nesuportate

Diagnostics expune înregistrări care conțin Kind, Subject, Value și MessageText; OnDiagnostic primește aceleași informații în timpul randării

Proprietățile necunoscute, valorile nesuportate, selectorii nesuportați și at-rule-urile nesuportate sunt ignorate cu un diagnostic, inclusiv declarațiile din reguli de stylesheet altfel nefolosite; selectorii pseudo sunt omiși, nu tratați ca selectori obișnuiți de tip

StrictCSS, dezactivat implicit, ridică EHPDFHTMLUnsupportedCSS la un diagnostic; conținutul anterior poate fi deja emis, deci apelanții care cer import tot-sau-nimic ar trebui să folosească un document separat

MaxDiagnostics implicit 256 mărginește înregistrările reținute; DiagnosticCount și livrarea prin callback rămân observabile după atingerea limitei de stocare, iar o limită nepozitivă dezactivează stocarea înregistrărilor

Bounded resources

Foile de stil externe, imaginile și fonturile @font-face sunt dezactivate dacă OnResource nu furnizează bytes-urile lor, astfel încât importul HTML nu deschide niciodată implicit o conexiune de fișier sau de rețea

@font-face suportă o sursă url(...), format('truetype') sau format('opentype') opțional, un alias de familie, stil normal sau italic și greutate normal, bold, 400 sau 700; font-display acceptă politicile standard, deoarece importul offline încarcă resursele sincron

Fonturile trebuie să fie resurse sfnt TrueType sau OpenType încorporabile, cu un nume de familie Windows ASCII de cel mult 31 de caractere; WOFF, colecțiile de fonturi, local(...), descriptorii de variabile și listele de surse produc diagnostice

Fonturile acceptate sunt înregistrate privat în memoria procesului pe Windows și rămân proprietatea documentului până la distrugerea acestuia, astfel încât eliberarea importatorului înainte de EndDoc nu invalidează încorporarea amânată a fonturilor

Resursele data: și rezultatele callback-urilor partajează limitele MaxResources, MaxResourceBytes și MaxTotalResourceBytes

MaxDecodedImageBytes implicit 128 MiB mărginește independent cache-ul de imagini decodate la patru bytes per pixel; dimensiunile BMP și PNG sunt verificate înainte de decodare, iar fiecare imagine acceptată este verificată înainte de a fi reținută

MaxDOMNodes, MaxCSSRules și MaxLayoutOperations mărginesc independent parsarea, construirea cascadei și munca de layout

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

Statistics

THPDFHTMLImportStatistics raportează versiunea profilului, nodurile parsate, regulile CSS, operațiile de layout, întreruperile de pagină, tabelele, controalele de formular, cererile de resurse, încărcările acceptate și respinse, bytes-urile de resurse acceptate, liniile de text măsurate, liniile cu despărțire, diagnosticele, containerele flex și containerele grid

OnLineLayout primește indicele paginii cu bază zero și al liniei de paragraf, originea, lățimea și înălțimea măsurate, textul logic, direcția și flag-ul de despărțire ale liniei, după ce textul PDF efectiv a fost emis

Fiecare apel RenderHTML5 resetează înregistrarea de statistici, iar încălcările de buget ridică EHPDFHTMLImportBudget

Exemplu

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;

See also: THPDFPage.TextOutHTML, Declarative Layout DOM, AcroForm Support