İçeriğe geç
getnextpdf.com

kararlılık: Deneysel

CJK metnini cmap'e duyarlı kodlamayla ayarlama

Bu 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.

cmap’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-lr değerlerini süren layoutVerticalComposer bayrağı); bkz. Dikey yazım modu. Belge yüzeyinde hâlâ buyurgan bir setWritingMode yöntemi ve vertical-rl ayarlayı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ı, CjkVerticalMetrics değer nesnesi ile /W2 ve /DW2 yayı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.
Terminal window
composer require nextpdf/core:^3

Sü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.

ISO 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.

  • FontRegistry::register(string $fontFile, string $alias = '', int $fontIndex = 0): FontInfoNextPDF\Typography\FontRegistry.
  • FontInfo::encodeText(string $unicodeText): EncodedGlyphRunNextPDF\Typography\FontInfo. 1. aşama cephesi.
  • EncodedGlyphRunNextPDF\Typography\Encoding\EncodedGlyphRun (byteStream, pdfStringOperand, mode, advanceWidths, toUnicodeMap, usedCodepoints, glyphCount()).
  • EncodingModeNextPDF\Typography\Encoding\EncodingMode (SingleByte, TwoByteCid).
  • CjkVerticalMetricsNextPDF\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.

<?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 fired
echo $encoded->glyphCount() . " glyph run entries\n";

Bu ö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)
  • 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 bir Document çağrısı ve vertical-rl / vertical-lr ayarlayıcısı yoktur. Deneysel HTML/CSS dikey oluşturucu ayrıdır, tercihe bağlıdır ve layoutVerticalComposer bayrağı üzerinden CSS güdümlüdür (kapsam notuna bakın). /W2 ve /DW2 yayı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çin DocumentFactory kullanı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).

encodeText(), 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.

Bir 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.

İfadeBelirtimMaddereference_id
Bir Identity-H/Identity-V Type 0 yazı tipi için, gösterilen dizgi CIDFont’u dizinleyen bayt çiftleridir.ISO 32000-2iso32000_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-2iso32000_2_sec9#x1.x44.p23
DW2 dizisi, bir CIDFont için varsayılan dikey yazım metriklerini verir.ISO 32000-2iso32000_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.

Uygulanamaz.