Ga naar inhoud

Lay-out: kopteksten, voetteksten, kolommen, boekje, paginabeheer

De Layout-module bevat de paginameubilair-engines achter de Document-facade: kopteksten, voetteksten, meerkoloms-lay-out, boekjeoplegging met rugnieting en structurele paginabewerkingen. De module is klein en stabiel: zes klassen, allemaal @since 1.0.0.

Terminal window
composer require nextpdf/core:^3

Layout (src/Layout/, zes klassen, @since 1.0.0) is de engine-laag onder de HasLayout-concern. Applicatiecode roept facademethoden aan op Document; de trait routeert elke aanroep naar een van deze engines. Het manifest markeert de module met risiconiveau standard en stabiliteit internal, met alleen Core als afhankelijke. Gebruik de module via de facade en construeer de klassen niet rechtstreeks.

HeaderFooter rendert de terugkerende koptekst en voettekst. Voor elke band bewaart de engine de titel, beschrijving, het logo, lettertype, de marge en de kleurstatus. Op aanvraag genereert hij Portable Document Format (PDF)-operatoren voor de content-stream via renderHeader() en renderFooter(). De standaardvoettekst schrijft een rechts uitgelijnde tekenreeks "page / total". setHeaderCallback() en setFooterCallback() vervangen de standaard-lay-out door een door de aanroeper opgegeven closure. getHeaderContentHeight() rapporteert hoeveel verticale ruimte de koptekst inneemt, zodat de paginabody eronder kan beginnen. Wanneer het document in tagged-PDF-modus staat, onderdrukt HasPages stroomopwaarts de automatische koptekst, omdat koptekstinhoud buiten de structuurboom valt.

ColumnLayout beheert de stroom over meerdere kolommen. setEqualColumns(int $count, float $totalWidth, float $gap = 5) verdeelt de beschikbare breedte in gelijke kolommen. setColumnsArray() accepteert expliciete ColumnDefinition-posities en -breedtes. Gebruik selectColumn() om een kolom te kiezen, of nextColumn() om door te gaan naar de volgende. getCurrentColumnX() / getCurrentColumnWidth() geven de geometrie van de actieve kolom terug. Een ongeldig kolomaantal, een negatieve tussenruimte of een niet-positieve berekende kolombreedte leidt tot PageLayoutException.

BookletLayout ordent pagina’s opnieuw voor binding met rugnieting (middenvouw). reorderPages() vult de paginalijst aan tot een veelvoud van vier, omdat een boekjevel vier paginaposities bevat, en legt vervolgens de pagina’s van buiten naar binnen op zodat de gevouwen, geniete vellen op volgorde kunnen worden gelezen. getMarginAdjustments() geeft de binnenmarges (rug) en buitenmarges (rand) voor elke zijde op een gegeven positie terug. getSheetCount() rapporteert hoeveel dubbelzijdige vellen een paginaaantal nodig heeft. Het opnieuw ordenen wijzigt alleen de plaatsing van de inhoud. De onderliggende PDF-paginavolgorde blijft lineair, in overeenstemming met de paginaboom, die de ordening van de pagina’s in het document bepaalt (ISO 32000-2 §7.7).

PageManager biedt structurele paginabewerkingen los van het renderen van inhoud. movePage(), copyPage() en deletePage() bewerken een PageData-array via referentie. Paginagebieden (addPageRegion(), isInRegion(), getRegionOffset()) definiëren zones zonder schrijftoegang. Paginagroepen (startPageGroup(), getGroupPageNo()) ondersteunen paginanummering per sectie. PageRegion en ColumnDefinition zijn de twee waardedragers die deze engines gebruiken. De Writer-module serialiseert de resulterende pagina’s in een paginaboom waarvan de Kids-entry een array met indirecte referenties naar de directe kinderen van een knooppunt in de paginaboom is (ISO 32000-2 §7.7.3.2).

SymboolSoortStabiliteitSinds
HeaderFooter::setHeaderData(string, string, string, float): selfmethodestabiel1.0.0
HeaderFooter::setHeaderFont(string, float): self / setHeaderMargin(float): selfmethodestabiel1.0.0
HeaderFooter::setFooterFont(string, float): self / setFooterMargin(float): selfmethodestabiel1.0.0
HeaderFooter::setHeaderCallback(Closure): self / setFooterCallback(Closure): selfmethodestabiel1.0.0
HeaderFooter::getHeaderContentHeight(): floatmethodestabiel1.0.0
HeaderFooter::renderHeader(float, float, float, float, int, int): stringmethodestabiel1.0.0
HeaderFooter::renderFooter(float, float, float, float, int, int, string): stringmethodestabiel1.0.0
ColumnLayout::setEqualColumns(int, float, float): selfmethodestabiel1.0.0
ColumnLayout::setColumnsArray(array): self / resetColumns(): selfmethodestabiel1.0.0
ColumnLayout::selectColumn(int): self / nextColumn(): boolmethodestabiel1.0.0
ColumnLayout::getCurrentColumnX(float): float / getCurrentColumnWidth(float): floatmethodestabiel1.0.0
BookletLayout::setBooklet(bool, float, float): voidmethodestabiel1.0.0
BookletLayout::reorderPages(array): arraymethodestabiel1.0.0
BookletLayout::getMarginAdjustments(int): array{left: float, right: float}methodestabiel1.0.0
BookletLayout::getSheetCount(int): intmethodestabiel1.0.0
PageManager::movePage(int, int, array): void / copyPage(int, array): void / deletePage(int, array): voidmethodestabiel1.0.0
PageManager::addPageRegion(float, float, float, float): void / isInRegion(float, float): boolmethodestabiel1.0.0
PageManager::getRegionOffset(float, float, float, float): floatmethodestabiel1.0.0
PageManager::startPageGroup(): void / getGroupPageNo(int): intmethodestabiel1.0.0
PageRegion / ColumnDefinitionwaardedragerstabiel1.0.0
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Header and Footer');
$doc->setHeaderData(
title: 'NextPDF Example',
description: 'Header and Footer Demonstration',
);
$doc->setHeaderFont('helvetica', 10);
$doc->setHeaderMargin(5);
$doc->setFooterFont('helvetica', 8);
$doc->setFooterMargin(10);
$doc->addPage();
$doc->setFont('helvetica', 'B', 16);
$doc->cell(0, 12, 'Document with Header and Footer', newLine: true);
$doc->save(__DIR__ . '/output/13-header-footer.pdf');

