Fon kustom: kontrak ekstensi FontRegistry
Sekilas pandang
Bagian berjudul “Sekilas pandang”FontRegistryInterface mendefinisikan kontrak yang berlaku sepanjang masa hidup proses untuk mendaftarkan dan menemukan fon. Daftarkan fon dari path berkas, direktori, atau data biner mentah, lalu kunci registri agar worker produksi tidak dapat mengubahnya.
Pemasangan
Bagian berjudul “Pemasangan”composer require nextpdf/core:^3Tinjauan konseptual
Bagian berjudul “Tinjauan konseptual”Registri fon adalah singleton yang masa hidupnya lebih panjang daripada setiap instance Document. Registri ini hanya menyimpan data PHP murni, tanpa handle sumber daya maupun objek ekstensi, sehingga Anda dapat membagikannya di antara permintaan dalam worker yang berjalan lama.
Gunakan salah satu dari tiga jalur pendaftaran berikut:
- Dari berkas.
register()mengurai berkas.ttf,.otf,.ttc, atau.pfb, lalu mengembalikan metadata. Untuk TrueType Collection, berikan indeks sub-fon. - Dari direktori.
addFontDirectory()menambahkan path pencarian yang dipindai mesin saat menyelesaikan famili berdasarkan nama. - Dari data biner.
registerFromBinary()mengurai bita TrueType atau OpenType mentah. Gunakan jalur ini sebagai jembatan@font-faceketika fon berasal dari Uniform Resource Identifier (URI)data:atau sumber jarak jauh.
Untuk mengurangi latensi permintaan pertama, panggil warmup() saat boot worker untuk mengurai sekumpulan fon sejak awal. Kemudian panggil lock(). Setelah lock(), setiap metode mutasi melempar LogicException: register(), addFontDirectory(), warmup(), registerBase14(), dan registerFromBinary(). Metode pencarian tetap tersedia: get(), has(), all(), dan getSearchDirectories(). Penguncian ini melindungi worker produksi dengan memastikan tidak ada permintaan yang dapat mengubah set fon bersama.
Dalam sebagian besar kasus, Anda tidak mengimplementasikan FontRegistryInterface. Mesin menyediakan implementasinya, dan Anda cukup memanggilnya. Implementasikan hanya ketika Anda memerlukan strategi penyelesaian fon kustom, misalnya yang didukung oleh penyimpanan beralamat-konten. Dalam kedua kasus tersebut, kontrak tetap menjadi batasnya.
Permukaan API
Bagian berjudul “Permukaan API”NextPDF\Contracts\FontRegistryInterface (stabil, sejak 1.7.0):
| Metode | Mengembalikan | Tujuan |
|---|---|---|
register(string $fontFile, string $alias, int $fontIndex) | FontInfo | Mengurai dan mendaftarkan berkas fon. Melempar pengecualian jika registri terkunci atau berkas tidak dapat diurai. |
registerFromBinary(string $fontData, string $alias) | FontInfo | Mendaftarkan fon dari bita TrueType atau OpenType mentah. |
registerBase14(string $key, FontInfo $font) | void | Mendaftarkan fon standar Base 14 bawaan. |
addFontDirectory(string $directory) | void | Menambahkan direktori pencarian fon. |
warmup(array $fontFiles) | void | Mengurai sekumpulan fon sejak awal saat boot worker. |
lock() | void | Membekukan registri untuk mencegah mutasi lebih lanjut. |
isLocked() | bool | Melaporkan apakah registri terkunci. |
get(string $family, string $style) | FontInfo | null | Mencari fon berdasarkan famili dan gaya. |
has(string $key) | bool | Memeriksa keberadaan kunci pendaftaran. |
all() | array<string, FontInfo> | Mengembalikan semua fon yang terdaftar. |
getSearchDirectories() | list<string> | Mengembalikan direktori pencarian dalam urutannya. |
memoryUsage() | MemoryReport | Melaporkan penggunaan memori registri saat ini. |
Contoh kode — Mulai cepat
Bagian berjudul “Contoh kode — Mulai cepat”<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;
/** @var FontRegistryInterface $fonts */$info = $fonts->register('/srv/fonts/Inter-Regular.ttf', 'Inter');
if (!$fonts->has('inter')) { throw new RuntimeException('Inter failed to register');}Contoh kode — Produksi
Bagian berjudul “Contoh kode — Produksi”Saat boot worker, lakukan warmup pada set fon, kunci registri, dan pantau setiap pemuatan untuk pelacakan lisensi. Contoh ini hanya menggunakan tipe publik.
<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;use NextPDF\Event\Content\FontLoadedEvent;use NextPDF\Event\EventDispatcher;use NextPDF\Event\ListenerProvider;use Psr\Log\LoggerInterface;
final class FontWarmup{ /** @param list<string> $fontFiles */ public function __construct( private readonly FontRegistryInterface $fonts, private readonly LoggerInterface $logger, private readonly array $fontFiles, ) {}
public function boot(): EventDispatcher { $listeners = new ListenerProvider(); $listeners->addListener( FontLoadedEvent::class, function (FontLoadedEvent $event): void { $this->logger->info('font.loaded', [ 'family' => $event->family, 'style' => $event->style, 'type' => $event->fontType->name, ]); }, );
if (!$this->fonts->isLocked()) { $this->fonts->warmup($this->fontFiles); $this->fonts->lock(); }
return new EventDispatcher($listeners); }}Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”- Registri terkunci. Setelah
lock(), mutasi apa pun melemparLogicException. PeriksaisLocked()sebelum melakukan warmup bersyarat pada worker yang didaur ulang. - Pendaftaran biner tidak di-cache berdasarkan kunci.
registerFromBinary()menulis ke berkas sementara lalu menguraikannya. GunakanFontInfoyang dikembalikan sebagai handle. - Indeks TrueType Collection (TTC). Untuk TrueType Collection, argumen ketiga pada
register()memilih sub-fon. Nilai standar0memilih face pertama. - Penyelesaian famili.
get()mengembalikannulluntuk pasangan famili-dan-gaya yang tidak dikenal. Jangan pernah mengasumsikan hasilnya bukan null.
Performa
Bagian berjudul “Performa”warmup() memindahkan biaya penguraian dari permintaan pertama ke boot worker. Metode registri menggunakan data PHP murni, dan pencarian adalah pembacaan map dengan waktu konstan. Panggil memoryUsage() untuk menyesuaikan ukuran set fon residen pada worker dengan anggaran memori Anda.
Catatan keamanan
Bagian berjudul “Catatan keamanan”Fon yang terdaftar dapat disematkan ke dalam konten Portable Document Format (PDF). Validasi asal-usul fon sebelum pendaftaran. Jangan mendaftarkan data biner yang dikendalikan penyerang tanpa pemeriksaan ukuran dan format. Gunakan hook FontLoadedEvent untuk menegakkan kepatuhan lisensi fon dan mencatat face mana saja yang disematkan dalam sebuah dokumen.
Kesesuaian
Bagian berjudul “Kesesuaian”Tidak ada klaim normatif penandatanganan atau pengarsipan yang berlaku. Penyematan dan subsetting fon sesuai dengan model fon PDF 2.0. Kesesuaian tersebut dipikul oleh subsetter internal; bukan oleh kontrak ini.
Konteks komersial
Bagian berjudul “Konteks komersial”NextPDF Enterprise menambahkan atestasi lisensi fon dan kebijakan subsetting teraudit di atas FontRegistryInterface yang sama. Kode pendaftaran Anda berfungsi sama di seluruh edisi karena kontrak tersebut menjadi batasnya.
Lihat juga
Bagian berjudul “Lihat juga”- Tinjauan penulisan ekstensi
- Pemicu aksi dan pendengar peristiwa
- Tata letak kustom dan intersepsi teks
- Aturan stabilitas SPI
Kontrak dan modul terkait
Bagian berjudul “Kontrak dan modul terkait”- Referensi modul fon — implementasi registri, penguraian, dan subsetting internal.
- Referensi kontrak tipografi — entri katalog untuk
FontRegistryInterface. - Pemicu aksi dan pendengar peristiwa —
FontLoadedEventdan dispatcher-nya. - Tata letak kustom dan intersepsi teks — kontrak strategi waktu-render yang terkait.
- Aturan stabilitas SPI — jaminan antarmuka di balik
FontRegistryInterface.
Glosarium mendefinisikan registri fon, registri gambar, dan pendengar peristiwa; lihat glosarium yang diterbitkan untuk definisi kanoniknya.