Deklaratywne DOM układu
HPDFLayoutDOM buduje komponenty dokumentu wielokrotnego użytku na THPDFLayoutElement, MeasureLayoutElement, PlaceLayoutElement, posiadanych fragmentach przepełnienia i ImmediateFlushLayout
Kompozycja dokumentu i sekcji
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 posiada swoje sekcje, każda THPDFDOMSection posiada swoją treść, nagłówek, stopkę i styl, a każdy stos lub kontener posiada dołączone do niego komponenty
THPDFDOMRenderer.Render rozpoczyna i kończy dokument docelowy, tworzy nową stronę dla każdej nowej sekcji, powtarza elementy sekcji na stronach kontynuacji i zwraca statystyki strony, umieszczenia, podziału, elementów sekcji, struktury, treści oznaczonej, artefaktów i maksymalnej kontynuacji
Przed wywołaniem Render ustaw wszystkie opcje wyjścia, kompresji, zgodności, warstw i natychmiastowego opróżnienia THotPDF
GenerateStructure domyślnie wynosi True, więc renderer buduje również drzewo logicznej struktury bezpieczne względem kontynuacji i używa THPDFDOMDocument.Language, gdy cel nie ma języka
Komponenty
THPDFDOMTextopakowuje tekst Unicode, buforuje granice wierszy wg szerokości i dziedziczonych metryk tekstu oraz dzieli przez zakresy znaków źródłowych bez kopiowania tekstu źródłowegoTHPDFDOMSpacerrezerwuje pionową przestrzeń i może dzielić się między stronamiTHPDFDOMStackukłada posiadane dzieci pionowo z dziedziczonym wypełnieniem i odstępamiTHPDFDOMContainerdodaje stylowane ramkę wokół jednego posiadanego dziecka i przekazuje podziały kontynuacjiTHPDFDOMTablerozpoznaje ważone kolumny, rysuje stylowane wiersze i komórki oraz powtarza wiodące wiersze nagłówków na stronach kontynuacjiTHPDFDOMListtworzy numerowane lub nienumerowane elementy listy z komponentami etykiety i treściTHPDFDOMImageposiada sklonowaną grafikę, rozpoznaje jawne wymiary oraz zapewnia semantykę figury i kontrolę kompresji
Wszystkie komponenty wystawiają stabilne kontrakty Name, Path, Style, Clone, Measure, Draw i Split oraz nadpisania roli semantycznej, języka, tekstu alternatywnego, tekstu zastępczego, tekstu ekspansji i artefaktów
Przechodzenie treści najwyższego poziomu jest liniowe i nie klonuje komponentów; kontynuacje tekstu i tabel zachowują metadane zakresu lub wycinka wiersza zamiast kopiowania kompletnego drzewa treści
Dziedziczenie stylu
THPDFDOMStyle rozpoznaje nazwę czcionki, rozmiar, style, kolor tekstu, tło, obramowanie, wypełnienie, odstępy i wysokość wiersza przez swój łańcuch nadrzędny
Styl sekcji jest nadrzędnym dla jej treści i elementów sekcji, styl stosu lub kontenera jest nadrzędnym dla jego dzieci, a styl tabeli przepływa przez wiersze do komórek
Tylko jawnie przypisane wartości zastępują rodzica; Clear usuwa lokalne przypisania i łącze nadrzędne, podczas gdy Assign kopiuje lokalne przypisania bez kopiowania własności lub pochodzenia
Łańcuchy nadrzędne głębsze niż 64 poziomy są odrzucane jako cykliczne lub nieograniczone
Fabryki komponentów wielokrotnego użytku
THPDFDOMComponentFactory to funkcja anonimowa, która tworzy jedną instancję THPDFDOMComponent należącą do wywołującego na każde wywołanie
Document.RegisterComponent('notice',
function: THPDFDOMComponent
begin
Result := THPDFDOMContainer.Create(
THPDFDOMText.Create('Reusable notice'));
end);
Section.Body.Add(Document.CreateComponent('notice'));
Nazwy fabryk są bez uwzględniania wielkości liter i unikalne, każde wywołanie musi zwracać nową instancję komponentu, a otrzymujący kontener przejmuje własność po Add
Używaj SetHeaderClone, SetFooterClone lub Clone, gdy jeden zadeklarowany komponent musi być ponownie użyty w kilku miejscach własności
Tabele z powtarzanym nagłówkiem
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);
Wiersze nagłówków muszą być ciągłe i poprzedzać wiersze treści, pozytywne wagi kolumn dzielą dostępną szerokość, a wysokości wierszy to jawne wartości pozytywne
Gdy RepeatHeaders jest prawdziwe, podział wymaga miejsca dla wszystkich wiodących wierszy nagłówków i co najmniej jednego wiersza treści, zapobiegając stronom kontynuacji zawierającym tylko nagłówki
Granice paginacji i awarii
Renderer najpierw ponownie mierzy każdy komponent względem pozostałego prostokąta treści, przenosi niepodzielny minimalny fragment na świeżą stronę, gdy to możliwe, i deleguje każdy prawidłowy podział do PlaceLayoutElement
Element, który nie zmieści się na pustej stronie treści, zgłasza wyjątek ze swoją stabilną ścieżką elementu zamiast po cichu odrzucać treść
MaximumContinuationDepth domyślnie wynosi 100 000 i ogranicza źle uformowane komponenty, które wielokrotnie zwracają niepostępową kontynuację
Wymiary strony sekcji muszą być pozytywne, marginesy i odstępy elementów sekcji nie mogą być ujemne, a geometria nagłówka plus stopki musi pozostawiać pozytywny prostokąt treści
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());
Wygenerowany HPDFLayoutDOM.hpp eksportuje tę samą powierzchnię dokumentu, stylu, komponentu, tabeli, sekcji, renderera i statystyk