Pro edizione
Flow Layout — Riferimento approfondito
In sintesi
Sezione intitolata “In sintesi”Questa pagina è il riferimento approfondito del modulo Pro Flow Layout. Copre il motore di posizionamento, il modello degli elementi, le strategie di interruzione di pagina, i loro contratti di comportamento e le loro modalità di errore. StreamingLayoutEngine percorre in ordine un elenco di valori FlowElement. Assegna a ciascuno un indice di pagina a base zero e una posizione all’interno di una LayoutRegion. Il risultato è un LayoutResult di record PlacedElement immutabili. Il modulo calcola solo il posizionamento; non esegue alcun rendering e nessuna operazione di I/O.
Disponibilità e licenza
Sezione intitolata “Disponibilità e licenza”Questa funzionalità è distribuita in NextPDF Pro (nextpdf/pro) e si attiva con un envelope di licenza di livello Pro. Un deployment privo di tale titolo non carica le classi della funzionalità. Confronta le edizioni e ottieni una licenza.
Non esiste alcun flag di licenza per singola funzionalità. È una funzionalità dell’edizione Pro.
Superficie API pubblica
Sezione intitolata “Superficie API pubblica”Tutti i simboli risiedono nel namespace NextPDF\Pro\FlowLayout. Tutti i value object sono final e immutabili.
| Simbolo | Parametri | Comportamento predefinito | Restituisce | Solleva o fallisce con | Note |
|---|---|---|---|---|---|
StreamingLayoutEngine::__construct | LayoutRegion $region, PageBreakStrategy $strategy = PageBreakStrategy::Greedy | Vincola un’area di contenuto per pagina a una strategia di interruzione | StreamingLayoutEngine | — | La strategia predefinita è Greedy. |
StreamingLayoutEngine::layout | list<FlowElement> $elements | Singolo passaggio in avanti; posizionamento sequenziale con interruzioni di pagina guidate dalla strategia | LayoutResult | Non solleva mai | Un elenco vuoto produce una pagina vuota. |
StreamingLayoutEngine::withStrategy | PageBreakStrategy $strategy | Deriva un nuovo motore con la stessa regione | self | — | Il ricevente rimane invariato. |
StreamingLayoutEngine::withRegion | LayoutRegion $region | Deriva un nuovo motore con la stessa strategia | self | — | Il ricevente rimane invariato. |
FlowElement::__construct | FlowElementType $type, string $content, float $widthPt = 0, float $heightPt = 0, float $marginTopPt = 0, float $marginBottomPt = 0, bool $keepWithNext = false | Value object di elemento immutabile | FlowElement | — | Unico percorso di costruzione per gli elementi Table. |
FlowElement::text | string $content, float $height | Elemento di testo con altezza misurata dal chiamante | self (statico) | — | La larghezza 0 si risolve nella larghezza della regione al momento del posizionamento. |
FlowElement::image | string $path, float $width, float $height | Elemento immagine; content contiene il percorso | self (statico) | — | Il motore non apre mai il file. |
FlowElement::spacer | float $height | Spazio verticale con contenuto vuoto | self (statico) | — | — |
FlowElement::pageBreak | — | Marcatore di interruzione esplicito | self (statico) | — | Non emette alcun PlacedElement. |
FlowElement::totalHeight | — | Altezza più i margini superiore e inferiore | float | — | Tutti i controlli di adattamento usano questo valore. |
FlowElementType | casi enum Text, Image, Table, Spacer, PageBreak | Basata su stringhe: text, image, table, spacer, page_break | — | — | — |
FlowElementType::isBreakable | — | Text e Table restituiscono true; gli altri restituiscono false | bool | — | Solo classificazione; vedere il contratto di posizionamento atomico più avanti. |
LayoutRegion::__construct | float $x, float $y, float $width, float $height | Riquadro di contenuto con origine in alto a sinistra, misurato in punti | LayoutRegion | — | Nessuna validazione; i valori sono assunti così come forniti. |
LayoutRegion::contains | float $px, float $py | Test di appartenenza del punto alla regione, confini inclusi | bool | — | — |
LayoutRegion::remainingHeight | float $currentY | Altezza della regione meno l’offset verticale consumato | float | — | Zero o negativo una volta che il cursore ha ecceduto. |
LayoutResult::__construct | list<PlacedElement> $placements, int $pageCount, float $totalHeightPt | Esito del layout immutabile | LayoutResult | — | — |
LayoutResult::placementsOnPage | int $pageIndex | Filtra i posizionamenti per indice di pagina a base zero | list<PlacedElement> | — | L’elenco restituito è re-indicizzato. |
LayoutResult::isEmpty | — | True quando nessun elemento è stato posizionato | bool | — | True per input vuoto e composto da soli marcatori di interruzione. |
PageBreakStrategy | casi enum Greedy, AvoidOrphans, KeepTogether | Basata su stringhe: greedy, avoid_orphans, keep_together | — | — | — |
PageBreakStrategy::label | — | Etichetta leggibile della strategia | string | — | — |
PlacedElement::__construct | FlowElement $element, int $pageIndex, float $x, float $y, float $width, float $height | Record di posizionamento immutabile | PlacedElement | — | Le coordinate sono in punti, origine in alto a sinistra. |
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(): selfContratto di comportamento
Sezione intitolata “Contratto di comportamento”StreamingLayoutEngine::layout() esegue un singolo passaggio in avanti sull’elenco di input. Per ogni elemento verifica l’adattamento, interrompe la pagina quando necessario, quindi registra un PlacedElement. Un elenco di input vuoto restituisce un LayoutResult senza posizionamenti, con un conteggio di pagine pari a 1 e un’altezza totale pari a 0.
La geometria di posizionamento è deterministica:
xè il bordo sinistro della regione.yè la posizione corrente del cursore più il margine superiore dell’elemento.widthè il valorewidthPtdell’elemento quando è positivo, altrimenti la larghezza della regione.heightè il valoreheightPtdell’elemento, esattamente come fornito.
Dopo ogni posizionamento il cursore avanza di totalHeight(), margini inclusi. La stessa quantità si accumula in LayoutResult::totalHeightPt.
Regole di interruzione di pagina, in ordine di valutazione:
- Un elemento
PageBreakesplicito incrementa l’indice di pagina e reimposta il cursore alla sommità della regione. Non emette alcun posizionamento e non aggiunge nulla all’altezza totale. - Quando il valore
totalHeight()di un elemento supera l’altezza rimanente, il motore interrompe — a meno che il cursore non si trovi già alla sommità della pagina. Greedynon aggiunge alcuna condizione ulteriore: gli elementi che entrano vengono sempre posizionati.AvoidOrphansinterrompe prima di un elemento che entra quando lo spazio residuo dopo il posizionamento sarebbe positivo ma inferiore alla metà dell’altezza richiesta dall’elemento stesso. L’altezza dell’elemento stesso è l’unità di riferimento, con un divisore fisso pari a due; nessuna metrica di font è coinvolta. Non interrompe mai alla sommità di una pagina.KeepTogetherinterrompe prima di un elemento che entra quando il suo flagkeepWithNextè impostato, esiste un elemento successivo, il cursore non è alla sommità della pagina e il valore combinatototalHeight()di entrambi gli elementi supera lo spazio rimanente. Il flag sull’elemento finale non ha alcun effetto.
Posizionamento atomico: il motore posiziona ogni elemento come unità. Non spezza mai il contenuto di un elemento tra più pagine. FlowElementType::isBreakable() classifica quali tipi un chiamante può pre-suddividere in elementi più piccoli; il motore stesso non lo consulta.
Assenza di stato e determinismo: il motore mantiene solo la propria regione e strategia. layout() non condivide alcuno stato tra le chiamate e input identici producono risultati identici. withStrategy() e withRegion() restituiscono nuovi motori e non mutano mai il ricevente.
Casi limite e modalità di errore
Sezione intitolata “Casi limite e modalità di errore”- Nessun metodo di questo modulo solleva eccezioni. Non esiste alcuna gerarchia di eccezioni da intercettare.
- I costruttori non validano nulla. Dimensioni della regione negative o nulle, altezze di elemento negative e margini negativi sono accettati e attraversano l’aritmetica senza alterazioni.
- Un elemento più alto della regione viene comunque posizionato. Alla sommità di una pagina viene posizionato lì ed eccede; altrove il motore interrompe prima e l’elemento eccede una pagina nuova. L’elemento successivo attiva poi sempre un’interruzione, quindi l’eccedenza è confinata a una sola pagina.
- Un
PageBreakiniziale posiziona il primo elemento di contenuto sull’indice di pagina 1, dando un conteggio di pagine di almeno 2. - Elementi
PageBreakconsecutivi fanno avanzare ciascuno il contatore di pagine, producendo pagine vuote. Uno finale lascia un’ultima pagina vuota inpageCount. - Keep-together si applica solo quando entrambi gli elementi accoppiati entrano insieme in un’unica pagina. Una coppia la cui altezza combinata supera una pagina intera si spezza comunque.
- Un valore
widthPtnon positivo si risolve nella larghezza della regione; il controllo di sostituzione è strettamente maggiore di zero. remainingHeight()può restituire zero o un valore negativo una volta che il cursore ha ecceduto.contains()tratta il confine della regione come interno.placementsOnPage()con un indice fuori intervallo restituisce un elenco vuoto.- Questo modulo non esegue alcuna operazione crittografica e non definisce alcun comportamento specifico di FIPS.
Conformità
Sezione intitolata “Conformità”Flow Layout implementa il comportamento di posizionamento definito da NextPDF. Non punta ad alcuno standard esterno di layout o tipografia, pertanto questa pagina non riporta alcuna tabella di citazioni normative. Le strategie di interruzione di pagina sono semantiche NextPDF; non sono implementazioni delle proprietà di frammentazione CSS né di alcun modello keep XSL-FO. Tutte le dimensioni sono espresse in punti, corrispondenti alle unità che il writer Core consuma.
Queste affermazioni descrivono solo le funzionalità. NextPDF non detiene alcuna certificazione di conformità e nessuna dichiarazione di certificazione è resa o implicita.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Misurare il contenuto a monte. Il motore consuma le altezze fornite dal chiamante; non dispone di metriche di font e non esegue alcuna misurazione del testo.
- Pre-suddividere i contenuti lunghi di testo o tabella in più elementi prima del layout. Usare
isBreakable()per decidere quali tipi un suddivisore può spezzare. - Riutilizzare un unico motore per ogni geometria di pagina. Derivare le varianti in modo economico con
withStrategy()ewithRegion(). - Raggruppare l’output per pagina con
placementsOnPage()quando si esegue il rendering pagina per pagina. - Il layout è un singolo passaggio, lineare rispetto al numero di elementi, e non conserva alcun albero del documento. I risultati sono deterministici, il che si presta ai test con golden file.
- Per il rendering da HTML a PDF, usare invece la pipeline HTML di Core; questo modulo non è un motore HTML o CSS.
Confine di pubblicazione
Sezione intitolata “Confine di pubblicazione”Questa pagina documenta solo il comportamento osservabile esternamente e la superficie API pubblica supportata. I percorsi interni dei namespace, le classi helper, le tabelle dei meccanismi, i nomi dei file di runbook e i prefissi dei ticket sono fuori ambito.