kararlılık: Deneysel
CJK metnini cmap'e duyarlı kodlamayla ayarlama
Bir bakışta
“Bir bakışta” başlıklı bölümBu tarif, bir CJK TrueType yazı tipi yüzünü kaydeder. Ardından Geleneksel Çince metni cmap’e duyarlı FontInfo::encodeText() cephesi üzerinden kodlar. Cephe, Identity-H iki baytlık CID bayt akışı üretir. Tarif, examples/35-cjk-cmap-demo.php dosyasını izler. Buna güvenmeden önce aşağıdaki kapsam notunu okuyun.
Kapsam ve durum (önce okuyun)
“Kapsam ve durum (önce okuyun)” başlıklı bölümcmap’e duyarlı metin kodlama mimarisi aşamalı olarak teslim edilir (ADR-013). 1. aşama tamamlandı: FontInfo::encodeText() cephesi ve cmap’e duyarlı kodlama stratejisi bağlandı ve kullanıcı alanından erişilebilir. 2. aşama devam ediyor: işleyiciyi ve yazıcıyı cephe üzerinden yönlendirir. 3. ve 4. aşamalar beklemede: yazı tipi başına /ToUnicode, /CIDSystemInfo, /Encoding ve /CIDToGIDMap çıktısı ile yedek yazı tipi çözümleyicisi henüz yazıcıya bağlanmadı.
Şu sonuçları göz önünde bulundurun:
- Bu tarif, anahtar teslim bir dikey yazım modunu değil, kodlama cephesini — metin kodlama katmanını — gösterir. HTML/CSS yerleşim yolu için artık tercihe bağlı, deneysel bir dikey yazım modu oluşturucusu mevcuttur (CSS
vertical-rl/vertical-lrdeğerlerini sürenlayoutVerticalComposerbayrağı); bkz. Dikey yazım modu. Belge yüzeyinde hâlâ buyurgan birsetWritingModeyöntemi vevertical-rlayarlayıcısı yoktur — dikey kompozisyon tercihe bağlıdır ve CSS güdümlüdür. - Temel alınan örnek, kendi başlığında belirtildiği üzere, bir uyumluluk dayanağı değil, bir entegrasyon duman testidir. 3. ve 4. aşamalar tamamlanana kadar, bu şekilde üretilen çıktı için PDF/UA-2 ve PDF/A-4 doğrulaması gerileyecektir. Bu yoldan üretilen çıktının uyumlu olduğunu belirtmeyin. Uyumluluğa bir denetleyici karar verir ve bu çıktıyı henüz geçirmez.
- Dikey yazım metrikleri altyapısı mevcuttur ancak dahilîdir. Bu altyapı,
CjkVerticalMetricsdeğer nesnesi ile/W2ve/DW2yayıcılarıdır. Kullanıcı alanına yönelik bir “dikey yaz” çağrısı olarak açığa çıkarılmamıştır ve sözlükleri yazıcı tarafından henüz yayılmamaktadır.
Kurulum
“Kurulum” başlıklı bölümcomposer require nextpdf/core:^3Sürüm kısıtı, nextpdf/core paketiyle eşleşir. Örnek PHP 8.4 üzerinde çalışır. Birlikte gelen Noto Sans TC test dayanağı, bu tarifi kendi içinde tamamlar.
Kavramsal genel bakış
“Kavramsal genel bakış” başlıklı bölümISO 32000-2, metin çıktısını üç katmanda modeller: Unicode kod noktası, karakter kodu ve glif kimliği. Bir CJK TrueType yazı tipi yüzü için motor, Identity-H kodlamasına sahip bileşik bir Type 0 yazı tipi kullanır. Bu kodlamada gösterilen dizgi, CIDFont’u dizinleyen bayt çiftlerinden oluşur (ISO 32000-2, reference_id=).
FontRegistry::register() yazı tipi yüzünü ayrıştırır. FontInfo::encodeText($unicodeText) ardından FontEncodingStrategyResolver aracılığıyla bir kodlama stratejisi belirler. Kayıtlı bir TrueType CJK yazı tipi yüzü söz konusu olduğunda, TrueTypeCmapStrategy stratejisine yönlendirir. Döndürülen EncodedGlyphRun, Identity-H bayt akışını, PDF dizgi işlenenini, glif başına ilerleme genişliklerini, kullanılan kod noktalarını ve GID→Unicode eşlemesini taşır. CJK alt kümeleme, ADR-008 uyarınca kullanılan kod noktalarını tüketir. Gelecekteki bir /ToUnicode akışı GID→Unicode eşlemesini kullanacaktır. Seçilen mod EncodingMode::TwoByteCid’dir.
PDF’de dikey yazımı iki CIDFont yapısı tanımlar. Birincisi, /W2 glif başına dikey metrikler dizisidir (ISO 32000-2, reference_id=). İkincisi, /DW2 varsayılan dikey metriklerdir (ISO 32000-2, reference_id=). NextPDF, her ikisi için değer nesnesini ve yayıcıları CjkVerticalMetrics::toW2Array(), toW2RangeArray() ve toDw2Array() aracılığıyla sağlar. Bunlar dahilîdir ve yazıcı bunları henüz yaymaz. Kapsam notuna bakın.
API yüzeyi
“API yüzeyi” başlıklı bölümFontRegistry::register(string $fontFile, string $alias = '', int $fontIndex = 0): FontInfo—NextPDF\Typography\FontRegistry.FontInfo::encodeText(string $unicodeText): EncodedGlyphRun—NextPDF\Typography\FontInfo. 1. aşama cephesi.EncodedGlyphRun—NextPDF\Typography\Encoding\EncodedGlyphRun(byteStream,pdfStringOperand,mode,advanceWidths,toUnicodeMap,usedCodepoints,glyphCount()).EncodingMode—NextPDF\Typography\Encoding\EncodingMode(SingleByte,TwoByteCid).CjkVerticalMetrics—NextPDF\Typography\CjkVerticalMetrics. Dahilî dikey metrikler değer nesnesi. Kullanıcı alanına yönelik bir yazım yolu olarak değil, şeffaflık amacıyla belgelenmiştir.
Tam PHPDoc tablosu kaynaktan üretilir.
Kod örneği — hızlı başlangıç
“Kod örneği — hızlı başlangıç” başlıklı bölüm<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Typography\Encoding\EncodingMode;use NextPDF\Typography\FontRegistry;
$registry = new FontRegistry();$font = $registry->register('/path/to/NotoSansTC-Regular.ttf', alias: 'NotoSansTC');
$encoded = $font->encodeText('PDF 2.0 引擎');
assert($encoded->mode === EncodingMode::TwoByteCid); // cmap-aware branch firedecho $encoded->glyphCount() . " glyph run entries\n";Kod örneği — üretim
“Kod örneği — üretim” başlıklı bölümBu örnek kendi içinde tamamdır ve test koşumunda çalıştırılabilir. examples/35-cjk-cmap-demo.php dosyasını yansıtır. Önce, birlikte gelen Noto Sans TC dayanağını kaydedin. Ardından, cmap’e duyarlı cepheye erişilebildiğini kanıtlayın. Sonra, doldurulmuş kayıt defterinin kullanılması için DocumentFactory üzerinden oluşturun.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\Encoding\EncodingMode;use NextPDF\Typography\FontRegistry;
$cjkFontPath = dirname(__DIR__, 2) . '/fonts/test-fixtures/Noto Sans TC/NotoSansTC-Regular.ttf';if (!is_file($cjkFontPath)) { fwrite(STDERR, "Missing CJK font fixture: {$cjkFontPath}\n"); exit(1);}
$fontRegistry = new FontRegistry();$cjkFont = $fontRegistry->register($cjkFontPath, alias: 'NotoSansTC');
// Phase 1 facade: prove the cmap-aware path is reachable from userland.$cjkSample = 'PDF 2.0 引擎 — 使用 CMap 編碼';$encoded = $cjkFont->encodeText($cjkSample);
if ($encoded->mode !== EncodingMode::TwoByteCid) { fwrite(STDERR, "Expected TwoByteCid (TrueTypeCmapStrategy branch)\n"); exit(2);}
$imageRegistry = new ImageRegistry(maxCacheBytes: 0);$documentFactory = new DocumentFactory($fontRegistry, $imageRegistry);
$doc = $documentFactory->create();$doc->setTitle('NextPDF CJK CMap-Aware Encoding Demo');$doc->setLanguage('zh-Hant');$doc->addPage();
$doc->setFont('helvetica', 'B', 16);$doc->cell(0, 12, 'CJK cmap-aware encoding (Phase 1 facade)', newLine: true);$doc->setFont('helvetica', '', 10);$doc->cell(0, 6, 'Mode: ' . $encoded->mode->name . ' (Identity-H, 2-byte CIDs)', newLine: true);$doc->cell(0, 6, 'Glyphs: ' . $encoded->glyphCount() . ' run entries', newLine: true);$doc->cell(0, 6, 'Bytes: ' . strlen($encoded->byteStream) . ' encoded bytes', newLine: true);$doc->ln(4);
$doc->setFont('NotoSansTC', '', 18);$doc->cell(0, 12, $cjkSample, newLine: true);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false ? $out : __DIR__ . '/cjk-vertical-writing.pdf');
echo "Wrote cjk-vertical-writing.pdf (Phase 1+2 dry-run; not a conformance fixture)\n";Beklenen STDOUT:
Wrote cjk-vertical-writing.pdf (Phase 1+2 dry-run; not a conformance fixture)Sınır durumları ve tuzaklar
“Sınır durumları ve tuzaklar” başlıklı bölüm- Bir uyumluluk dayanağı değildir. Temel alınan örneğin kendi başlığında belirtildiği üzere, bu çıktı bir entegrasyon duman testidir. 3. ve 4. aşamalar tamamlanana kadar, bunun için PDF/UA-2 ve PDF/A-4 denetimleri gerileyecektir. Bunu bir uyumluluk altın referansı olarak kaydetmeyin.
- Buyurgan belge yazım modu API’si yoktur.
setWritingMode()gibi herkese açık birDocumentçağrısı vevertical-rl/vertical-lrayarlayıcısı yoktur. Deneysel HTML/CSS dikey oluşturucu ayrıdır, tercihe bağlıdır velayoutVerticalComposerbayrağı üzerinden CSS güdümlüdür (kapsam notuna bakın)./W2ve/DW2yayıcıları dahilî olarak mevcuttur. Bunlar açığa çıkarılmamıştır ve henüz yazı tipi sözlüğüne yazılmaz. - Kayıt defteri sahipliği.
Document::createStandalone()kendi kayıt defterini oluşturur. Belgenin, CJK yazı tipi yüzüyle doldurduğunuz kayıt defterini okuması içinDocumentFactorykullanın. - Son bayt akışı yolu. 2. aşama tamamlanana kadar, görünür içerik akışı hâlâ eski metin yolundan geçer. Şu anda kanıtlanmış ve erişilebilir olan kısım, üst akıştaki kodlama adımıdır: cmap ileri araması artı Identity-H bayt akışı.
- CJK alt kümeleme maliyeti. Büyük CJK yazı tipi yüzleri, yalıtılmış bir alt süreç aracılığıyla alt kümelenir. Bu alt sürecin PHP’ye özgü bir yedeği ve iki saniyelik bir zaman aşımı vardır (ADR-008).
Performans
“Performans” başlıklı bölümencodeText(), girdi üzerinde tek bir cmap ileri arama geçişidir. Kod noktası sayısına göre doğrusaldır, O(n). Bütçe wall_ms: 2000, peak_mb: 128 değerindedir. Bu kümedeki en yüksek bütçe budur; çünkü CJK yazı tipi yüzleri büyüktür ve baskın maliyet alt kümelemedir. ADR-008, çağıranı bloke edememesi için bu işi yalıtır.
Güvenlik notları
“Güvenlik notları” başlıklı bölümBir CJK yazı tipi dosyası, güvenilmeyen ikili girdidir. Ayrıştırıcı, akış sarmalayıcı yollarını ve boş baytları reddeder. CJK alt kümeleme, devralınan durumu olmayan yalıtılmış bir alt süreçte çalışır (ADR-008). Son kullanıcıların sağladığı yazı tipi yüzlerinin kaynağını doğrulayın. CJK metin içeriği yorumlanmaz, işlenir.
Uyumluluk
“Uyumluluk” başlıklı bölüm| İfade | Belirtim | Madde | reference_id |
|---|---|---|---|
| Bir Identity-H/Identity-V Type 0 yazı tipi için, gösterilen dizgi CIDFont’u dizinleyen bayt çiftleridir. | ISO 32000-2 | iso32000_2_sec9#x1.x49.p90 | |
| W2 dizisi, glif başına dikey yazım metriklerini verir ve yalnızca dikey yazım için kullanılan CIDFont’lara uygulanır. | ISO 32000-2 | iso32000_2_sec9#x1.x44.p23 | |
| DW2 dizisi, bir CIDFont için varsayılan dikey yazım metriklerini verir. | ISO 32000-2 | iso32000_2_sec9#x1.x44.p22 |
Bu tarif, cmap’e duyarlı CJK kodlama cephesinin kullanıcı alanından erişilebilir olduğunu gösterir (1. aşama). Üretilen dosya için dikey yazım çıktısı veya PDF/UA-2 / PDF/A-4 uyumluluğu iddia etmez. Yazıcı tarafındaki /ToUnicode ve dikey metrikler çıktısı (3. ve 4. aşamalar) beklemededir ve bir denetleyici bu çıktıyı şu anda geçirmez.
Ticari bağlam
“Ticari bağlam” başlıklı bölümUygulanamaz.