Ga naar inhoud

Content: tekstueel + gestructureerd inhoudsmodel

De Content-module bouwt tekstweergaveoperators, tekststatusoperators, tekstschaduwen, JavaScript op documentniveau en property-dictionaries voor gemarkeerde inhoud. De module zit tussen de lay-out en de contentstream.

Terminal window
composer require nextpdf/core:^3

Content levert de primitieven waarmee opgeloste tekst wordt omgezet naar operators van het Portable Document Format (PDF). TextRenderer is de centrale component. Hij bouwt de tekstweergaveoperator voor een string en de tekststatusoperators die daaraan voorafgaan. Volgens International Organization for Standardization (ISO) 32000-2 §9 tekent de Tj-operator de glyphs van een string met het huidige lettertype en de grafische parameters voor tekst. TextRenderer kiest op basis van de actieve TypographyMode tussen een enkele weergaveoperator en een gepositioneerde TJ-array. Hij past kerning-aanpassingen toe als de modus TJ-arrays gebruikt.

De tekststatus wordt als volledige set gemodelleerd. setTextRenderingMode() accepteert een TextRenderingMode-enum. De acht cases komen een-op-een overeen met de tekstweergavemodi van ISO 32000-2: fill, stroke, fill-then-stroke, invisible en de vier clip-varianten (Tabel 104). De renderer regelt ook de lijndikte, tekenafstand, woordafstand, horizontale uitrekking, text rise, rechts-naar-linksrichting en een optionele Hyphenator. Een aanroep van buildTextStateOperators() geeft de opgebouwde status als één operatorblok uit.

TextShadow is een value object: kleur, X- en Y-offsets in gebruikerseenheden en dekking. De renderer gebruikt het om een tweede tekenpas met de offset uit te geven. De standaard-offsets zijn subtiel: 0,5/−0,5 met een dekking van 0,5, vergelijkbaar met een zachte schaduw in Cascading Style Sheets (CSS).

JavaScriptManager beheert scripting op documentniveau. includeJs() registreert een documentscript. addJsObject() registreert een benoemd scriptobject. writeJavaScript() / writeOpenAction() serialiseren scripts naar de catalog en naar de OpenAction. De manager valideert en PDF-string-encodeert elke scriptinhoud vóór uitvoer.

PropertiesRegistry is de property-store voor gemarkeerde inhoud. register() geeft een stabiele tag-index voor een property-dictionary terug. registerOcg() / registerOcgs() koppelen optional-content groups (OCGs) aan objectnummers. writeProperties() serialiseert het register naar de resource-dictionary van de pagina. De ContentStream-module leest deze gegevens wanneer deze een gemarkeerde reeks met een property-lijst opent.

Deze module bevat ook twee beelddecoders, omdat ze PDF-eigen pass-through-formaten verwerken. JBig2Loader en JpxLoader ontleden de segmentstructuren van JBIG2 en JPEG 2000 en geven ImageData terug zonder pixels te rasteren. De gecodeerde bytes gaan ongewijzigd naar de viewer. Wanneer een JBIG2-bron een afzonderlijk globals-segment bevat, bedt JBig2Loader dit in via een /JBIG2Globals-streamreferentie op de afbeeldings-XObject; de in-stream/in-line-vorm blijft net als voorheen volledig round-trippen. Dit is uitsluitend structurele bedrading: de globals-bytes worden zonder rastering doorgegeven, niet gedecodeerd.

KlasseBelangrijkste methodenRol
TextRendererbuildTextShowOperator(), buildTextStateOperators(), setTextRenderingMode(), setTextStrokeWidth(), setTextShadow(), setFontSpacing(), setWordSpacing(), setFontStretching(), setTextRise(), setRTL(), setHyphenation()Tekstweergave- + tekststatusoperatorbouwer
TextRenderingMode (enum)Fill, Stroke, FillStroke, Invisible, FillClip, StrokeClip, FillStrokeClip, ClipTekstweergavemodi van ISO 32000-2
TextShadow__construct(Color, offsetX, offsetY, opacity)Value object voor tekenpas met offset
JavaScriptManagerincludeJs(), addJsObject(), hasJavaScript(), writeJavaScript(), writeOpenAction()Catalog-bedrading voor JavaScript op documentniveau
PropertiesRegistryregister(), getTagIndex(), registerOcg(), registerOcgs(), getAll(), writeProperties()Property-store voor gemarkeerde inhoud + OCG
JBig2Loaderload(), loadFromString(), parseSegments()JBIG2 pass-through-decoder
JpxLoaderload(), loadFromString(), parseBoxes()JPEG 2000 pass-through-decoder

Voer composer docs:generate-api-php -- --module=Content uit voor de volledige PHPDoc-tabel.

