Pro Edition
Flow Layout — Ausführliche Referenz
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Diese Seite ist die ausführliche Referenz für das Flow-Layout-Modul von Pro. Sie behandelt die Platzierungs-Engine, das Elementmodell, die Seitenumbruchstrategien, deren Verhaltensverträge und deren Fehlermodi. StreamingLayoutEngine durchläuft eine Liste von FlowElement-Werten der Reihe nach. Sie weist jedem Wert einen nullbasierten Seitenindex und eine Position innerhalb einer LayoutRegion zu. Das Ergebnis ist ein LayoutResult aus unveränderlichen PlacedElement-Datensätzen. Das Modul berechnet ausschließlich die Platzierung; es rendert nichts und führt keine I/O aus.
Verfügbarkeit & Lizenzierung
Abschnitt betitelt „Verfügbarkeit & Lizenzierung“Diese Fähigkeit wird mit NextPDF Pro (nextpdf/pro) ausgeliefert und aktiviert sich mit einer Lizenzhülle der Pro-Stufe. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Fähigkeit nicht. Editionen vergleichen und eine Lizenz erwerben.
Es gibt kein Lizenzkennzeichen pro Feature. Dies ist eine Fähigkeit der Pro-Edition.
Öffentliche API-Oberfläche
Abschnitt betitelt „Öffentliche API-Oberfläche“Alle Symbole befinden sich im Namensraum NextPDF\Pro\FlowLayout. Alle Wertobjekte sind final und unveränderlich.
| Symbol | Parameter | Standardverhalten | Rückgabe | Wirft oder scheitert mit | Hinweise |
|---|---|---|---|---|---|
StreamingLayoutEngine::__construct | LayoutRegion $region, PageBreakStrategy $strategy = PageBreakStrategy::Greedy | Bindet einen Inhaltsbereich pro Seite an eine Umbruchstrategie | StreamingLayoutEngine | — | Die Strategie ist standardmäßig Greedy. |
StreamingLayoutEngine::layout | list<FlowElement> $elements | Einzelner Vorwärtsdurchlauf; sequenzielle Platzierung mit strategiegesteuerten Seitenumbrüchen | LayoutResult | Wirft nie | Eine leere Liste ergibt eine leere Seite. |
StreamingLayoutEngine::withStrategy | PageBreakStrategy $strategy | Leitet eine neue Engine mit derselben Region ab | self | — | Der Empfänger bleibt unverändert. |
StreamingLayoutEngine::withRegion | LayoutRegion $region | Leitet eine neue Engine mit derselben Strategie ab | self | — | Der Empfänger bleibt unverändert. |
FlowElement::__construct | FlowElementType $type, string $content, float $widthPt = 0, float $heightPt = 0, float $marginTopPt = 0, float $marginBottomPt = 0, bool $keepWithNext = false | Unveränderliches Element-Wertobjekt | FlowElement | — | Einziger Konstruktionsweg für Table-Elemente. |
FlowElement::text | string $content, float $height | Textelement mit einer vom Aufrufer gemessenen Höhe | self (statisch) | — | Breite 0 löst sich bei der Platzierung zur Regionsbreite auf. |
FlowElement::image | string $path, float $width, float $height | Bildelement; content trägt den Pfad | self (statisch) | — | Die Engine öffnet die Datei nie. |
FlowElement::spacer | float $height | Vertikaler Leerraum mit leerem Inhalt | self (statisch) | — | — |
FlowElement::pageBreak | — | Expliziter Umbruchmarker | self (statisch) | — | Erzeugt kein PlacedElement. |
FlowElement::totalHeight | — | Höhe plus oberer und unterer Rand | float | — | Alle Passprüfungen verwenden diesen Wert. |
FlowElementType | Enum-Fälle Text, Image, Table, Spacer, PageBreak | String-basiert: text, image, table, spacer, page_break | — | — | — |
FlowElementType::isBreakable | — | Text und Table liefern true; andere liefern false | bool | — | Nur Klassifizierung; siehe den Vertrag zur atomaren Platzierung unten. |
LayoutRegion::__construct | float $x, float $y, float $width, float $height | Inhaltsbox mit Ursprung oben links, gemessen in Punkten | LayoutRegion | — | Keine Validierung; Werte werden wie angegeben übernommen. |
LayoutRegion::contains | float $px, float $py | Grenzeinschließender Punkt-in-Region-Test | bool | — | — |
LayoutRegion::remainingHeight | float $currentY | Regionshöhe minus des verbrauchten vertikalen Versatzes | float | — | Null oder negativ, sobald der Cursor übergelaufen ist. |
LayoutResult::__construct | list<PlacedElement> $placements, int $pageCount, float $totalHeightPt | Unveränderliches Layout-Ergebnis | LayoutResult | — | — |
LayoutResult::placementsOnPage | int $pageIndex | Filtert Platzierungen nach nullbasiertem Seitenindex | list<PlacedElement> | — | Die zurückgegebene Liste wird neu indiziert. |
LayoutResult::isEmpty | — | True, wenn keine Elemente platziert wurden | bool | — | True bei leerer und nur aus Umbrüchen bestehender Eingabe. |
PageBreakStrategy | Enum-Fälle Greedy, AvoidOrphans, KeepTogether | String-basiert: greedy, avoid_orphans, keep_together | — | — | — |
PageBreakStrategy::label | — | Menschenlesbares Strategie-Label | string | — | — |
PlacedElement::__construct | FlowElement $element, int $pageIndex, float $x, float $y, float $width, float $height | Unveränderlicher Platzierungsdatensatz | PlacedElement | — | Koordinaten in Punkten, Ursprung oben links. |
public function layout(array $elements): LayoutResultpublic function withStrategy(PageBreakStrategy $strategy): selfpublic function withRegion(LayoutRegion $region): selfpublic static function text(string $content, float $height): selfpublic static function image(string $path, float $width, float $height): selfpublic static function spacer(float $height): selfpublic static function pageBreak(): selfVerhaltensvertrag
Abschnitt betitelt „Verhaltensvertrag“StreamingLayoutEngine::layout() führt einen einzelnen Vorwärtsdurchlauf über die Eingabeliste aus. Für jedes Element prüft die Engine den Pass, bricht die Seite bei Bedarf um und zeichnet dann ein PlacedElement auf. Eine leere Eingabeliste liefert ein LayoutResult ohne Platzierungen, mit einer Seitenzahl von 1 und einer Gesamthöhe von 0.
Die Platzierungsgeometrie ist deterministisch:
xist die linke Kante der Region.yist die aktuelle Cursorposition plus der obere Rand des Elements.widthist derwidthPtdes Elements, sofern positiv, andernfalls die Regionsbreite.heightist derheightPtdes Elements, exakt wie angegeben.
Nach jeder Platzierung rückt der Cursor um totalHeight() vor, einschließlich der Ränder. Derselbe Betrag summiert sich in LayoutResult::totalHeightPt.
Seitenumbruchregeln, in Auswertungsreihenfolge:
- Ein explizites
PageBreak-Element erhöht den Seitenindex und setzt den Cursor auf den oberen Rand der Region zurück. Es erzeugt keine Platzierung und trägt nichts zur Gesamthöhe bei. - Wenn der
totalHeight()eines Elements die verbleibende Höhe überschreitet, bricht die Engine um — es sei denn, der Cursor befindet sich bereits am oberen Rand der Seite. Greedyfügt keine weitere Bedingung hinzu: passende Elemente werden stets platziert.AvoidOrphansbricht vor einem passenden Element um, wenn der nach der Platzierung verbleibende Raum positiv, aber kleiner als die Hälfte der eigenen benötigten Höhe des Elements wäre. Die eigene Höhe des Elements ist die Bezugseinheit, mit einem festen Divisor von zwei; keine Schriftmetrik ist beteiligt. Am oberen Rand einer Seite bricht sie nie um.KeepTogetherbricht vor einem passenden Element um, wenn dessenkeepWithNext-Flag gesetzt ist, ein nächstes Element existiert, der Cursor nicht am oberen Rand der Seite steht und der kombiniertetotalHeight()beider Elemente den verbleibenden Raum überschreitet. Das Flag am letzten Element hat keine Wirkung.
Atomare Platzierung: Die Engine platziert jedes Element als Einheit. Sie teilt Elementinhalte niemals über Seiten hinweg auf. FlowElementType::isBreakable() klassifiziert, welche Typen ein Aufrufer in kleinere Elemente vorab aufteilen darf; die Engine selbst zieht diese Angabe nicht heran.
Zustandslosigkeit und Determinismus: Die Engine hält nur ihre Region und Strategie. layout() teilt keinen Zustand zwischen Aufrufen, und identische Eingaben erzeugen identische Ergebnisse. withStrategy() und withRegion() liefern neue Engines und verändern den Empfänger nie.
Randfälle & Fehlermodi
Abschnitt betitelt „Randfälle & Fehlermodi“- Keine Methode in diesem Modul wirft. Es gibt keine Ausnahmehierarchie zum Abfangen.
- Konstruktoren validieren nichts. Negative oder Null-Regionsabmessungen, negative Elementhöhen und negative Ränder werden akzeptiert und durchlaufen die Arithmetik unverändert.
- Ein Element, das höher als die Region ist, wird dennoch platziert. Am oberen Rand einer Seite wird es dort platziert und läuft über; andernorts bricht die Engine zuerst um, und es läuft über eine frische Seite über. Das nächste Element löst dann stets einen Umbruch aus, sodass der Überlauf auf eine Seite beschränkt bleibt.
- Ein führendes
PageBreakplatziert das erste Inhaltselement auf Seitenindex 1 und ergibt eine Seitenzahl von mindestens 2. - Aufeinanderfolgende
PageBreak-Elemente rücken jeweils den Seitenzähler vor und erzeugen leere Seiten. Ein abschließendes hinterlässt eine letzte leere Seite inpageCount. - Keep-together hält nur, wenn beide gepaarten Elemente gemeinsam auf eine Seite passen. Ein Paar, dessen kombinierte Höhe eine volle Seite überschreitet, wird dennoch aufgeteilt.
- Ein nicht-positiver
widthPtlöst sich zur Regionsbreite auf; die Ersetzungsprüfung ist strikt größer als null. remainingHeight()kann null oder einen negativen Wert liefern, sobald der Cursor übergelaufen ist.contains()behandelt die Regionsgrenze als innenliegend.placementsOnPage()mit einem Index außerhalb des Bereichs liefert eine leere Liste.- Dieses Modul führt keine kryptografischen Operationen aus und definiert kein FIPS-spezifisches Verhalten.
Konformität
Abschnitt betitelt „Konformität“Flow Layout implementiert von NextPDF definiertes Platzierungsverhalten. Es zielt auf keinen externen Layout- oder Typografiestandard ab, weshalb diese Seite keine normative Zitationstabelle führt. Die Seitenumbruchstrategien sind NextPDF-Semantik; sie sind keine Implementierungen von CSS-Fragmentierungseigenschaften oder eines XSL-FO-Keep-Modells. Alle Abmessungen sind in Punkten ausgedrückt, passend zu den Einheiten, die der Core-Writer konsumiert.
Diese Aussagen beschreiben ausschließlich die Fähigkeit. NextPDF hält keine Konformitätszertifizierung, und es wird kein Zertifizierungsanspruch erhoben oder impliziert.
Entwicklungshinweise
Abschnitt betitelt „Entwicklungshinweise“- Messen Sie Inhalte vorgelagert. Die Engine konsumiert vom Aufrufer bereitgestellte Höhen; sie hat keine Schriftmetriken und führt keine Textmessung aus.
- Teilen Sie langen Text- oder Tabelleninhalt vor dem Layout in mehrere Elemente vorab auf. Verwenden Sie
isBreakable(), um zu entscheiden, welche Typen ein Chunker aufteilen darf. - Verwenden Sie eine Engine pro Seitengeometrie wieder. Leiten Sie Varianten kostengünstig mit
withStrategy()undwithRegion()ab. - Gruppieren Sie die Ausgabe pro Seite mit
placementsOnPage(), wenn Sie Seite für Seite rendern. - Das Layout ist ein einzelner Durchlauf, linear in der Elementanzahl, und behält keinen Dokumentbaum. Die Ergebnisse sind deterministisch, was sich für Golden-File-Tests eignet.
- Verwenden Sie für das HTML-zu-PDF-Rendering stattdessen die Core-HTML-Pipeline; dieses Modul ist keine HTML- oder CSS-Engine.
Publikationsgrenze
Abschnitt betitelt „Publikationsgrenze“Diese Seite dokumentiert ausschließlich extern beobachtbares Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namensraumpfade, Hilfsklassen, Mechanismustabellen, Runbook-Dateinamen und Ticket-Präfixe sind außerhalb des Geltungsbereichs.