Bron: examples/13-header-footer.php. De koptekst wordt bij elke aanroep van addPage() gerenderd; de voettekst wanneer de pagina wordt geflusht.

Een voettekst-callback bepaalt de tekst van het paginanummer en de kolom-engine stuurt een body met twee kolommen aan. Beide engines zijn bereikbaar via de facade.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Two-Column Report');
$doc->setFooterCallback(static function (Document $d): void {
$d->setFont('helvetica', '', 8);
$d->text(180.0, 285.0, 'Page ' . ($d->getPage() + 1));
});
$doc->addPage();
$doc->setEqualColumns(2, gap: 8);
$doc->selectColumn(0);
$doc->setFont('helvetica', '', 10);
$doc->multiCell(0, 6, 'Left column flows here.');
$doc->selectColumn(1);
$doc->multiCell(0, 6, 'Right column flows here.');
$doc->save(__DIR__ . '/output/two-column-report.pdf');

Bron: patroon uit examples/13-header-footer.php.

  • setEqualColumns() weigert een kolomaantal kleiner dan 1, een negatieve tussenruimte of een lay-out waarvan de berekende kolombreedte niet positief is. De methode veroorzaakt PageLayoutException in plaats van een gedegradeerde lay-out terug te geven.
  • selectColumn() negeert een index buiten bereik en behoudt de huidige kolom; de methode werpt nooit een uitzondering bij een ongeldige index. nextColumn() geeft false terug wanneer de kolom al de laatste is.
  • BookletLayout::reorderPages() vult aan tot een veelvoud van vier met lege pagina’s waarvan de afmetingen zijn gekloond van de laatste pagina. Een lege paginalijst geeft een lege array terug. Het opnieuw ordenen beïnvloedt alleen de plaatsing; de indexen van movePage() verwijzen nog steeds naar de logische volgorde.
  • PageManager::movePage(), copyPage() en deletePage() doen stilzwijgend niets wanneer een index buiten bereik ligt; ze valideren met isset() en keren terug zonder de array te wijzigen. Controleer de index zelf wanneer een ontbrekende pagina een fout van de aanroeper is.
  • getHeaderContentHeight() geeft 0.0 terug wanneer de koptekst is uitgeschakeld of geen titel en geen beschrijving heeft. De paginabody begint dan bij de bovenmarge.
  • In tagged-PDF-modus wordt de automatische koptekst stroomopwaarts onderdrukt. Bouw een structuurbewuste lay-out voor toegankelijke documenten.

Het renderen van de koptekst en voettekst voegt operatoren toe aan de buffer van de actieve pagina in O(meubilairinhoud); de kosten schalen mee met de geschreven titel, beschrijving en scheidingslijn, niet met de documentgrootte. De kolomberekening is O(1) per aanroep. BookletLayout::reorderPages() is O(n) in het paginaaantal, met een eenmalige aanvulpas; de oplegginglus verwerkt elke aangevulde positie één keer. De gebiedstests van PageManager zijn O(gebieden) per punt, en paginabewerkingen zijn O(n) array-splices. Deze engines houden geen status per pagina bij over het hele document, dus ze veroorzaken geen geheugengroei bij lange documenten. De grootste geheugenkost is de opgebouwde content-stream, die wordt behandeld in het concept streaming en geheugen. De latentie- en geheugenbudgetgate van de HyperText Markup Language (HTML)-pijplijn is gedocumenteerd in PERFORMANCE-BUDGETS; die geldt alleen voor het HTML-renderpad en legt geen rechtstreekse gate op aan deze lay-out-engines. De performance_budget van 1500 ms / 64 MB is de canvas-envelop voor het snel-aan-de-slag-voorbeeld, niet een contract per aanroep.

Deze engines verwerken door de aanroeper opgegeven tekenreeksen en een door de aanroeper opgegeven logopad. Het logopad gaat via de afbeeldings-engine, die het bestand valideert voordat het wordt ingesloten. renderHeader() en renderFooter() escapen de titel-, beschrijvings- en paginanummertekst via de gecentraliseerde PDF-string-escaper voordat die tekst de content-stream bereikt, zodat aanroepertekst niet uit de grammatica van de letterlijke tekenreeks kan breken. Een koptekst- of voettekst-callback voert aanroepercode uit met hetzelfde vertrouwen als de rest van het document; ga dienovereenkomstig om met externe gegevens die de callback leest. Paginabewerkingen van PageManager verplaatsen referenties naar bestaande PageData; ze parseren geen niet-vertrouwde bytes.

BeweringStandaardClausuleBewijs
Het opnieuw ordenen van pagina’s voor boekjeuitvoer wijzigt alleen de plaatsing; de paginaboom bepaalt nog steeds de lineaire ordening van de pagina’s in het document.ISO 32000-2§7.7
De Kids-entry van het geserialiseerde knooppunt in de paginaboom is een array van indirecte referenties naar de directe kinderen van dat knooppunt.ISO 32000-2§7.7.3.2

De tabel parafraseert elke clausule en houdt de glossariumtermen vast; er wordt geen normatieve tekst weergegeven.