İçeriğe geç

CJK metnini cmap'e duyarlı kodlamayla ayarlama

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

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ş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ı ve vertical-rl ayarlayı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. CjkVerticalMetrics değer nesnesini ve /W2 ile /DW2 yayı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.
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).

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.

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

<?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 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)
  • 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-rl ve vertical-lr modlarını kapsayacak dikey yazıma geçiş yapmaz. /W2 ve /DW2 yayı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ç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ı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).

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

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.