Lewati ke konten

Content: model konten tekstual + terstruktur

Modul Content membangun operator penampil teks, operator status teks, bayangan teks, JavaScript tingkat dokumen, dan kamus properti marked-content. Modul ini menjembatani tata letak dan content stream.

Terminal window
composer require nextpdf/core:^3

Content menyediakan primitif yang mengubah teks hasil resolusi menjadi operator Portable Document Format (PDF). TextRenderer adalah komponen utamanya. Komponen ini membangun operator penampil teks untuk sebuah string beserta operator status teks yang mendahuluinya. Menurut International Organization for Standardization (ISO) 32000-2 §9, operator Tj menggambar glif sebuah string dengan font saat ini dan parameter grafis terkait teks. TextRenderer memilih antara operator show tunggal atau larik TJ berposisi berdasarkan TypographyMode yang aktif. Komponen ini menerapkan penyesuaian kerning ketika mode menggunakan larik TJ.

Status teks dimodelkan sebagai satu set lengkap. setTextRenderingMode() menerima enum TextRenderingMode. Delapan kasusnya dipetakan satu lawan satu ke mode rendering teks ISO 32000-2: fill, stroke, fill-then-stroke, invisible, dan empat varian clip (Tabel 104). Renderer juga mengontrol lebar stroke, spasi karakter, spasi kata, peregangan horizontal, kenaikan teks, arah kanan-ke-kiri, dan Hyphenator opsional. Memanggil buildTextStateOperators() menghasilkan status yang terakumulasi sebagai satu blok operator tunggal.

TextShadow adalah value object: warna, offset X dan Y dalam satuan pengguna, dan opasitas. Renderer menggunakannya untuk menghasilkan draw pass kedua pada offset tersebut. Offset standarnya yang halus adalah 0.5/−0.5 dengan opasitas 0.5, mirip dengan soft shadow pada Cascading Style Sheets (CSS).

JavaScriptManager menangani skrip tingkat dokumen. includeJs() mendaftarkan skrip dokumen. addJsObject() mendaftarkan objek skrip bernama. writeJavaScript() / writeOpenAction() menserialisasi skrip ke dalam katalog dan OpenAction. Manajer ini memvalidasi dan mengenkode setiap badan skrip sebagai PDF-string sebelum emisi.

PropertiesRegistry adalah penyimpan properti marked-content. register() mengembalikan indeks tag yang stabil untuk sebuah kamus properti. registerOcg() / registerOcgs() mengikat grup konten opsional (OCG) berdasarkan nomor objek. writeProperties() menserialisasi registri ke dalam kamus sumber daya halaman. Modul ContentStream membaca data ini saat membuka marked sequence dengan daftar properti.

Dua dekoder gambar berada di modul ini karena keduanya menangani format pass-through yang native PDF. JBig2Loader dan JpxLoader mengurai struktur segmen JBIG2 dan JPEG 2000 serta mengembalikan ImageData tanpa meraster piksel. Byte yang terenkode diteruskan ke penampil tanpa perubahan. Ketika sumber JBIG2 membawa segmen globals terpisah, JBig2Loader menyematkannya melalui referensi stream /JBIG2Globals pada image XObject; bentuk in-stream/in-line tetap melakukan round-trip seperti sebelumnya. Ini hanya wiring struktural: byte globals diteruskan tanpa diraster, tidak didekode.

KelasMetode utamaPeran
TextRendererbuildTextShowOperator(), buildTextStateOperators(), setTextRenderingMode(), setTextStrokeWidth(), setTextShadow(), setFontSpacing(), setWordSpacing(), setFontStretching(), setTextRise(), setRTL(), setHyphenation()Pembangun operator penampil teks + status teks
TextRenderingMode (enum)Fill, Stroke, FillStroke, Invisible, FillClip, StrokeClip, FillStrokeClip, ClipMode rendering teks ISO 32000-2
TextShadow__construct(Color, offsetX, offsetY, opacity)Value object untuk draw-pass beroffset
JavaScriptManagerincludeJs(), addJsObject(), hasJavaScript(), writeJavaScript(), writeOpenAction()Wiring katalog JavaScript tingkat dokumen
PropertiesRegistryregister(), getTagIndex(), registerOcg(), registerOcgs(), getAll(), writeProperties()Penyimpan properti marked-content + OCG
JBig2Loaderload(), loadFromString(), parseSegments()Dekoder pass-through JBIG2
JpxLoaderload(), loadFromString(), parseBoxes()Dekoder pass-through JPEG 2000

