Content: tekstowy i strukturalny model treści
W skrócie
Dział zatytułowany „W skrócie”Moduł Content buduje operatory wyświetlania tekstu, operatory stanu tekstu, cienie tekstu, kod JavaScript na poziomie dokumentu oraz słowniki właściwości treści oznaczonej. Działa między warstwą układu a strumieniem treści.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Content udostępnia prymitywy, które przekształcają rozwiązany tekst w operatory formatu Portable Document Format (PDF). TextRenderer jest centralnym komponentem. Buduje operator wyświetlania tekstu dla łańcucha znaków oraz poprzedzające go operatory stanu tekstu. Zgodnie z normą International Organization for Standardization (ISO) 32000-2 §9 operator Tj rysuje glify łańcucha znaków przy użyciu bieżącej czcionki oraz parametrów graficznych związanych z tekstem. TextRenderer wybiera pojedynczy operator wyświetlania albo pozycjonowaną tablicę TJ zależnie od aktywnego trybu TypographyMode. Stosuje korekty kerningu, gdy tryb używa tablic TJ.
Stan tekstu jest modelowany jako kompletny zestaw parametrów. setTextRenderingMode() przyjmuje wyliczenie TextRenderingMode. Osiem przypadków tego wyliczenia odpowiada jeden do jednego trybom renderowania tekstu z normy ISO 32000-2: wypełnienie, obrys, wypełnienie z obrysem, niewidoczny oraz cztery warianty przycinania (tabela 104). Komponent kontroluje również szerokość obrysu, odstępy między znakami, odstępy między wyrazami, rozciągnięcie poziome, podniesienie tekstu, kierunek od prawej do lewej oraz opcjonalny Hyphenator. Wywołanie buildTextStateOperators() emituje zgromadzony stan jako pojedynczy blok operatorów.
TextShadow jest obiektem wartości: zawiera kolor, przesunięcia X i Y w jednostkach użytkownika oraz krycie. Komponent używa go do wyemitowania drugiego przebiegu rysowania w miejscu przesunięcia. Domyślne przesunięcia to subtelne 0.5/−0.5 z kryciem 0.5, podobnie jak miękki cień w Cascading Style Sheets (CSS).
JavaScriptManager odpowiada za skrypty na poziomie dokumentu. includeJs() rejestruje skrypt dokumentu. addJsObject() rejestruje nazwany obiekt skryptu. writeJavaScript() / writeOpenAction() serializują skrypty do katalogu oraz do akcji OpenAction. Menedżer waliduje każdą zawartość skryptu i koduje ją jako łańcuch PDF przed wyemitowaniem.
PropertiesRegistry jest magazynem właściwości treści oznaczonej. register() zwraca stabilny indeks znacznika dla słownika właściwości. registerOcg() / registerOcgs() wiążą grupy treści opcjonalnej (OCG) według numeru obiektu. writeProperties() serializuje rejestr do słownika zasobów strony. Moduł ContentStream odczytuje te dane, gdy otwiera oznaczoną sekwencję z listą właściwości.
W tym module znajdują się dwa dekodery obrazów, ponieważ obsługują natywne dla PDF formaty przekazywane bezpośrednio. JBig2Loader oraz JpxLoader analizują struktury segmentów JBIG2 oraz JPEG 2000 i zwracają ImageData bez rasteryzacji pikseli. Zakodowane bajty są przekazywane do przeglądarki bez zmian. Gdy źródło JBIG2 zawiera osobny segment globalny, JBig2Loader osadza go za pomocą odwołania do strumienia /JBIG2Globals w obiekcie XObject obrazu; postać in-stream/in-line nadal podlega pełnemu cyklowi zapisu i odczytu jak wcześniej. To wyłącznie połączenie strukturalne: bajty globalne są przekazywane bez rasteryzacji i bez dekodowania.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Klasa | Kluczowe metody | Rola |
|---|---|---|
TextRenderer | buildTextShowOperator(), buildTextStateOperators(), setTextRenderingMode(), setTextStrokeWidth(), setTextShadow(), setFontSpacing(), setWordSpacing(), setFontStretching(), setTextRise(), setRTL(), setHyphenation() | Konstruktor operatorów wyświetlania i stanu tekstu |
TextRenderingMode (wyliczenie) | Fill, Stroke, FillStroke, Invisible, FillClip, StrokeClip, FillStrokeClip, Clip | Tryby renderowania tekstu wg ISO 32000-2 |
TextShadow | __construct(Color, offsetX, offsetY, opacity) | Obiekt wartości dla przesuniętego przebiegu rysowania |
JavaScriptManager | includeJs(), addJsObject(), hasJavaScript(), writeJavaScript(), writeOpenAction() | Łączy kod JavaScript na poziomie dokumentu z katalogiem |
PropertiesRegistry | register(), getTagIndex(), registerOcg(), registerOcgs(), getAll(), writeProperties() | Magazyn właściwości treści oznaczonej i OCG |
JBig2Loader | load(), loadFromString(), parseSegments() | Dekoder JBIG2 przekazujący dane bezpośrednio |
JpxLoader | load(), loadFromString(), parseBoxes() | Dekoder JPEG 2000 przekazujący dane bezpośrednio |
Uruchom composer docs:generate-api-php -- --module=Content, aby uzyskać pełną tabelę PHPDoc.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”Źródło: 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();Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”Przykład dodaje miękki cień i podział na sylaby, a następnie buduje operator wyświetlania z dostarczonym przez wywołującego wywołaniem zwrotnym zmiany znaczenia — kanoniczną granicą PdfStringEscaper opisaną w zapisie decyzji architektonicznej 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;Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”buildTextShowOperator()zwraca pusty łańcuch znaków dla pustego wejścia. Nie emituj pustegoTj; obsłuż to wcześniej, jeśli układ może generować puste fragmenty.- Wywołanie zwrotne zmiany znaczenia jest obowiązkowe i odpowiada za bezpieczeństwo łańcucha znaków. Przekaż kanoniczny
PdfStringEscaper::escapeLiteral()z ADR-015. Niepełny mechanizm zmiany znaczenia tworzy niepoprawny składniowo dosłowny łańcuch znaków. - W układzie współrzędnych z początkiem w lewym górnym rogu ujemne wartości
TextShadow::offsetYprzesuwają cień w dół. Dodatnia wartość Y przesuwa cień w górę, co rzadko jest zamierzone. JavaScriptManagerwaliduje dane wejściowe skryptu. Nieprawidłowa zawartość skryptów jest odrzucana podczas rejestracji, a nie po cichu pomijana na etapie zapisu.JBig2LoaderorazJpxLoadernigdy nie rasteryzują. Walidują i przekazują zakodowane bajty bez zmian. Uszkodzony segment ujawnia się jako błąd analizy, a nie jako pusty obraz.PropertiesRegistry::register()jest idempotentne dla każdego słownika; identyczne słowniki właściwości ponownie używają jednego indeksu znacznika.
Wydajność
Dział zatytułowany „Wydajność”Konstrukcja operatorów ma złożoność O(n) względem długości łańcucha znaków, plus przejście kerningu O(n), gdy tryb typografii używa tablic TJ. Nie obejmuje kosztu układu ani kształtowania; te zadania pozostają w modułach Typography oraz Layout. Serializacja kodu JavaScript oraz właściwości ma złożoność O(liczba wpisów). Moduły ładowania obrazów przekazujące dane bezpośrednio stosują analizę O(liczba bajtów) przy zerowym koszcie dekodowania. Jest to ich główna zaleta w obciążeniach związanych ze skanowanymi dokumentami. Wartość performance_budget dla referencyjnego obciążenia to 1500 ms czasu rzeczywistego i 64 MB szczytowego zużycia pamięci.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”JavaScriptManager przyjmuje zawartość skryptów, która może pochodzić z niezaufanych szablonów. Waliduje i koduje każdą zawartość jako łańcuch PDF, ale kod JavaScript w dokumencie pozostaje powierzchnią aktywnej treści. Wyłącz go dla niezaufanych danych wyjściowych lub usuń za pomocą ścieżki oczyszczania opisanej w /modules/core/security/. JBig2Loader oraz JpxLoader analizują niezaufane struktury segmentów: ogranicz rozmiar danych wejściowych i czas analizy oraz uruchamiaj ekstrakcję w izolowanym procesie roboczym, gdy źródło pochodzi od użytkownika. Granicą zmiany znaczenia tekstu jest wywołanie zwrotne dostarczone przez wywołującego. Zawsze przekazuj kanoniczny mechanizm zmiany znaczenia, aby bajty sterujące nie mogły wyjść poza dosłowny łańcuch znaków.
Zgodność
Dział zatytułowany „Zgodność”Moduł emituje operatory wyświetlania tekstu i stanu tekstu zgodne z modelem tekstu ISO 32000-2 §9. Obejmuje to semantykę operatora Tj oraz tryby renderowania z tabeli 104 odzwierciedlane przez wyliczenie TextRenderingMode. Są to fakty implementacyjne: src/Content/TextRenderer.php oraz wyliczenie TextRenderingMode tworzą kształty operatorów, a tests/Unit/Content/TextRenderer*, JavaScriptManagerIsoTest oraz PropertiesRegistryTest je weryfikują. Nie potwierdzają one pełnej, kompleksowej zgodności z PDF 2.0. Kontrakt zmiany znaczenia łańcuchów znaków jest zgodny z ADR-015 oraz ISO 32000-2 §7.3.4.2. Ścieżki przekazujące dane bezpośrednio dla JBIG2 i JPEG 2000 zachowują zakodowane strumienie bez zmian. Osobny segment globalny JBIG2 jest osadzany jako odwołanie do strumienia /JBIG2Globals w obiekcie XObject obrazu; jest to weryfikowane jako połączenie strukturalne, a nie jako stwierdzenie wierności dekodowania. Zgodność na poziomie dokumentu jest walidowana przez zestawy oracle i wzorcowe w /modules/core/conformance/.