Content: textuelles + strukturiertes Inhaltsmodell
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Das Content-Modul erzeugt Textanzeige-Operatoren, Textzustands-Operatoren, Textschatten, Dokument-JavaScript und Eigenschafts-Dictionarys für markierte Inhalte. Es bildet die Schicht zwischen Layout und Content-Stream.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Content enthält die Primitive, mit denen aufgelöster Text in PDF-Operatoren überführt wird. TextRenderer ist die zentrale Komponente. Er erzeugt den Textanzeige-Operator für einen String und die vorangestellten Textzustands-Operatoren. Der Operator Tj zeichnet die Glyphen eines Strings mit der aktuellen Schrift und den übrigen textbezogenen Grafikparametern — ISO 32000-2 §9. TextRenderer wählt anhand des aktiven TypographyMode zwischen einem einzelnen Anzeige-Operator und einem positionierten TJ-Array. Er wendet Kerning-Anpassungen an, wenn der Modus TJ-Arrays verwendet.
Der Textzustand ist vollständig modelliert. setTextRenderingMode() nimmt ein TextRenderingMode-Enum entgegen. Seine acht Fälle entsprechen eins zu eins den Textrendering-Modi nach ISO 32000-2: Fill, Stroke, Fill-then-stroke, Invisible und die vier Clip-Varianten (Tabelle 104). Der Renderer steuert außerdem Strichbreite, Zeichen- und Wortabstand, horizontale Streckung, Textversatz nach oben, Rechts-nach-links-Richtung und einen optionalen Hyphenator. Ein Aufruf von buildTextStateOperators() gibt den akkumulierten Zustand als einzelnen Operatorblock aus.
TextShadow ist ein Value Object — es umfasst Farbe, X- und Y-Versatz in Benutzereinheiten sowie Deckkraft. Der Renderer nutzt es, um einen zweiten, versetzten Zeichendurchlauf auszugeben. Die Standardversätze liegen bei dezenten 0,5/−0,5 mit 0,5 Deckkraft und ergeben einen weichen Schatten im CSS-Stil.
JavaScriptManager verwaltet das Scripting auf Dokumentebene. includeJs() registriert ein Dokument-Skript. addJsObject() registriert ein benanntes Skript-Objekt. writeJavaScript() / writeOpenAction() serialisieren die Skripte in den Katalog und die OpenAction. Der Manager prüft jeden Skript-Körper und kodiert ihn vor der Ausgabe als PDF-String.
PropertiesRegistry ist der Eigenschaftsspeicher für markierte Inhalte. register() gibt für ein Eigenschafts-Dictionary einen stabilen Tag-Index zurück. registerOcg() / registerOcgs() binden optionale Inhaltsgruppen über die Objektnummer ein. writeProperties() serialisiert die Registry in das Ressourcen-Dictionary der Seite. Das sind die Daten, auf die das ContentStream-Modul verweist, wenn es eine markierte Sequenz mit einer Eigenschaftsliste öffnet.
Zwei Bild-Decoder liegen hier, weil es sich um PDF-native Pass-through-Formate handelt. JBig2Loader und JpxLoader parsen JBIG2- und JPEG-2000-Segmentstrukturen und geben ImageData zurück, ohne jemals Pixel zu rastern. Die kodierten Bytes werden unverändert an den Viewer weitergereicht. Enthält eine JBIG2-Quelle ein separates Globals-Segment, bettet JBig2Loader es über eine /JBIG2Globals-Stream-Referenz am Bild-XObject ein; die in-stream/in-line-Form bleibt beim Round-Trip unverändert. Das ist reine strukturelle Verdrahtung — die Globals-Bytes werden ohne Rasterung durchgereicht, nicht dekodiert.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“| Klasse | Wichtige Methoden | Rolle |
|---|---|---|
TextRenderer | buildTextShowOperator(), buildTextStateOperators(), setTextRenderingMode(), setTextStrokeWidth(), setTextShadow(), setFontSpacing(), setWordSpacing(), setFontStretching(), setTextRise(), setRTL(), setHyphenation() | Builder für Textanzeige- und Textzustands-Operatoren |
TextRenderingMode (Enum) | Fill, Stroke, FillStroke, Invisible, FillClip, StrokeClip, FillStrokeClip, Clip | ISO 32000-2 Textrendering-Modi |
TextShadow | __construct(Color, offsetX, offsetY, opacity) | Value Object für den versetzten Zeichendurchlauf |
JavaScriptManager | includeJs(), addJsObject(), hasJavaScript(), writeJavaScript(), writeOpenAction() | Verdrahtung von Dokument-JavaScript in den Katalog |
PropertiesRegistry | register(), getTagIndex(), registerOcg(), registerOcgs(), getAll(), writeProperties() | Eigenschaftsspeicher für markierte Inhalte und OCG |
JBig2Loader | load(), loadFromString(), parseSegments() | JBIG2-Pass-through-Decoder |
JpxLoader | load(), loadFromString(), parseBoxes() | JPEG-2000-Pass-through-Decoder |
Führen Sie composer docs:generate-api-php -- --module=Content aus, um die vollständige PHPDoc-Tabelle zu erzeugen.
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“Quelle: 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();Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Das Beispiel ergänzt einen weichen Schatten und einen Hyphenator und erstellt anschließend den Anzeige-Operator mit einer vom Aufrufer bereitgestellten Escape-Funktion (dem kanonischen PdfStringEscaper-Seam aus 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;Sonderfälle & Stolperfallen
Abschnitt betitelt „Sonderfälle & Stolperfallen“buildTextShowOperator()gibt bei leerer Eingabe einen leeren String zurück. Geben Sie keinen leerenTjaus — sichern Sie das vorgelagert ab, falls Ihr Layout leere Läufe erzeugen kann.- Der Escape-Callback ist verpflichtend und für die String-Sicherheit verantwortlich. Übergeben Sie den kanonischen
PdfStringEscaper::escapeLiteral()(ADR-015). Ein unvollständiger Escaper erzeugt einen syntaktisch defekten Literal-String. TextShadow::offsetYist bei einem Ursprung oben links nach unten negativ. Ein positiver Y-Wert verschiebt den Schatten nach oben, was selten beabsichtigt ist.JavaScriptManagerprüft die Skript-Eingabe. Ein ungültiger Skript-Körper wird bereits bei der Registrierung abgelehnt und nicht erst zum Schreibzeitpunkt stillschweigend verworfen.JBig2LoaderundJpxLoaderrastern niemals. Sie validieren die kodierten Bytes und reichen sie durch. Ein beschädigtes Segment wird als Parse-Fehler sichtbar, nicht als leeres Bild.PropertiesRegistry::register()ist pro Dictionary idempotent — identische Eigenschafts-Dictionarys teilen sich einen Tag-Index.
Performance
Abschnitt betitelt „Performance“Die Operatorkonstruktion ist O(n) in der String-Länge, zuzüglich eines O(n)-Kerning-Durchlaufs, wenn der Typografie-Modus TJ-Arrays verwendet. Dabei entstehen keine Layout- oder Shaping-Kosten — diese verbleiben in den Modulen Typography und Layout. Die Serialisierung von JavaScript und Eigenschaften ist O(Einträge). Die Pass-through-Bildlader parsen in O(Bytes) ohne Dekodierkosten. Das ist ihr wesentlicher Vorteil bei Arbeitslasten mit gescannten Dokumenten. Das performance_budget für die Referenz-Arbeitslast beträgt 1500 ms Wandzeit und 64 MB Spitzenverbrauch.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“JavaScriptManager akzeptiert Skript-Körper, die aus nicht vertrauenswürdigen Templates stammen können. Er prüft jeden Körper und kodiert ihn als PDF-String, aber Dokument-JavaScript bleibt eine Angriffsfläche für aktive Inhalte. Deaktivieren Sie es für nicht vertrauenswürdige Ausgaben, oder entfernen Sie es über den Bereinigungspfad, der unter /modules/core/security/ beschrieben ist. JBig2Loader und JpxLoader parsen nicht vertrauenswürdige Segmentstrukturen: Begrenzen Sie Eingabegröße und Parse-Zeit, und führen Sie die Extraktion in einem eingeschränkten Worker aus, wenn die Quelle vom Benutzer stammt. Die Escape-Grenze für Text ist der vom Aufrufer bereitgestellte Callback. Übergeben Sie stets den kanonischen Escaper, damit Steuerbytes nicht aus einem Literal-String ausbrechen können.
Konformität
Abschnitt betitelt „Konformität“Das Modul gibt Textanzeige- und Textzustands-Operatoren aus, die mit dem Textmodell aus ISO 32000-2 §9 übereinstimmen. Dazu gehören die Semantik des Operators Tj und die Rendering-Modi aus Tabelle 104, die das TextRenderingMode-Enum spiegelt. Dies sind Implementierungsfakten: Die Operatorformen werden von src/Content/TextRenderer.php und dem TextRenderingMode-Enum erzeugt und von tests/Unit/Content/TextRenderer*, JavaScriptManagerIsoTest und PropertiesRegistryTest geprüft. Sie sichern keine Ende-zu-Ende-Konformität mit PDF 2.0 zu. Der String-Escape-Vertrag folgt ADR-015 und ISO 32000-2 §7.3.4.2. Die Pass-through-Pfade für JBIG2 und JPEG 2000 erhalten die kodierten Streams unverändert. Ein separates JBIG2-Globals-Segment wird als /JBIG2Globals-Stream-Referenz am Bild-XObject eingebettet — verifiziert als strukturelle Verdrahtung, nicht als Aussage zur Dekodiertreue. Die Validierung der Konformität auf Dokumentebene erfolgt durch die Oracle- und Golden-Suiten in /modules/core/conformance/.