Phông chữ tùy chỉnh: hợp đồng mở rộng của FontRegistry
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”FontRegistryInterface định nghĩa hợp đồng đăng ký và tra cứu phông chữ tồn tại trong suốt vòng đời tiến trình. Hãy đăng ký phông chữ từ đường dẫn tệp, thư mục hoặc dữ liệu nhị phân thô, rồi khóa registry để các worker production không thể thay đổi nó.
Cài đặt
Phần tiêu đề “Cài đặt”composer require nextpdf/core:^3Tổng quan khái niệm
Phần tiêu đề “Tổng quan khái niệm”Font registry là một singleton có vòng đời dài hơn từng instance Document. Nó chỉ lưu dữ liệu PHP thuần, không giữ resource handle hay đối tượng extension nào, nên bạn có thể chia sẻ nó giữa các request trong một worker chạy lâu dài.
Hãy dùng một trong ba cách đăng ký:
- Từ một tệp.
register()phân tích một tệp.ttf,.otf,.ttchoặc.pfbvà trả về metadata. Với một TrueType Collection, hãy truyền chỉ mục của phông chữ con. - Từ một thư mục.
addFontDirectory()thêm đường dẫn tìm kiếm để engine quét khi phân giải họ phông chữ theo tên. - Từ dữ liệu nhị phân.
registerFromBinary()phân tích các byte TrueType hoặc OpenType thô. Hãy dùng cách này cho cầu nối@font-facekhi phông chữ đến từ một Uniform Resource Identifier (URI)data:hoặc từ nguồn từ xa.
Để giảm độ trễ ở request đầu tiên, hãy gọi warmup() khi worker khởi động để phân tích trước một loạt phông chữ. Sau đó gọi lock(). Sau lock(), mọi phương thức gây thay đổi đều ném LogicException: register(), addFontDirectory(), warmup(), registerBase14() và registerFromBinary(). Các phương thức tra cứu vẫn dùng được: get(), has(), all() và getSearchDirectories(). Cơ chế khóa này bảo vệ các worker production bằng cách đảm bảo không request nào có thể thay đổi tập phông chữ dùng chung.
Trong hầu hết trường hợp, bạn không cần tự hiện thực FontRegistryInterface. Engine cung cấp phần hiện thực; bạn chỉ cần gọi nó. Chỉ tự hiện thực khi bạn cần chiến lược phân giải phông chữ tùy chỉnh, chẳng hạn chiến lược dựa trên kho lưu trữ định địa chỉ theo nội dung. Trong cả hai trường hợp, hợp đồng vẫn là ranh giới.
Bề mặt API
Phần tiêu đề “Bề mặt API”NextPDF\Contracts\FontRegistryInterface (ổn định, kể từ 1.7.0):
| Phương thức | Trả về | Mục đích |
|---|---|---|
register(string $fontFile, string $alias, int $fontIndex) | FontInfo | Phân tích và đăng ký một tệp phông chữ. Ném ngoại lệ khi registry đã bị khóa hoặc tệp không phân tích được. |
registerFromBinary(string $fontData, string $alias) | FontInfo | Đăng ký một phông chữ từ các byte TrueType hoặc OpenType thô. |
registerBase14(string $key, FontInfo $font) | void | Đăng ký một phông chữ Base 14 chuẩn có sẵn. |
addFontDirectory(string $directory) | void | Thêm một thư mục tìm kiếm phông chữ. |
warmup(array $fontFiles) | void | Phân tích trước một loạt phông chữ khi worker khởi động. |
lock() | void | Đóng băng registry để ngăn mọi thay đổi tiếp theo. |
isLocked() | bool | Báo cáo xem registry có đang bị khóa hay không. |
get(string $family, string $style) | FontInfo | null | Tra cứu một phông chữ theo họ và kiểu dáng. |
has(string $key) | bool | Kiểm tra xem một khóa đăng ký có tồn tại hay không. |
all() | array<string, FontInfo> | Trả về mọi phông chữ đã đăng ký. |
getSearchDirectories() | list<string> | Trả về các thư mục tìm kiếm theo thứ tự. |
memoryUsage() | MemoryReport | Báo cáo lượng bộ nhớ registry đang sử dụng. |
Ví dụ mã — bắt đầu nhanh
Phần tiêu đề “Ví dụ mã — bắt đầu nhanh”<?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');}Ví dụ mã — production
Phần tiêu đề “Ví dụ mã — production”Khi worker khởi động, hãy làm nóng tập phông chữ, khóa registry và ghi nhận từng lần tải để theo dõi giấy phép. Ví dụ này chỉ dùng các kiểu công khai.
<?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); }}Trường hợp biên & lưu ý
Phần tiêu đề “Trường hợp biên & lưu ý”- Registry đã khóa. Sau
lock(), mọi thay đổi đều némLogicException. Hãy kiểm traisLocked()trước khi làm nóng có điều kiện trong một worker được dùng lại. - Đăng ký nhị phân không được cache theo khóa.
registerFromBinary()ghi ra một tệp tạm rồi phân tích tệp đó. Hãy dùngFontInfođược trả về làm handle. - Chỉ mục TrueType Collection (TTC). Với một TrueType Collection, đối số thứ ba của
register()chọn phông chữ con. Giá trị mặc định0chọn face đầu tiên. - Phân giải họ phông chữ.
get()trả vềnullvới một cặp họ-và-kiểu không xác định. Đừng bao giờ giả định kết quả khác null.
Hiệu năng
Phần tiêu đề “Hiệu năng”warmup() chuyển chi phí phân tích từ request đầu tiên sang lúc worker khởi động. Các phương thức registry dùng dữ liệu PHP thuần, còn các lần tra cứu là thao tác đọc map với thời gian hằng số. Hãy gọi memoryUsage() để cân đối tập phông chữ thường trú của worker với ngân sách bộ nhớ của bạn.
Lưu ý bảo mật
Phần tiêu đề “Lưu ý bảo mật”Một phông chữ đã đăng ký có thể được nhúng vào nội dung Portable Document Format (PDF). Hãy xác thực nguồn gốc của phông chữ trước khi đăng ký. Đừng đăng ký dữ liệu nhị phân do kẻ tấn công kiểm soát nếu chưa kiểm tra kích thước và định dạng. Hãy dùng hook FontLoadedEvent để thực thi việc tuân thủ giấy phép phông chữ và ghi lại những face mà tài liệu đã nhúng.
Tuân thủ tiêu chuẩn
Phần tiêu đề “Tuân thủ tiêu chuẩn”Không có tuyên bố quy chuẩn nào về ký số hoặc lưu trữ áp dụng ở đây. Việc nhúng phông chữ và tạo tập con tuân theo mô hình phông chữ của PDF 2.0. Bộ tạo tập con nội bộ chịu trách nhiệm cho sự tuân thủ đó; hợp đồng này thì không.
Bối cảnh thương mại
Phần tiêu đề “Bối cảnh thương mại”NextPDF Enterprise bổ sung chứng thực giấy phép phông chữ và chính sách tạo tập con được kiểm toán trên cùng một FontRegistryInterface. Mã đăng ký của bạn hoạt động như nhau trên các phiên bản vì hợp đồng là ranh giới.
Xem thêm
Phần tiêu đề “Xem thêm”- Tổng quan về phát triển extension
- Action trigger và event listener
- Bố cục tùy chỉnh và chặn văn bản
- Quy tắc ổn định của SPI
Các hợp đồng và mô-đun liên quan
Phần tiêu đề “Các hợp đồng và mô-đun liên quan”- Tài liệu tham khảo mô-đun font — phần hiện thực registry, việc phân tích và cơ chế nội bộ của việc tạo tập con.
- Tài liệu tham khảo hợp đồng typography — mục danh mục cho
FontRegistryInterface. - Action trigger và event listener —
FontLoadedEventvà dispatcher. - Bố cục tùy chỉnh và chặn văn bản — hợp đồng chiến lược cùng cấp ở thời điểm kết xuất.
- Quy tắc ổn định của SPI — lời cam kết về interface đứng sau
FontRegistryInterface.
Bảng thuật ngữ định nghĩa font registry, image registry và event listener; hãy xem bảng thuật ngữ đã xuất bản để biết định nghĩa chuẩn.