콘텐츠로 이동

오른쪽에서 왼쪽으로 쓰는 아랍어 HTML 렌더링

오른쪽에서 왼쪽으로 쓰는(RTL) HTML을 writeHtml()로 PDF에 렌더링합니다. CSS direction: rtl 속성을 설정하고 아랍어 지원 글꼴을 등록합니다. 엔진은 유니코드 양방향 알고리즘(UAX #9)에 따라 텍스트를 시각적 순서로 재정렬하고, 아랍어 글자를 문맥에 맞는 형식으로 처리합니다. 이 레시피에서는 작은 아랍어 송장을 렌더링합니다. RTL은 아랍어, 히브리어, 페르시아어, 우르두어에 적용됩니다. 히브리어는 재정렬되지만 글자 모양 처리는 수행되지 않으며, 이는 해당 문자 체계에서 올바른 동작입니다.

Terminal window
composer require nextpdf/core

아랍어를 지원하는 TrueType 또는 OpenType 글꼴도 필요합니다. 글꼴의 문자 맵에는 아랍어 표현 형식-B(Arabic Presentation Forms-B) 블록이 포함되어야 합니다. Noto Naskh Arabic과 Amiri는 적합한 오픈 라이선스 페이스입니다.

RTL 렌더링에는 CSS direction: rtl 속성과 등록된 아랍어 글꼴이라는 두 가지 입력이 필요합니다.

direction: rtl은 레이아웃에 텍스트를 오른쪽에서 왼쪽으로 배치하라고 지시합니다. 그러면 엔진은 유니코드 양방향 알고리즘(UAX #9)을 사용해 시각적 순서를 해석합니다. 혼합 콘텐츠도 올바르게 정렬됩니다. 라틴 단어, 아랍어 단어, 숫자는 각각 고유한 방향을 유지합니다. 아랍어 텍스트 뒤에 오는 숫자는 자릿수를 왼쪽에서 오른쪽 순서로 유지합니다.

아랍어는 필기체 문자 체계이므로 각 글자는 이웃 글자에 따라 다른 글리프를 사용합니다. 엔진은 각 글자에 대해 초성, 중성, 종성 또는 단독 형식을 선택하고 Lam-Alef 합자를 적용합니다. 이러한 문맥 기반 글자 모양 처리에는 문자 맵이 아랍어 표현 형식-B(Arabic Presentation Forms-B) 블록을 포함하는 글꼴이 필요합니다. 표준 14개 페이스를 포함한 라틴 전용 글꼴로는 아랍어를 그릴 수 없습니다.

표에서는 각 셀이 독립적으로 재정렬되고 글자 모양이 처리되며, 셀은 시작 가장자리에 정렬됩니다. direction: rtl에서는 이 시작 가장자리가 오른쪽 가장자리입니다. 논리적 text-align 값인 startend는 방향에 따라 해석되므로, RTL 콘텐츠에서 start는 오른쪽 가장자리에 매핑됩니다.

방향은 CSS direction 속성으로 설정합니다. HTML dir 속성은 이 속성에 매핑되지 않습니다. 현재 구현상의 경계는 RTL — 현재 제한 사항을 참조하십시오.

심볼위치역할
Document::writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutput현재 커서 위치에서 HTML 조각을 렌더링합니다.
FontRegistry::register(string $fontFile, string $alias = '', int $fontIndex = 0): FontInfoNextPDF\Typography\FontRegistry아랍어 페이스를 별칭으로 등록합니다.
DocumentFactory::create(): DocumentNextPDF\Core\DocumentFactory채워진 레지스트리를 읽는 문서를 생성합니다.

이 예제는 다음 CSS 속성을 사용합니다: direction, font-family, text-align. CSS font-family에서는 등록된 글꼴을 해당 레지스트리 별칭으로 참조합니다.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Typography\FontRegistry;
$fontRegistry = new FontRegistry();
$fontRegistry->register(__DIR__ . '/NotoNaskhArabic-Regular.ttf', alias: 'ArabicFont');
$documentFactory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));
$doc = $documentFactory->create();
$doc->addPage();
$doc->writeHtml(
'<div style="direction: rtl; font-family: \'ArabicFont\';">'
. '<h1>فاتورة</h1>'
. '<p>المبلغ الإجمالي 380.00</p>'
. '</div>'
);
$doc->save(__DIR__ . '/rtl-arabic.pdf');

제목은 오른쪽에서 왼쪽으로 렌더링되고, 숫자 380.00은 아랍어 문장 안에서도 왼쪽에서 오른쪽 순서를 유지합니다.

