Przejdź do głównej zawartości
getnextpdf.com

Tworzenie plików PDF CJK i arabskich z poprawnym kopiowaniem i wklejaniem

Utwórz plik Portable Document Format (PDF) z tekstem chińskim, japońskim, koreańskim (CJK) i arabskim, który kopiuje się i wkleja jako oryginalne znaki logiczne. Silnik odwzorowuje każdy glif na Unicode za pomocą mapy CMap /ToUnicode, kanonikalizuje wynik z użyciem Normalization Form Compatibility Composition (NFKC) i opakowuje ukształtowane lub rozstrzelone przebiegi w /Span zawierający /ActualText. Zarejestruj czcionki i zapisz treść; wyodrębnianie pozostanie poprawne. Weryfikuj wyodrębnianie za pomocą pdftotext/Poppler, a nie PyMuPDF; veraPDF waliduje PDF/Universal Accessibility 2 (PDF/UA-2), a nie samo wyodrębnianie.

Okno terminala
composer require nextpdf/core

Zarejestruj czcionkę CJK, taką jak Noto Sans CJK, oraz czcionkę obsługującą arabski, z mapą znaków obejmującą blok Arabic Presentation Forms-B, taką jak Noto Naskh Arabic. Osadzaj tylko czcionki, na których osadzanie masz licencję.

Kody glifów w strumieniu treści nie są kodami Unicode. Mapa CMap /ToUnicode odwzorowuje każdy kod z powrotem na Unicode, dzięki czemu czytnik może wyodrębnić tekst (ISO 32000-2 §9.10). Silnik kanonikalizuje te wartości za pomocą Normalization Form Compatibility Composition (NFKC), zdefiniowanej w Unicode UAX #15. Ideogram zgodności CJK oraz arabska forma prezentacyjna odwzorowują się na odpowiedni znak bazowy, więc wyszukiwanie i kopiowanie zwracają tekst kanoniczny zamiast punktu kodowego zgodności.

Dwa przypadki wymagają czegoś więcej niż /ToUnicode: rozstrzelona łacina i ukształtowany arabski pisany od prawej do lewej. Silnik rysuje je jako rozstrzelone lub przestawione glify, więc sama kolejność glifów nie pozwala odtworzyć łańcucha logicznego. Każdy przebieg opakowuje w sekwencję treści oznaczonej /Span zawierającą /ActualText, czyli dokładne zastąpienie zawartej treści (ISO 32000-2 §14.9). Narzędzia wyodrębniające, które respektują /ActualText, zwracają łańcuch logiczny.

SymbolLokalizacjaRola
FontRegistry::register(string $fontFile, string $alias = ''): FontInfoNextPDF\Typography\FontRegistryRejestruje kroje CJK i arabskie.
DocumentFactory::create(): DocumentNextPDF\Core\DocumentFactoryBuduje dokument korzystający z tego rejestru.
Document::writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutputRenderuje treść wielojęzyczną.
<?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');
Okno terminala
pdftotext multilingual.pdf - | head
# Extracts the logical text: "PDF 2.0 引擎 — 量子" and the logical Arabic "فاتورة",
# not compatibility code points or reversed presentation forms.

Ten samodzielny przykład otagowuje dokument, dodaje rozstrzelony nagłówek i zapisuje wynik w ścieżce środowiska testowego.

<?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";

Uruchom pdftotext dla wyniku. Rozstrzelony nagłówek wyodrębnia się jako CODE WORD bez wstawionych spacji, wiersz CJK wyodrębnia się jako znaki bazowe, a wiersz arabski jako łańcuch logiczny.

  • Weryfikuj wyodrębnianie za pomocą pdftotext, a nie PyMuPDF. Tryb surowego tekstu w PyMuPDF ignoruje wbudowany /ActualText i zwraca wizualne glify, więc może zaniżać ocenę poprawności. Poppler (pdftotext) respektuje /ActualText; veraPDF waliduje PDF/UA-2, a nie samo wyodrębnianie.
  • Wyodrębnianie wymaga /ToUnicode. Zarejestruj i osadź czcionki, aby writer wyemitował mapę CMap /ToUnicode. Nieosadzona, niestandardowa czcionka nie może zagwarantować odwzorowania na Unicode.
  • /ActualText obejmuje przebiegi ukształtowane i rozstrzelone. Dla zwykłego, nieukształtowanego, nierozstrzelonego tekstu sama mapa /ToUnicode wyodrębnia poprawnie; opakowanie /Span zachowuje przebiegi rozstrzelone lub przestawione.
  • Otagowane tabele HTML przechodzą walidację PDF/UA-2. Wyodrębnianie jest poprawne, a otagowana tabela HTML <table> przechodzi teraz walidację veraPDF --flavour ua2 bez żadnych błędów — zobacz Dostępność.

Budowanie mapy CMap /ToUnicode oraz opakowań /Span skaluje się liniowo z liczbą glifów. Ten przepis przyjmuje budżet wall_ms: 1500, peak_mb: 96.

Sprawdzaj długość wielojęzycznych łańcuchów dostarczonych przez użytkownika, aby rozmiar wyjścia pozostawał ograniczony. Konstruktor /ToUnicode odrzuca połówki par zastępczych i kody spoza przestrzeni kodowej, więc zniekształcona mapa nie może utworzyć uszkodzonego zasobu wyodrębniania. Silnik nie uruchamia żadnych skryptów i nie pobiera zdalnych zasobów w przypadku czcionek lokalnych.

StwierdzenieSpecyfikacjaKlauzula
Mapa CMap /ToUnicode odwzorowuje kody znaków na Unicode na potrzeby wyodrębniania.ISO 32000-2§9.10
/ActualText jest dokładnym zastąpieniem zawartej treści.ISO 32000-2§14.9
NFKC to dekompozycja zgodności, po której następuje kompozycja kanoniczna.Unicode UAX #15§1.2

Nie dotyczy.