Bron: examples/28-text-rendering.php.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Content\TextRenderer;
use NextPDF\Content\TextRenderingMode;
$renderer = new TextRenderer();
$renderer
->setTextRenderingMode(TextRenderingMode::FillStroke)
->setTextStrokeWidth(0.3)
->setWordSpacing(0.5);
$stateOps = $renderer->buildTextStateOperators();

Dit voegt een zachte schaduw en een hyphenator toe en bouwt daarna de weergaveoperator met een door de aanroeper aangeleverde escape-functie, de canonieke PdfStringEscaper-grens uit architecture decision record ADR-015.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Content\TextRenderer;
use NextPDF\Content\TextShadow;
use NextPDF\Graphics\Color;
use NextPDF\Support\PdfStringEscaper;
$renderer = new TextRenderer();
$renderer
->setTextShadow(new TextShadow(Color::rgb(0, 0, 0), 0.4, -0.4, 0.45))
->setRTL(false);
$showOp = $renderer->buildTextShowOperator(
text: 'Quarterly report',
fontKey: 'F1',
metrics: $fontMetrics,
escapeSegment: static fn (string $s): string => PdfStringEscaper::escapeLiteral($s),
);
$pageContent = $renderer->buildTextStateOperators() . $showOp;
  • buildTextShowOperator() geeft een lege string terug bij lege invoer. Geef geen lege Tj uit; bouw stroomopwaarts een vangnet in als je lay-out lege runs kan produceren.
  • De escape-callback is verplicht en zorgt voor stringveiligheid. Geef de canonieke PdfStringEscaper::escapeLiteral() uit ADR-015 door. Een onvolledige escaper produceert een syntactisch ongeldige literal string.
  • Bij een oorsprong linksboven loopt een negatieve TextShadow::offsetY omlaag. Een positieve Y duwt de schaduw omhoog, wat zelden de bedoeling is.
  • JavaScriptManager valideert de scriptinvoer. Ongeldige scriptinhoud wordt bij registratie geweigerd en niet pas stilzwijgend genegeerd op het moment van wegschrijven.
  • JBig2Loader en JpxLoader rasteren nooit. Ze valideren de gecodeerde bytes en geven ze door. Een beschadigd segment levert een parsefout op, geen lege afbeelding.
  • PropertiesRegistry::register() is idempotent per dictionary; identieke property-dictionaries hergebruiken één tag-index.

Operatorconstructie is O(n) in de stringlengte, plus een O(n)-kerningpas als de typografiemodus TJ-arrays gebruikt. Er zijn hier geen lay-out- of shapingkosten; dat werk blijft in de modules Typography en Layout. JavaScript- en property-serialisatie zijn O(entries). De pass-through-beeldladers gebruiken O(bytes)-parsing zonder decodeerkosten. Dat is hun belangrijkste voordeel voor workloads met gescande documenten. Het performance_budget voor de referentieworkload is 1500 ms wall en 64 MB peak.

JavaScriptManager accepteert scriptinhoud die uit niet-vertrouwde templates kan komen. Hij valideert en PDF-string-encodeert elke inhoud, maar document-JavaScript blijft een oppervlak voor active content. Schakel het uit voor niet-vertrouwde uitvoer, of verwijder het met het sanitisatiepad dat wordt beschreven in /modules/core/security/. JBig2Loader en JpxLoader parseren niet-vertrouwde segmentstructuren: begrens de invoergrootte en de parsetijd, en voer extractie uit in een afgeschermde worker wanneer de bron door gebruikers wordt aangeleverd. De text-escape-grens is de door de aanroeper geleverde callback. Geef altijd de canonieke escaper door, zodat stuurbytes niet uit een literal string kunnen ontsnappen.

De module geeft tekstweergave- en tekststatusoperators uit die consistent zijn met het tekstmodel van ISO 32000-2 §9. Dit omvat de semantiek van de Tj-operator en de weergavemodi uit Tabel 104 die door de TextRenderingMode-enum worden weerspiegeld. Dit zijn implementatiefeiten: src/Content/TextRenderer.php en de TextRenderingMode-enum produceren de operatorvormen, en tests/Unit/Content/TextRenderer*, JavaScriptManagerIsoTest en PropertiesRegistryTest dekken ze af. Daarmee wordt geen end-to-end PDF 2.0-conformiteit geclaimd. Het string-escape-contract volgt ADR-015 en ISO 32000-2 §7.3.4.2. De pass-through-paden van JBIG2 en JPEG 2000 behouden de gecodeerde streams ongewijzigd. Een afzonderlijk JBIG2-globals-segment wordt ingebed als een /JBIG2Globals-streamreferentie op de afbeeldings-XObject; dit wordt geverifieerd als structurele bedrading, niet als een claim over decodeergetrouwheid. Conformiteit op documentniveau wordt gevalideerd door de oracle- en golden-suites in /modules/core/conformance/.