이 자체 완결형 예제는 아랍어 송장 표를 렌더링합니다. 각 셀에 direction: rtl과 등록된 아랍어 글꼴이 포함되어 있으므로, 엔진은 모든 줄을 재정렬하고 글자 모양을 처리한 다음 셀을 오른쪽 가장자리에 정렬합니다.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Typography\FontRegistry;
// Supply an Arabic-capable face whose cmap covers Arabic Presentation Forms-B.
// Embed only fonts you are licensed to embed.
$fontPath = __DIR__ . '/NotoNaskhArabic-Regular.ttf';
if (!is_file($fontPath)) {
fwrite(STDERR, "Arabic font not found at {$fontPath}\n");
exit(1);
}
$fontRegistry = new FontRegistry();
$fontRegistry->register($fontPath, alias: 'ArabicFont');
$documentFactory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));
$doc = $documentFactory->create();
$doc->setTitle('Arabic invoice');
$doc->addPage();
$html = <<<'HTML'
<div style="direction: rtl; font-family: 'ArabicFont'; font-size: 12pt;">
<h1>فاتورة</h1>
<table style="width: 100%; border-collapse: collapse;">
<tr>
<th style="border: 1px solid #333; padding: 6px;">الوصف</th>
<th style="border: 1px solid #333; padding: 6px;">المبلغ</th>
</tr>
<tr>
<td style="border: 1px solid #333; padding: 6px;">خدمات استشارية</td>
<td style="border: 1px solid #333; padding: 6px;">380.00</td>
</tr>
<tr>
<td style="border: 1px solid #333; padding: 6px;">الإجمالي</td>
<td style="border: 1px solid #333; padding: 6px;">380.00</td>
</tr>
</table>
</div>
HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_OUT');
$doc->save($out !== false ? $out : __DIR__ . '/render-rtl-arabic-html.pdf');
echo "Wrote the Arabic invoice PDF\n";
HTML;$doc->writeHtml($html);$out = getenv('NEXTPDF_OUT');$doc->save($out !== false ? $out : __DIR__ . '/render-rtl-arabic-html.pdf');echo "Wrote the Arabic invoice PDF\n";">
  • 문서를 빌드하기 전에 글꼴을 등록하십시오. Document::createStandalone()은 자체 레지스트리를 구성하므로 다른 곳에서 등록한 페이스를 볼 수 없습니다. 두 샘플처럼 DocumentFactory를 통해 빌드하여 작성기가 사용자의 레지스트리를 읽도록 하십시오.
  • CSS font-family를 레지스트리 별칭과 일치시키십시오. register(..., alias: 'ArabicFont')에 전달하는 이름이 CSS에서 참조하는 이름입니다.
  • HTML dir 속성이 아니라 CSS direction을 사용하십시오. CSS 속성만이 레이아웃을 전환합니다.
  • 아랍어 뒤의 숫자는 왼쪽에서 오른쪽으로 유지됩니다. 이는 UAX #9를 따릅니다. 아랍어 글자 뒤에 오는 유럽 숫자는 아랍 숫자로 해석되어 자릿수 순서를 유지하므로, 380.00은 뒤집히지 않습니다.

현재 구현은 RTL 텍스트를 재정렬하고 글자 모양을 처리하며 표 셀을 정렬합니다. 다음 경계는 남아 있습니다. 각 항목에는 향후 줄 단위 인라인 서식을 위한 줄 상자가 필요합니다:

  • 표 외부의 블록 및 인라인 정렬. 표 셀 외부의 블록 수준 및 인라인 텍스트는 재정렬되고 글자 모양이 처리되지만, 시작(왼쪽) 가장자리에서 렌더링됩니다. 표가 아닌 텍스트의 오른쪽 또는 가운데 정렬, 그리고 text-align: justify 분배는 아직 적용되지 않습니다. 표 셀은 정렬됩니다.
  • HTML dir 속성은 direction에 매핑되지 않습니다. 방향은 CSS direction 속성으로 설정하십시오.
  • 양방향 해석은 텍스트 런 단위로 이루어집니다. 중립 문자는 같은 줄에 있는 <span> 옆의 <b>처럼 두 인라인 요소에 걸쳐 해석되지 않습니다.
  • 좁은 아랍어 열은 논리적 텍스트로 측정됩니다. 줄바꿈은 논리적이고 글자 모양을 처리하기 전인 텍스트로 측정되므로, 매우 좁은 아랍어 열에서는 줄이 약간 이르거나 늦게 끊길 수 있습니다.
  • 글자 모양이 처리된 아랍어에는 표현 형식-B(Presentation Forms-B) 적용 범위가 필요합니다. 페이스는 아랍어 표현 형식-B(Arabic Presentation Forms-B) 블록을 포함해야 합니다. OpenType GSUB 치환에만 의존하는 글꼴과 HarfBuzz 모양 처리 경로는 향후 작업입니다. 아랍어가 아닌 글꼴은 아랍어를 그릴 수 없습니다.

렌더링은 글리프 수에 따라 선형적으로 확장됩니다. 양방향 재정렬과 문맥 기반 글자 모양 처리는 줄 단위로 실행되며, 왼쪽에서 오른쪽으로 쓰는 텍스트보다 작은 상수 계수를 추가합니다. 이 레시피의 예산은 wall_ms: 1500, peak_mb: 64입니다.

출력 크기를 제한하려면 사용자가 제공한 문자열의 길이를 검증하십시오. 엔진은 텍스트를 렌더링할 뿐 해석하지 않으며 어떤 스크립트도 실행하지 않습니다. 원격 @font-face 소스를 통해 글꼴을 로드하는 경우, 보안 외부 리소스 정책이 가져오기를 관장합니다. 예측 가능한 출력을 위해서는 로컬 글꼴 파일을 사용하는 것이 좋습니다.

진술사양reference_id
시각적 순서는 가장 높은 수준에서 가장 낮은 홀수 수준까지 문자 런을 뒤집어 생성됩니다.Unicode UAX #9§3.3.6 Rule L2 (uax9#3.3.6.p13)814977a77019d728dc562a612098a82dc260f6844f5998eca5fe7a3baf3394af
아랍어 글자 뒤에 오는 유럽 숫자는 아랍 숫자로 해석되므로, 그 자릿수는 왼쪽에서 오른쪽 순서를 유지합니다.Unicode UAX #9§3.3.4 Rule W2 (uax9#3.3.4.p9)5747405357772797d62b3f4ba79328557fa0c4273a1dd5ffa8d996f24c78e120

아랍어 문맥 기반 글자 모양 처리(초성, 중성, 종성, 단독 형식과 Lam-Alef 합자)는 별도의 적합성 주장이 아니라 테스트 스위트가 다루는 검증된 엔진 기능입니다. 이 기능에는 문자 맵이 아랍어 표현 형식-B(Arabic Presentation Forms-B) 블록을 포함하는 글꼴이 필요합니다.

해당 없음.