Jalankan composer docs:generate-api-php -- --module=Content untuk tabel PHPDoc lengkap.

Sumber: 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();

Ini menambahkan soft shadow dan hyphenator, lalu membangun operator show dengan fungsi escape yang disediakan pemanggil, yaitu batas kanonis PdfStringEscaper dari 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() mengembalikan string kosong untuk masukan kosong. Jangan menghasilkan Tj yang kosong; pasang guard di hulu jika tata letak Anda dapat menghasilkan run kosong.
  • Callback escape wajib ada dan bertanggung jawab atas keamanan string. Teruskan PdfStringEscaper::escapeLiteral() kanonis dari ADR-015. Escaper yang parsial menghasilkan string literal yang tidak valid secara sintaksis.
  • Pada origin kiri-atas, TextShadow::offsetY bersifat negatif ke bawah. Y yang positif mendorong bayangan ke atas, yang jarang diinginkan.
  • JavaScriptManager memvalidasi masukan skrip. Badan skrip yang tidak valid ditolak saat registrasi, bukan dibuang secara diam-diam pada saat penulisan.
  • JBig2Loader dan JpxLoader tidak pernah meraster. Keduanya memvalidasi dan meneruskan byte yang terenkode. Segmen yang rusak muncul sebagai parse error, bukan gambar kosong.
  • PropertiesRegistry::register() bersifat idempoten per kamus; kamus properti yang identik menggunakan kembali satu indeks tag.

Konstruksi operator bersifat O(n) terhadap panjang string, ditambah satu lintasan kerning O(n) ketika mode tipografi menggunakan larik TJ. Tidak ada biaya tata letak atau shaping di sini; pekerjaan itu tetap berada di modul Typography dan Layout. Serialisasi JavaScript dan properti bersifat O(entries). Loader gambar pass-through menggunakan penguraian O(bytes) tanpa biaya dekode. Ini menjadi keunggulan utama keduanya untuk beban kerja dokumen pindaian. performance_budget untuk beban kerja referensi adalah 1500 ms wall dan 64 MB puncak.

JavaScriptManager menerima badan skrip yang mungkin berasal dari templat tidak tepercaya. Manajer ini memvalidasi dan mengenkode setiap badan sebagai PDF-string, tetapi JavaScript dokumen tetap menjadi permukaan konten aktif. Nonaktifkan untuk keluaran tidak tepercaya, atau bersihkan melalui jalur sanitasi yang dijelaskan di /modules/core/security/. JBig2Loader dan JpxLoader mengurai struktur segmen yang tidak tepercaya: batasi ukuran masukan dan waktu penguraian, serta jalankan ekstraksi dalam worker terbatas ketika sumbernya disediakan pengguna. Batas escape teks adalah callback yang disediakan pemanggil. Selalu teruskan escaper kanonis agar byte kontrol tidak dapat keluar dari string literal.

Modul ini menghasilkan operator penampil teks dan status teks yang konsisten dengan model teks ISO 32000-2 §9. Ini mencakup semantik operator Tj dan mode rendering Tabel 104 yang dicerminkan oleh enum TextRenderingMode. Ini adalah fakta implementasi: src/Content/TextRenderer.php dan enum TextRenderingMode menghasilkan bentuk operator, dan tests/Unit/Content/TextRenderer*, JavaScriptManagerIsoTest, dan PropertiesRegistryTest mengujinya. Pengujian tersebut tidak menyatakan konformitas PDF 2.0 menyeluruh. Kontrak string-escape mengikuti ADR-015 dan ISO 32000-2 §7.3.4.2. Jalur pass-through JBIG2 dan JPEG 2000 mempertahankan stream terenkode tanpa perubahan. Segmen globals JBIG2 yang terpisah disematkan sebagai referensi stream /JBIG2Globals pada image XObject; ini diverifikasi sebagai wiring struktural, bukan sebagai klaim fidelitas hasil dekode. Konformitas tingkat dokumen divalidasi oleh oracle dan golden suite di /modules/core/conformance/.