Import HTML5 stránkovaných médií

THPDFHTMLImporter.RenderHTML5 převede shovívavé označení HTML5 a tiskové CSS na stránkovaný obsah PDF, zatímco kompaktní starší cesta RenderHTML zůstává zachována

Délky v CSS a také Margin, BaseFontSize, ListIndent a BlockSpacing importéru jsou v bodech, takže oba renderery vyprodukují tutéž stránku bez ohledu na THotPDF.Resolution; vlastní kreslení před importem a po něm dál používá 1/Resolution palce

Deklarace

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;

Smlouva profilu

HTML5ProfileVersion vrací 1 a HTML5ProfileMilestones uvádí parser a kaskádu, stránkované rozvržení, tabulky a formuláře a omezené zdroje

Měřené odstavce a směr

Odstavce se zalomují podle naměřených posunů aktuálního fontu, včetně změn fontu, běhů bold a italic, letter spacing, word spacing, explicitních zalomení řádků a hranic znaků východoasijských písem; zarovnání a dekorace se aplikují zvlášť na každý vzniklý řádek

direction: ltr, direction: rtl a atribut HTML dir volí směr odstavce; dir="auto" použije Unicode směr prvního silného znaku

Na Windows se bidirectionální běhy skriptů řeší přes Uniscribe a přeřazují napříč hranicemi stylů, zatímco stávající textový engine PDF zajistí tvarování glyfů v rámci každého běhu; směr dokumentu, viewer preferences a uložený textový stav stránky se po řádce obnoví

Inline přepisy směru, bdi a bdo aktuálně použijí pořadí odstavce a vyprodukují diagnostiku hdkLayoutFallback; unicode-bidi leží mimo tento profil a tvarování skriptů dál řídí konfigurace tvarování dokumentu

Fragmentace odstavců

widows a orphans jsou děděná kladná celá čísla, obě defaultně 2; stránkování používá naměřené řádkové boxy, nikoli odhadovaný počet znaků

Importér přesune odstavec nebo upraví jeho dělení tak, aby před a po zalomení stránky zůstal požadovaný minimální počet řádků; break-inside: avoid udrží odstavec pohromadě, když se vejde na novou stránku

Když stránka nedokáže požadované omezení uspokojit, vykreslení pokračuje jeho uvolněním a zaznamenáním hdkPaginationConstraint; každý fragment stránky dostane vlastní pozadí a okraj

Volitelné dělení slov

hyphens: none potlačí dispozitivní dělení a defaultní hyphens: manual používá U+00AD nebo ­; viditelná pomlčka se emituje jen tehdy, když se zvolené dělení skutečně použije

hyphens: auto navíc volá OnHyphenate se slovem a zděděnou hodnotou HTML lang; bez callbacku si ponechá ruční dělení a nahlásí layout fallback, protože žádný jazykový slovník se dodává

Pozice dělení počítají UTF-16 code unit od začátku slova; neplatné, mimo rozsah, dělící náhradníkové páry a základní dělící combining marks se ignorují

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

Ohraničené flex a grid boxy

display: flex podporuje row, row-reverse, column a column-reverse; potomci řádku použijí explicitní šířky nebo se dělí o zbývající šířku a kladné hodnoty flex-grow váží dodatečný prostor

Řádky podporují justify-content start, end, center, space-between, space-around a space-evenly, plus příčné zarovnání start, end, center a stretch; tok do sloupce podporuje přirozené svislé rozvržení a při nepodporovaném dělení pevnou výškou nebo příčném zarovnání emituje diagnostiku

display: grid podporuje kladné pevné délky a sloupcové tracky fr, včetně ohraničeného repeat(n, tracks) s nejvýše 64 sloupci; buňky se umísťují v pořadí ve zdroji a zaplňují po jedné řádce

grid-column: span N a grid-column-end: span N dovolí potomkovi obsadit navazující tracky i mezery mezi nimi; položka, která se nevejde do aktuální řádky, přejde na další řádku a span přesahující počet tracků vyprodukuje layout fallback

flex-wrap: wrap začne novou řádku, když se explicitní šířka a gap další položky nevejdou; každá řádka nezávisle aplikuje flex-grow a justify-content, zatímco row-reverse a RTL otočí pozice v rámci každé řádky, aniž by přesouvaly položky mezi řádkami

gap přijímá jednu nebo dvě délky, s nezávislými přepisy row-gap a column-gap; rovnoběžné řádky zůstanou na jedné stránce a kontrolují se před malováním

