Import HTML5 paginowanych mediów
THPDFHTMLImporter.RenderHTML5 konwertuje tolerancyjny znacznik HTML5 i CSS druku na paginowaną treść PDF, zachowując zwartą starszą ścieżkę RenderHTML
Długości CSS oraz Margin, BaseFontSize, ListIndent i BlockSpacing importera są w punktach, więc oba renderery produkują tę samą stronę niezależnie od ustawionego THotPDF.Resolution; własne rysowanie przed i po imporcie nadal używa 1/Resolution cala
Deklaracja
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;
Kontrakt profilu
HTML5ProfileVersion zwraca 1, a HTML5ProfileMilestones raportuje parser i kaskadę, układ paginowany, tabele i formularze oraz ograniczone zasoby
- The tolerant DOM przyjmuje typowe pominięte znaczniki końcowe, zachowuje kolejność tekstu, pomija nieaktywne regiony dokumentu i egzekwuje
MaxDOMNodes - Kaskada obsługuje selektory typu, klasy, ID, atrybutu równości, potomka i bezpośredniego dziecka, kolejność źródła, specyficzność, deklaracje wbudowane,
!important,@media printi marginesy@page - Układ paginowany obsługuje przepływ blokowy, nagłówki, listy, obramowania, tła, odstępy ramek, jawne przerwy stron, tabele, obrazy i automatyczną paginację przepełnienia
- Wejścia tekstowe, przyciski, pola wyboru, przyciski opcji, obszary tekstowe i kontrolki wyboru renderują jako statyczne wyglądy lub natywne pola AcroForm, gdy
CreateAcroFormsjest włączone
Mierzone akapity i kierunek
Akapity zawijają się z użyciem zmierzonych posunięć bieżącego fontu, łącznie ze zmianami fontu, przebiegami bold i italic, odstępami liter, odstępami słów, jawnymi łamaniami linii i granicami znaków wschodnioazjatyckich; wyrównanie i dekoracje stosują się osobno do każdej powstałej linii
direction: ltr, direction: rtl i atrybut HTML dir wybierają kierunek akapitu; dir="auto" używa kierunku Unicode pierwszego silnego znaku
Na Windows dwukierunkowe przebiegi skryptów są rozwiązywane przez Uniscribe i przestawiane przez granice stylów, podczas gdy istniejący silnik tekstu PDF zajmuje się shapingu glifów wewnątrz każdego przebiegu; kierunek dokumentu, preferencje przeglądarki i zapisany stan tekstu strony są przywracane po linii
Wbudowane nadpisania kierunku, bdi i bdo używają obecnie kolejności akapitu i dają diagnostykę hdkLayoutFallback; unicode-bidi wykracza poza ten profil, a shaping skryptów nadal podąża za konfiguracją shapingu dokumentu
Fragmentacja akapitów
widows i orphans to dziedziczone dodatnie liczby całkowite, oba domyślnie 2; paginacja używa zmierzonych line boxów, a nie szacowanej liczby znaków
Importer przenosi akapit albo koryguje jego podział tak, by przed i po przerwie strony zostawić żądaną minimalną liczbę linii; break-inside: avoid trzyma akapit w całości, gdy mieści się na świeżej stronie
Gdy strona nie może pomieścić żądanego ograniczenia, renderowanie robi postępy przez jego poluzowanie i zapisanie hdkPaginationConstraint; każdy fragment strony dostaje własne tło i obramowanie
Opcjonalne dzielenie wyrazów
hyphens: none wycisza łamania dyskrecjonalne, a domyślne hyphens: manual używa U+00AD lub ­; widoczny łącznik pojawia się tylko wtedy, gdy wybrane łamanie jest faktycznie użyte
hyphens: auto dodatkowo wywołuje OnHyphenate ze słowem i odziedziczoną wartością HTML lang; bez callbacku pozostają łamania ręczne i raportowany jest fallback układu, bo żadnego słownika językowego nie ma w pakiecie
Pozycje łamań liczą jednostki kodowe UTF-16 od początku słowa; pozycje nieprawidłowe, poza zakresem, dzielące pary zastępcze i dzielące podstawowe znaki diakrytyczne są ignorowane
THPDFHTMLHyphenationEvent = procedure(
Sender: TObject;
const WordText, Language: WideString;
var BreakPositions: TArray<Integer>
) of object;
Ograniczone boxy flex i grid
display: flex obsługuje row, row-reverse, column i column-reverse; dzieci w wierszu używają jawnych szerokości albo dzielą pozostałą szerokość, a dodatnie wartości flex-grow ważują dodatkową przestrzeń
Wiersze obsługują justify-content start, end, center, space-between, space-around i space-evenly oraz wyrównanie osi poprzecznej start, end, center i stretch; przepływ kolumnowy obsługuje naturalny układ pionowy i emituje diagnostykę dla nieobsługiwanego rozkładu o stałej wysokości albo wyrównania osi poprzecznej
display: grid obsługuje dodatnie kolumny o stałej długości i fr, łącznie z ograniczonym repeat(n, tracks) do 64 kolumn; komórki są umieszczane w kolejności źródłowej, wypełniając wiersz po wierszu
grid-column: span N i grid-column-end: span N pozwalają dziecku zająć sąsiednie kolumny razem z interweniującymi odstępami; element, który nie mieści się w bieżącym wierszu, przechodzi do następnego, a rozpiętości większe niż liczba kolumn dają fallback układu
flex-wrap: wrap zaczyna nową linię, gdy jawna szerokość i odstęp następnego elementu nie mieszczą się; każda linia niezależnie stosuje flex-grow i justify-content, przy czym row-reverse i RTL odwracają pozycje wewnątrz każdej linii bez przenoszenia elementów między liniami
gap przyjmuje jedną lub dwie długości, z niezależnymi nadpisaniami row-gap i column-gap; równoległe wiersze pozostają na jednej stronie i są sprawdzane przed malowaniem
Dzieci równoległe obsługują bloki tekstu ze stylingiem inline, rekurencyjnie zagnieżdżone zwykłe kontenery blokowe z paddingiem, obramowaniami i tłami, zagnieżdżone kontenery flex i grid, obrazy oraz statyczne albo natywne kontrolki formularzy
Obrazy używają bajtów z callbacku albo data URI, zachowują własne proporcje, gdy nie podano wysokości, i są dekodowane raz na węzeł DOM; preflight i fallback ponownie używają tej samej zcache'owanej grafiki bez kolejnego żądania zasobu
Wszystkie boxy dzieci są mierzone przed zamalowaniem czegokolwiek w równoległym wierszu, więc zawartość nieobsługiwana albo zbyt duża schodzi do pionowego przepływu strony bez powtarzania zamalowanych wierszy; planowanie zagnieżdżania jest ograniczone do 64 poziomów i zużywa istniejący budżet operacji układu
Zawijające się dzieci bez jawnej szerokości zajmują jeden pełny wiersz; tabele i listy wewnątrz dzieci równoległych, flex basis i shrink, wrap-reverse, wewnętrzne wymiarowanie ścieżek, wiersze gridu i rozpiętości wierszy oraz jawne rozmieszczanie gridu pozostają poza tym profilem i dają obserwowalne diagnostyki
Diagnostyka nieobsługiwanego CSS
Diagnostics wystawia rekordy zawierające Kind, Subject, Value i MessageText; OnDiagnostic odbiera te same informacje podczas renderowania
Nieznane właściwości, nieobsługiwane wartości, nieobsługiwane selektory i nieobsługiwane at-rules są ignorowane z diagnostyką, łącznie z deklaracjami w nieużywanych regułach arkusza; selektory pseudo są pomijane, a nie traktowane jak zwykłe selektory typu
StrictCSS, domyślnie wyłączone, podnosi EHPDFHTMLUnsupportedCSS przy diagnostyce; wcześniejsza zawartość mogła już zostać wyemitowana, więc wywołujący wymagający importu wszystko-albo-nic powinni użyć osobnego dokumentu
MaxDiagnostics domyślnie 256 ogranicza przechowywane rekordy; DiagnosticCount i dostarczanie przez callback pozostają obserwowalne po osiągnięciu limitu magazynu, a niepozytywny limit wyłącza magazynowanie rekordów
Ograniczone zasoby
Zewnętrzne arkusze stylów, obrazy i fonty @font-face są wyłączone, chyba że OnResource dostarcza ich bajty, więc import HTML nigdy nie otwiera pliku ani połączenia sieciowego pośrednio
@font-face obsługuje jedno źródło url(...), opcjonalne format('truetype') lub format('opentype'), alias rodziny, styl normal lub italic oraz grubość normal, bold, 400 albo 700; font-display akceptuje standardowe polityki, bo import offline ładuje zasoby synchronicznie
Fonty muszą być osadzalnymi zasobami sfnt TrueType lub OpenType z ASCII nazwą rodziny Windows o długości co najwyżej 31 znaków; WOFF, kolekcje fontów, local(...), deskryptory zmiennych i listy źródeł dają diagnostyki
Przyjęte fonty są rejestrowane prywatnie w pamięci procesu na Windows i pozostają własnością dokumentu aż do jego zniszczenia, więc zwolnienie importera przed EndDoc nie unieważnia odroczonego osadzania fontów
Zasoby data: i wyniki wywołań zwrotnych współdzielą limity MaxResources, MaxResourceBytes i MaxTotalResourceBytes
MaxDecodedImageBytes domyślnie 128 MiB i niezależnie ogranicza zdekodowany cache obrazów do czterech bajtów na piksel; wymiary BMP i PNG są sprawdzane przed dekodowaniem, a każda przyjęta grafika przed jej zachowaniem
MaxDOMNodes, MaxCSSRules i MaxLayoutOperations niezależnie ograniczają parsowanie, konstrukcję kaskady i pracę układu
THPDFHTMLResourceEvent = procedure(
Sender: TObject;
const URI: WideString;
ResourceKind: THPDFHTMLResourceKind;
var Data: TBytes;
var ContentType: string;
var Handled: Boolean
) of object;
Statystyki
THPDFHTMLImportStatistics raportuje wersję profilu, parsowane węzły, reguły CSS, operacje układu, przerwy stron, tabele, kontrolki formularzy, żądania zasobów, zaakceptowane i odrzucone ładunki, zaakceptowane bajty zasobów, zmierzone linie tekstu, linie z podzielonymi wyrazami, diagnostyki oraz kontenery flex i grid
OnLineLayout odbiera zerowe indeksy strony i linii akapitu linii, początek, zmierzoną szerokość i wysokość, logiczny tekst, kierunek i flagę podziału wyrazów po faktycznym zapisaniu tekstu PDF
Każde wywołanie RenderHTML5 resetuje rekord statystyk, a naruszenia budżetu zgłaszają EHPDFHTMLImportBudget
Przykład
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;
Zobacz także: THPDFPage.TextOutHTML, Deklaratywne DOM układu, Obsługa AcroForm