stabilitas: Eksperimental
Dukungan shaping skrip-kompleks
Sekilas
Bagian berjudul “Sekilas”Preview opt-in. Shaping skrip-kompleks default-mati. Saat mati, mesin merender melalui jalur codepoint-ke-cmap yang sudah ada — byte-identik dengan build tanpa fitur tersebut. Aktifkan hanya saat Anda memiliki libharfbuzz dan font yang mampu melakukan shaping, dan validasi hasilnya.
Perender HTML menambahkan shaper skrip-kompleks yang opt-in untuk Tibet dan Mongolia. Saat shaper aktif, sebuah run Tibet atau Mongolia dalam-cakupan yang terdeteksi di-shape melalui libharfbuzz dan dipancarkan sebagai kode glyph Identity-H. Shaper mencakup Tibet horizontal pada face TrueType dan CFF/OTTO, termasuk pembungkusan, serta Mongolia vertikal yang disusun dari atas ke bawah (TTB).
Pemasangan
Bagian berjudul “Pemasangan”composer require nextpdf/core:^3Shaper disertakan dalam paket core. Opt-in
CssFeatureFlags::$complexTextShaping adalah @since 6.1.0. libharfbuzz adalah
persyaratan runtime saat flag aktif — shaper memanggil libharfbuzz melalui
ekstensi FFI PHP. Saat flag mati, pustaka tidak memiliki dependensi libharfbuzz.
Ikhtisar konseptual
Bagian berjudul “Ikhtisar konseptual”Skrip kompleks menyusun ulang, mensubstitusi, dan memreposisi glyph menurut konteks. Pemetaan codepoint-ke-glyph yang naif merendernya dengan jelas keliru. Shaper menyerahkan sebuah run dalam-cakupan ke libharfbuzz, yang menerapkan tabel shaping OpenType font, dan mesin memancarkan urutan glyph yang dihasilkan sebagai font Type 0 komposit dengan encoding Identity-H (ISO 32000-2 §9.7.4 — string yang ditampilkan adalah CID dua-byte).
Cakupannya disengaja. Shaper mengenali run Tibet dan Mongolia dan men-shape-nya; ia tidak mengklaim cakupan skrip-kompleks umum. Tibet horizontal di-shape pada face TrueType dan CFF/OTTO, dengan pembungkusan baris. Mongolia di-shape secara vertikal, dari atas ke bawah.
Batasan fail-closed — keras dan bertipe
Bagian berjudul “Batasan fail-closed — keras dan bertipe”Shaper tidak pernah memancarkan glyph yang tak-di-shape dan rusak secara visual sebagai fallback. Sebuah run yang tidak dapat di-shape secara setia akan memunculkan eksepsi bertipe sebagai gantinya:
ComplexScriptShapingException— run tidak dapat di-shape secara setia: font tidak memiliki glyph yang dibutuhkan (sebuah.notdefakan dihasilkan), sebuah face CFF diminta men-shape pada jalur vertikal, run berisi sebuah tautan, atau sebuah kolom Mongolia membutuhkan pembungkusan (kasus di luar cakupan).HarfBuzzUnavailableException— flag aktif tetapi libharfbuzz tidak dapat dijangkau melalui FFI pada runtime.
Dengan flag mati, sebuah run dalam-cakupan dirender melalui jalur codepoint-ke-cmap yang sudah ada. Itu adalah keterbatasan terdokumentasi, bukan klaim shaping: jalur mati tidak menerapkan shaping OpenType, sehingga bentuk kontekstual tidak dijamin. Jangan jelaskan keluaran jalur-mati sebagai “di-shape”.
Batas kejujuran — paritas objektif, bukan persetujuan estetis
Bagian berjudul “Batas kejujuran — paritas objektif, bukan persetujuan estetis”Fidelitas shaping divalidasi secara objektif terhadap HarfBuzz: pengenal glyph yang dipancarkan, pemetaan cluster, dan posisi glyph cocok dengan keluaran referensi HarfBuzz (paritas glyph, cluster, dan posisi). Tinjauan estetis oleh penutur asli — menilai apakah hasilnya terbaca alami bagi pembaca fasih — merupakan tindak lanjut pasca-rilis yang dilacak. NextPDF tidak membuat klaim kualitas-bahasa apa pun dalam API ini atau dalam dokumen ini. Paritas objektif ditegaskan; kualitas estetis tidak.
Permukaan API
Bagian berjudul “Permukaan API”| Simbol | Lokasi | Peran |
|---|---|---|
CssFeatureFlags::$complexTextShaping | src/Html/CssFeatureFlags.php | Flag opt-in untuk shaper Tibet/Mongolia (default false). |
Config::withCssFeatureFlags(CssFeatureFlags $flags): self | src/Core/Config.php | Melampirkan kumpulan flag ke konfigurasi dokumen. |
ComplexScriptShapingException | src/Font/Shaper/ComplexScriptShapingException.php | Dilempar saat run dalam-cakupan tidak dapat di-shape secara setia. |
HarfBuzzUnavailableException | src/Font/Shaper/HarfBuzzUnavailableException.php | Dilempar saat flag aktif tetapi libharfbuzz tidak tersedia. |
Contoh kode — Mulai cepat
Bagian berjudul “Contoh kode — Mulai cepat”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;use NextPDF\Html\Css\CssFeatureFlags;
$config = (new Config())->withCssFeatureFlags( new CssFeatureFlags(complexTextShaping: true),);
$doc = Document::createStandalone($config);$doc->addPage();$doc->writeHtml( '<div style="font-family: NotoSerifTibetan;">བོད་སྐད་</div>',);$doc->save(__DIR__ . '/tibetan.pdf');Contoh kode — Produksi
Bagian berjudul “Contoh kode — Produksi”Daftarkan sebuah font yang mampu melakukan shaping, opt-in ke shaper, dan tangani kedua mode kegagalan bertipe secara eksplisit. Render yang setia atau eksepsi yang jelas — tidak pernah run glyph yang diam-diam rusak.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\DocumentFactory;use NextPDF\Exception\ComplexScriptShapingException;use NextPDF\Exception\HarfBuzzUnavailableException;use NextPDF\Graphics\ImageRegistry;use NextPDF\Html\Css\CssFeatureFlags;use NextPDF\Typography\FontRegistry;
$fontRegistry = new FontRegistry();$fontRegistry->register('/path/to/NotoSerifTibetan-Regular.ttf', alias: 'NotoSerifTibetan');
$config = (new Config())->withCssFeatureFlags( new CssFeatureFlags(complexTextShaping: true),);
$factory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));$doc = $factory->create($config);$doc->setLanguage('bo');$doc->addPage();
try { $doc->writeHtml('<div style="font-family: NotoSerifTibetan;">བོད་སྐད་</div>');} catch (HarfBuzzUnavailableException $e) { // The flag is on but libharfbuzz is not reachable. Install it, or turn the // flag off to fall back to the unshaped cmap path. throw $e;} catch (ComplexScriptShapingException $e) { // The run cannot be shaped faithfully (missing glyphs, link in run, // out-of-scope case). Fix the font or the content; do not ship broken glyphs. throw $e;}
$doc->save($out);Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”- libharfbuzz diperlukan saat aktif. Dengan flag aktif dan libharfbuzz tidak
ada, mesin melempar
HarfBuzzUnavailableException. Ia tidak diam-diam terdegradasi. - Mati bukan “di-shape”. Dengan flag mati, sebuah run dalam-cakupan dirender melalui jalur cmap tanpa shaping OpenType. Ini adalah keterbatasan terdokumentasi; jangan menyebutnya keluaran yang di-shape.
- Cakupannya Tibet dan Mongolia. Skrip kompleks lain berada di luar cakupan untuk irisan ini.
- Tautan di dalam run gagal secara fail-closed. Sebuah run yang berisi anotasi
tautan memunculkan
ComplexScriptShapingException, karena persegi panjang tautan tidak dapat mengikuti penataan-ulang yang di-shape. - Tidak ada klaim kualitas-bahasa. Paritas dengan HarfBuzz ditegaskan; kualitas estetis oleh penutur asli adalah tindak lanjut yang dilacak dan tidak diklaim.
Kinerja
Bagian berjudul “Kinerja”Shaping menambah satu panggilan libharfbuzz per run dalam-cakupan, plus lintasan
pancaran-glyph, linear terhadap jumlah glyph. Anggaran (wall_ms: 2000,
peak_mb: 128) mengikuti profil CJK/skrip-kompleks, karena font shaping berukuran
besar dan penanganan font mendominasi biaya.
Catatan keamanan
Bagian berjudul “Catatan keamanan”Mengaktifkan shaper memperkenalkan panggilan FFI ke libharfbuzz, sebuah pustaka native. Berkas font tetap merupakan masukan biner tak-tepercaya yang ditangani validasi yang sudah ada pada lapisan tipografi sebelum mencapai shaper. Shaper mengonsumsi face yang sudah terdaftar dan sudah divalidasi. Perlakukan asal-usul font yang dipasok pengguna-akhir sebagai tak-tepercaya, dan sediakan libharfbuzz dari sumber yang tepercaya.
Konformitas
Bagian berjudul “Konformitas”| Pernyataan | Standar | Klausul |
|---|---|---|
| Run yang di-shape dipancarkan sebagai CID dua-byte Identity-H dalam font Type 0 komposit. | ISO 32000-2 | §9.7.4 |
| Shaper menerapkan substitusi dan pemosisian glyph OpenType font. | OpenType Specification | GSUB / GPOS |
| Pembentukan cluster mengikuti properti skrip untuk Tibet dan Mongolia. | Unicode Standard Annex | Tibetan and Mongolian |
Ini adalah implementasi preview yang dicakupkan ke Tibet dan Mongolia, divalidasi untuk paritas objektif HarfBuzz. Ia tidak membuat klaim kualitas-bahasa dan tidak menegaskan konformitas PDF ujung-ke-ujung untuk berkas yang dihasilkan. Tidak ada teks standar yang direproduksi.