Rovnoběžní potomci podporují textové bloky s inline stylováním, rekurzivně vnořené obyčejné blokové kontejnery s paddingem, okraji a pozadím, vnořené flex i grid kontejnery, obrázky a statické nebo nativní formulářové controls

Obrázky používají bajty z callbacku nebo data URI, bez zadané výšky si zachovají vnitřní poměr stran a dekódují se jednou na uzel DOM; preflight i fallback znovu použijí tutéž cacheovanou Image, aniž by spotřebovaly další požadavek na zdroj

Všechny potomské boxy se změří, než se jakákoli rovnoběžná řádka vykreslí, takže nepodporovaný nebo příliš velký obsah spadne zpět do svislého toku stránky bez opakování už vykreslených řádek; vnořené plánování je omezené na 64 úrovní a spotřebovává stávající rozpočet layout operací

Zalamující potomci bez explicitní šířky zabírají celou řádku; tabulky a seznamy uvnitř rovnoběžných potomků, flex basis a shrink, wrap-reverse, vnitřní velikost tracků, řádkové tracky a row spany v gridu a explicitní umísťování v gridu zůstávají mimo tento profil a produkují pozorovatelné diagnostiky

Diagnostika nepodporovaného CSS

Diagnostics zpřístupňuje záznamy obsahující Kind, Subject, Value a MessageText; OnDiagnostic dostane tutéž informaci během vykreslování

Neznámé vlastnosti, nepodporované hodnoty, nepodporované selektory a nepodporované at-rules se ignorují s diagnostikou, včetně deklarací v jinak nepoužitých pravidlech stylesheetu; pseudo selektory se přeskočí, místo aby se braly jako obyčejné typové selektory

StrictCSS, defaultně vypnuté, vyvolá na diagnostiku EHPDFHTMLUnsupportedCSS; část obsahu už mohla být emitovaná, takže volající vyžadující import vše-nebo-nic by měli použít samostatný dokument

MaxDiagnostics má defaultně 256 a omezuje uchovávané záznamy; DiagnosticCount a doručování do callbacku zůstávají pozorovatelné i po dosažení limitu úložiště a nepozitivní limit ukládání záznamů vypne

Omezené zdroje

Externí stylesheety, obrázky a fonty @font-face jsou zakázané, pokud jejich bajty neposkytne OnResource, takže HTML import nikdy implicitně neotevře soubor ani síťové spojení

@font-face podporuje jeden zdroj url(...), volitelné format('truetype') nebo format('opentype'), alias rodiny, styl normal nebo italic a weight normal, bold, 400 nebo 700; font-display přijímá standardní politiky, protože offline import načítá zdroje synchronně

Fonty musí být embeddovatelné TrueType nebo OpenType sfnt zdroje s ASCII názvem rodiny Windows do 31 znaků; WOFF, font collections, local(...), variabilní deskriptory a seznamy zdrojů produkují diagnostiky

Přijaté fonty se na Windows registrují soukromě v paměti procesu a zůstávají vlastněné dokumentem až do jeho zničení, takže uvolnění importéru před EndDoc nezneplatní odložené vkládání fontů

Zdroje data: i výsledky callbacků sdílejí limity MaxResources, MaxResourceBytes a MaxTotalResourceBytes

MaxDecodedImageBytes má defaultně 128 MiB a nezávisle omezuje cache dekódovaných obrázků na čtyři bajty na pixel; rozměry BMP a PNG se kontrolují před dekódováním a každý přijatý obrázek se kontroluje před uchováním

MaxDOMNodes, MaxCSSRules a MaxLayoutOperations nezávisle omezují parsování, stavbu kaskády a práci rozvržení

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

Statistiky

THPDFHTMLImportStatistics uvádí verzi profilu, naparsované uzly, CSS pravidla, operace rozvržení, zalomení stránek, tabulky, ovládací prvky formulářů, požadavky na zdroje, přijatá i odmítnutá načtení, přijaté bajty zdrojů, naměřené textové řádky, řádky s dělením slov, diagnostiky, flex kontejnery a grid kontejnery

OnLineLayout dostane po emitování skutečného textu PDF index stránky a řádky odstavce od nuly, počátek, naměřenou šířku a výšku, logický text, směr a příznak dělení slov

Každé volání RenderHTML5 vynuluje záznam statistik a porušení rozpočtu vyvolá EHPDFHTMLImportBudget

Příklad

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;

Viz také: THPDFPage.TextOutHTML, Declarative Layout DOM, AcroForm Support