CJK metnini cmap'e duyarlı kodlamayla ayarlama
Bir bakışta
“Bir bakışta” başlıklı bölümBu tarif, bir Çince, Japonca ve Korece (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ışı döndürür. Tarif, examples/35-cjk-cmap-demo.php dosyasını izler. Buna güvenmeden önce 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şleyicinin ve yazıcının cephe üzerinden yönlendirilmesini kapsar. 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ı.
Planlamanızı şu sonuçları göz önünde bulundurarak yapın:
- Bu tarif, eksiksiz bir dikey yazım modunu değil, kodlama cephesini gösterir. Belge yüzeyinde şu anda herkese açık bir yazım modu API’si yoktur; bu nedenle
setWritingModeçağrısı vevertical-rlayarlayıcısı bulunmaz. - 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ı PDF/UA-2 ve PDF/A-4 doğrulamasından geçmez. 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 dahilidir.
CjkVerticalMetricsdeğer nesnesini ve/W2ile/DW2yayıcılarını içerir. NextPDF bunu kullanıcı alanına bir “dikey yaz” çağrısı olarak açmaz ve yazıcı sözlüklerini henüz yaymaz.
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).
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 kod noktalarını kullanır. 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). İkincisi, /DW2 varsayılan dikey metriklerdir (ISO 32000-2). NextPDF, her ikisi için değer nesnesini ve yayıcıları CjkVerticalMetrics::toW2Array(), toW2RangeArray() ve toDw2Array() aracılığıyla sağlar. Bunlar dahilidir 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. Dahili 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 doğrulayın. Sonra, belgenin sizin doldurduğunuz kayıt defterini kullanması 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 geçmez. Bunu bir uyumluluk altın referansı olarak kaydetmeyin.
- Yazım modu API’si yoktur. Herkese açık hiçbir çağrı,
vertical-rlvevertical-lrmodlarını kapsayacak dikey yazıma geçiş yapmaz./W2ve/DW2yayıcıları dahili 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 kullanması 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ıyla birlikte 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şi yapar. 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 etmemesi 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.