Lewati ke konten
getnextpdf.com

Buat PDF CJK dan Arab yang tetap benar saat disalin-tempel

Buat berkas Portable Document Format (PDF) dengan teks Tionghoa, Jepang, Korea (CJK), dan Arab yang ketika disalin dan ditempel tetap berupa karakter logis aslinya. Mesin memetakan setiap glif ke Unicode melalui CMap /ToUnicode, mengkanonikalisasi hasilnya dengan Normalization Form Compatibility Composition (NFKC), dan membungkus run yang dibentuk atau berjarak antarhuruf dalam /Span yang membawa /ActualText. Daftarkan fon lalu tulis kontennya; ekstraksi tetap benar. Verifikasi ekstraksi dengan pdftotext/Poppler, bukan PyMuPDF; veraPDF memvalidasi PDF/Universal Accessibility 2 (PDF/UA-2), bukan hasil ekstraksi.

Terminal window
composer require nextpdf/core

Daftarkan satu fon CJK, misalnya Noto Sans CJK, dan satu fon berkemampuan Arab yang peta karakternya mencakup blok Arabic Presentation Forms-B, misalnya Noto Naskh Arabic. Sematkan hanya fon yang lisensinya mengizinkan Anda untuk menyematkannya.

Kode glif dalam aliran konten bukanlah Unicode. CMap /ToUnicode memetakan setiap kode kembali ke Unicode sehingga pembaca dapat mengekstraksi teks (ISO 32000-2 §9.10). Mesin mengkanonikalisasi nilai tersebut dengan Normalization Form Compatibility Composition (NFKC), seperti yang didefinisikan oleh Unicode UAX #15. CJK Compatibility Ideograph dan bentuk presentasi Arab dipetakan ke karakter dasarnya, sehingga pencarian dan penyalinan mengembalikan teks kanonis, bukan titik kode kompatibilitas.

Dua kasus membutuhkan lebih dari sekadar /ToUnicode: teks Latin berjarak antarhuruf dan teks Arab kanan-ke-kiri yang dibentuk. Mesin merendernya sebagai glif yang berjarak atau diurutkan ulang, sehingga urutan glif saja tidak dapat memulihkan string logis. Mesin membungkus setiap run dalam urutan marked-content /Span yang membawa /ActualText, sebagai pengganti persis untuk konten yang dilingkupinya (ISO 32000-2 §14.9). Ekstraktor yang menghormati /ActualText akan mengembalikan string logis.

SimbolLokasiPeran
FontRegistry::register(string $fontFile, string $alias = ''): FontInfoNextPDF\Typography\FontRegistryDaftarkan muka fon untuk CJK dan Arab.
DocumentFactory::create(): DocumentNextPDF\Core\DocumentFactoryBangun dokumen yang menggunakan registri Anda.
Document::writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutputRender konten multibahasa.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Typography\FontRegistry;
$fonts = new FontRegistry();
$fonts->register(__DIR__ . '/NotoSansCJK-Regular.ttf', alias: 'CJK');
$fonts->register(__DIR__ . '/NotoNaskhArabic-Regular.ttf', alias: 'Arabic');
$doc = (new DocumentFactory($fonts, new ImageRegistry(maxCacheBytes: 0)))->create();
$doc->addPage();
$doc->writeHtml(
'<p style="font-family: \'CJK\';">PDF 2.0 引擎 — 量子</p>'
. '<p style="direction: rtl; font-family: \'Arabic\';">فاتورة</p>'
);
$doc->save(__DIR__ . '/multilingual.pdf');
Terminal window
pdftotext multilingual.pdf - | head
# Extracts the logical text: "PDF 2.0 引擎 — 量子" and the logical Arabic "فاتورة",
# not compatibility code points or reversed presentation forms.

Contoh mandiri ini memberi tag pada dokumen, menambahkan judul dengan jarak antarhuruf, dan menulis ke jalur harness.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Typography\FontRegistry;
$fonts = new FontRegistry();
$fonts->register(__DIR__ . '/NotoSansCJK-Regular.ttf', alias: 'CJK');
$fonts->register(__DIR__ . '/NotoNaskhArabic-Regular.ttf', alias: 'Arabic');
$doc = (new DocumentFactory($fonts, new ImageRegistry(maxCacheBytes: 0)))->create();
$doc->setTitle('Multilingual extraction');
$doc->enableTaggedPdf('en');
$doc->addPage();
$html = <<<'HTML'
<h1 style="font-family: 'CJK'; letter-spacing: 3px;">CODE WORD</h1>
<p style="font-family: 'CJK';">中文 · 日本語 · 한국어 · 量子 (compatibility ideograph)</p>
<p style="direction: rtl; font-family: 'Arabic';">المبلغ الإجمالي 380.00</p>
HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_OUT');
$doc->save($out !== false ? $out : __DIR__ . '/multilingual-copy-paste-extraction.pdf');
echo "Wrote the multilingual PDF\n";

Jalankan pdftotext pada hasil keluarannya. Judul dengan jarak antarhuruf terekstraksi sebagai CODE WORD tanpa spasi yang disisipkan, baris CJK terekstraksi sebagai karakter dasarnya, dan baris Arab terekstraksi sebagai string logis.

  • Verifikasi ekstraksi dengan pdftotext, bukan PyMuPDF. Mode teks mentah PyMuPDF mengabaikan /ActualText inline dan mengembalikan glif visual, sehingga dapat melaporkan akurasi yang lebih rendah dari semestinya. Poppler (pdftotext) menghormati /ActualText; veraPDF memvalidasi PDF/UA-2, bukan hasil ekstraksi.
  • Ekstraksi membutuhkan /ToUnicode. Daftarkan dan sematkan fon agar penulis menghasilkan CMap /ToUnicode. Fon non-standar yang tidak disematkan tidak dapat menjamin pemetaan Unicode.
  • /ActualText mencakup run yang dibentuk dan run berjarak antarhuruf. Untuk teks biasa yang tidak dibentuk dan tidak diberi jarak, /ToUnicode saja sudah mengekstraksi dengan benar; pembungkus /Span mempertahankan run yang berjarak atau diurutkan ulang.
  • Tabel HTML bertanda lulus pemeriksaan PDF/UA-2. Ekstraksi tetap benar, dan sebuah <table> HTML bertanda kini lulus veraPDF --flavour ua2 dengan nol kegagalan — lihat Aksesibilitas.

Pembuatan CMap /ToUnicode dan pembungkus /Span berskala linear terhadap jumlah glif. Resep ini menetapkan anggaran wall_ms: 1500, peak_mb: 96.

Validasi panjang string multibahasa yang disediakan pengguna agar ukuran keluaran tetap terbatas. Pembangun /ToUnicode menolak separuh surrogate dan kode di luar codespace, sehingga peta yang cacat tidak dapat menciptakan sumber daya ekstraksi yang rusak. Mesin tidak menjalankan skrip apa pun dan tidak mengambil sumber daya jarak jauh untuk fon lokal.

PernyataanSpesifikasiKlausa
CMap /ToUnicode memetakan kode karakter ke Unicode untuk ekstraksi.ISO 32000-2§9.10
/ActualText adalah pengganti persis untuk konten yang dilingkupinya.ISO 32000-2§14.9
NFKC adalah dekomposisi kompatibilitas yang diikuti komposisi kanonis.Unicode UAX #15§1.2

Tidak berlaku.