Văn bản: ranh giới shaping, CJK và xử lý run
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Module text định nghĩa ranh giới shaping. Module này cung cấp một interface gọn nhẹ để biến một run 8-bit Unicode Transformation Format (UTF-8) thành các glyph đã định vị, chọn backend OpenType thực khi có sẵn, fallback theo cách xác định khi không có, và cung cấp registry cho các shaper riêng theo script.
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”ShaperInterface kết nối pipeline bố cục văn bản với một engine shaping OpenType. Interface này được chủ ý giữ gọn: một phương thức shape() nhận ShaperInput và trả về ShapingResult. Kiểu trả về đó là đầu ra duy nhất mà bên sử dụng nhìn thấy. Các bản triển khai không được để lộ phần nội bộ của shaping engine, và kiểu trả về có định kiểu sẽ thực thi ranh giới này. ShapingResult mang theo danh sách bản ghi GlyphRun, văn bản nguồn được trả lại, script và hướng, cùng thẻ shaperImpl xác định backend đã tạo ra kết quả.
Việc chọn backend là tường minh và báo cáo năng lực mà không phỏng đoán. ShaperFactory chạy thăm dò năng lực một lần. Nếu host có binding HarfBuzz hoạt động, create() trả về shaper dựa trên HarfBuzz. Nếu không, phương thức này trả về NullShaper. NullShaper là fallback chuyển tiếp nguyên dạng. Nó phát ra một glyph tổng hợp cho mỗi codepoint Unicode, với advance bằng không và offset bằng không. Nó gắn thẻ vào kết quả để lớp quan sát có thể phát hiện fallback, đồng thời để module font-metrics xác định advance. Đường đi này là mức suy giảm đã được ghi nhận trong tài liệu, không phải shaping đầy đủ. Thay thế, ligature, định vị dấu và các dạng theo ngữ cảnh đều cần backend thực. wouldUseRealShaper() là một vị từ chẩn đoán. Mã production nên rẽ nhánh dựa trên thẻ shaperImpl của kết quả.
Shaping riêng theo script là một service provider interface (SPI), không phải bản triển khai đi kèm. ScriptShaperRegistry là registry theo phong cách PHP Standards Recommendation 11 (PSR-11), dùng để phân giải MongolianShaperInterface hoặc TibetanShaperInterface theo thẻ script International Organization for Standardization (ISO) 15924. Registry lưu trữ khóa không phân biệt chữ hoa chữ thường và dựa vào một nguồn chân lý duy nhất để xác định tính hợp lệ của mã script. Registry và các interface script-shaper là hợp đồng đã đóng băng, vì vậy extension có thể đăng ký provider Phase-12 mà không phải chạm vào các điểm gọi. Engine cung cấp ranh giới. Bên sử dụng cung cấp provider cho các script phức tạp.
Việc xử lý run tiếng Trung, tiếng Nhật và tiếng Hàn (CJK) nằm ở ranh giới mã hóa typography. Một face TrueType CJK được nhúng sẽ được phát ra dưới dạng font Type 0 với một CMap Identity-H và một hậu duệ CIDFontType2, như được nêu trong ISO 32000-2 §9.7.4 (bản tóm tắt retrieval-augmented generation (RAG) bị cắt ngắn do giới hạn giấy phép; được ghi lại trong _downgraded-claims-o3.md). Khi chương trình TrueType được nhúng, Type 2 CIDFont ánh xạ các định danh ký tự sang chỉ số glyph thông qua mục CIDToGIDMap, như được nêu trong ISO 32000-2 §9 (bản tóm tắt được ghim bởi trang hợp đồng B1). Bộ subset giữ nguyên cách đánh số glyph gốc để /CIDToGIDMap /Identity vẫn hợp lệ cho bản subset. CjkFontValidator kiểm tra xem phông chữ ứng viên có bao phủ các khối Unicode mà script cần hay không trước khi phông chữ đó được chọn.
Bề mặt API
Phần tiêu đề “Bề mặt API”| Kiểu | Loại | Thành viên chính | Độ ổn định | Từ phiên bản |
|---|---|---|---|---|
ShaperInterface | interface | shape(ShaperInput): ShapingResult | ổn định | 3.2.0 |
ShaperFactory | final class | default(), create(), wouldUseRealShaper() | ổn định | 3.2.0 |
NullShaper | final readonly class | shaper dự phòng chuyển tiếp nguyên dạng | ổn định | 3.2.0 |
ShapingResult | final readonly class | $glyphRuns, $originalText, $script, $direction, $shaperImpl | ổn định | 3.2.0 |
ScriptShaperRegistry | final class | registerMongolian(), getMongolian(), hasMongolian(), và các phương thức Tibetan tương đương | ổn định | 3.1.0 |
CjkFontValidator | final class | validateCoverage(), detectScript(), isCjkCodepoint() | ổn định | 1.0.0 |
Hình dạng phương thức register*, get* và has* của ScriptShaperRegistry cùng các interface script-shaper là một hợp đồng đã đóng băng. Theo thiết kế, ShapingResult là đầu ra duy nhất của shaper mà bên sử dụng có thể nhìn thấy.
Mẫu mã — bắt đầu nhanh
Phần tiêu đề “Mẫu mã — bắt đầu nhanh”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Font\Shaper\ShaperFactory;use NextPDF\Font\Shaper\ShaperImpl;
$factory = ShaperFactory::default();$shaper = $factory->create();
// Branch on the result tag, not on the concrete class.$wouldShape = $factory->wouldUseRealShaper() ? 'HarfBuzz backend available' : 'NullShaper fallback (degraded — no substitution or positioning)';
echo $wouldShape, "\n";ShaperFactory::default() nối dây phần thăm dò năng lực trong môi trường production. create() ghi nhớ backend đã chọn trong suốt vòng đời của factory. Dùng wouldUseRealShaper() và thẻ shaperImpl trên mỗi kết quả để kiểm tra năng lực.
Mẫu mã — Production
Phần tiêu đề “Mẫu mã — Production”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Text\Shaping\MongolianShaperInterface;use NextPDF\Text\Shaping\ScriptShaperRegistry;
final readonly class ComplexScriptBootstrap{ public function __construct(private ScriptShaperRegistry $registry) {}
/** * Register a consumer-supplied Mongolian shaper provider at boot so * the layout pipeline can resolve it by ISO 15924 script tag. */ public function register(MongolianShaperInterface $mongolian): void { $this->registry->registerMongolian($mongolian); }
public function hasMongolian(): bool { return $this->registry->hasMongolian(); }}Registry là điểm tích hợp cho các provider script phức tạp. Engine cung cấp ranh giới và hình dạng accessor đã đóng băng. Bên sử dụng cung cấp các bản triển khai Mongolian và Tibetan.
Trường hợp biên & điểm cần lưu ý
Phần tiêu đề “Trường hợp biên & điểm cần lưu ý”- Một kết quả
NullShapercó advance bằng không và offset bằng không. Đừng đưa trực tiếp các vị trí đó vào bố cục văn bản. Hãy xác định advance từ module font-metrics và phát hiện fallback thông qua thẻshaperImpl. - Đầu vào rỗng tạo ra danh sách
glyphRunsrỗng, chứ không phải một run rỗng. Mã lặp ở phía bên sử dụng không cần trường hợp đặc biệt cho run có độ dài bằng không. ScriptShaperRegistrykhông trực tiếp triển khaiPsr\Container\ContainerInterface, vì vậy các accessor có định kiểu vẫn giữ được kiểu trả về đã thu hẹp dưới phân tích tĩnh. Hãy dùnggetMongolian()vàgetTibetan(), không dùng mộtget()chung.- Các thẻ script được so khớp theo giá trị alpha-4 chuẩn của ISO 15924 và được lưu trữ không phân biệt chữ hoa chữ thường. Truyền vào
MonghoặcTibt. Việc viết hoa hay viết thường không ảnh hưởng đến tra cứu. - Các ký tự CJK Extension B nằm trong Unicode plane 2 và bắt buộc phải dùng subtable cmap Format 12 trong bản subset. Đường đi mã hóa xử lý điều này. Đừng giả định rằng basic multilingual plane bao phủ toàn bộ văn bản CJK.
Hiệu năng
Phần tiêu đề “Hiệu năng”Việc thăm dò năng lực chạy một lần cho mỗi instance ShaperFactory, và backend được ghi nhớ, nên các lần gọi create() lặp lại không phát sinh chi phí đáng kể. NullShaper tuyến tính theo số lượng codepoint của run đầu vào và không thực hiện input/output (I/O) nào. Việc phân giải ScriptShaperRegistry là tra cứu theo khóa với thời gian hằng số. CjkFontValidator lấy mẫu codepoint theo bước nhảy thay vì kiểm tra từng codepoint một, nhờ đó việc kiểm tra độ bao phủ vẫn rẻ ngay cả với phông chữ CJK có 20,000 glyph. performance_budget 1500 ms thời gian thực và 64 MB đỉnh bao trùm một lần chạy điển hình. Trong shaping thực, chi phí chủ đạo là backend OpenType. Chi phí đó nằm ngoài phạm vi của module này khi fallback đang hoạt động.
Ghi chú bảo mật
Phần tiêu đề “Ghi chú bảo mật”Ranh giới shaper nhận vào một chuỗi UTF-8. NullShaper dung thứ cho UTF-8 không hợp lệ bằng cách tách theo phương án nỗ lực tối đa thay vì ném lỗi, vì hợp đồng fallback đã được ghi nhận sẵn là “không shaping thực”. Bên gọi đã sẵn sàng chấp nhận đầu ra chất lượng thấp. Hợp đồng cluster theo byte-offset dùng độ dài theo byte, vốn đúng với đầu vào nhiều byte và tránh lỗi lệch một codepoint khi ánh xạ cluster. Khi có mặt, backend thực là một thư viện native của bên thứ ba. Hãy coi đầu vào của nó là không đáng tin cậy và giới hạn độ dài run ở phía thượng nguồn. Registry script-shaper lưu trữ các provider do bên sử dụng cung cấp. Các bản triển khai đó nằm trong ranh giới tin cậy của bên sử dụng, không phải của engine.
Tuân thủ
Phần tiêu đề “Tuân thủ”| Tuyên bố | Tiêu chuẩn | Điều khoản | Bằng chứng |
|---|---|---|---|
Một face TrueType CJK được nhúng sẽ được phát ra dưới dạng font Type 0 với một CMap Identity-H và một hậu duệ CIDFontType2. | ISO 32000-2 | §9.7.4 | Bản tóm tắt retrieval-augmented generation (RAG) bị cắt ngắn do giới hạn giấy phép; tiền tố 7a5258772f508e3b, xem _downgraded-claims-o3.md |
Một Type 2 CIDFont được nhúng ánh xạ các định danh ký tự sang chỉ số glyph thông qua CIDToGIDMap. | ISO 32000-2 | §9 |
Cả hai điều khoản đều được diễn giải lại. Điều khoản thứ hai được ghim theo bản tóm tắt (tái sử dụng từ trang hợp đồng B1), và điều khoản đầu tiên được củng cố bởi ADR-013 cùng tài liệu tổng quan dành cho nhà phát triển về cmap-encoder. NextPDF không sao chép lại văn bản quy phạm. Backend shaper độc lập với việc tuân thủ Portable Document Format (PDF). Các tuyên bố tuân thủ ở đây liên quan đến việc phát ra từ điển phông chữ CJK do ranh giới mã hóa tạo ra. ADR-013 và tài liệu tổng quan dành cho nhà phát triển về cmap-encoder mô tả đường đi đó chi tiết hơn.
Bối cảnh thương mại
Phần tiêu đề “Bối cảnh thương mại”Pipeline tiền xử lý văn bản nâng cao và các dịch vụ trích xuất được xây dựng dựa trên ranh giới shaper của Core và các kiểu giá trị xử lý run. Module text của Core cung cấp ranh giới, fallback và registry script-shaper mà không cần giấy phép. Việc thiếu liên kết chuyển đổi là có chủ ý.
Xem thêm
Phần tiêu đề “Xem thêm”- Typography: registry, subsetting, CMap, encoding, BiDi — ranh giới mã hóa và engine văn bản hai chiều.
- Font: value types, embedding, fallback — giá trị
FontInfođược tham chiếu bởi đầu vào của shaper. - Contracts / Typography — hợp đồng text-preprocessor ở phía thượng nguồn của shaping.