تضمين خط TrueType وإنشاء مجموعة فرعية منه
لمحة سريعة
قسم بعنوان «لمحة سريعة»سجّل خط TrueType، واعرض النص به، واترك أداة الكتابة تضمّن المجموعة الفرعية المطلوبة فقط. تتبع هذه الوصفة مسار المحتوى نفسه الذي يتبعه examples/04-text-and-fonts.php، مع إضافة خط TrueType (.ttf) مُسجَّل.
التثبيت
قسم بعنوان «التثبيت»composer require nextpdf/core:^3يثبّت هذا القيد حزمة nextpdf/core. يعمل المثال على PHP 8.4، ويجعل تجهيز الاختبار المُضمَّن LiberationSans-Regular.ttf الوصفة مكتفية ذاتيًا.
نظرة مفاهيمية عامة
قسم بعنوان «نظرة مفاهيمية عامة»سجّل وجه خط باستخدام FontRegistry::register($path, $alias). يحلّل السجل الملف ويُرجع FontInfo، مستخدمًا TrueTypeParser لملفات .ttf و.otf. لتفعيل الوجه، حدّد اسمه المستعار باستخدام setFont($alias, ...). يسجّل هذا الاستدعاء أيضًا النقاط الرمزية المستخدمة.
تُنشَأ المجموعة الفرعية تلقائيًا عند save(). يجمع كاتب خط PDF النقاط الرمزية المستخدمة ويستدعي FontSubsetter::subset()، أو CffSubsetter لوجوه خطوط Compact Font Format (CFF) أو OpenType. عندما تكون المجموعة الفرعية أصغر من البرنامج الكامل، تضمّن أداة الكتابة المجموعة الفرعية. وتعيد أيضًا كتابة BaseFont وFontName بوسم مجموعة فرعية مكوَّن من ستة أحرف كبيرة موصولة بعلامة زائد. هذه هي صيغة ABCDEF+FontName التي يشترطها ISO 32000-2 للمجموعة الفرعية من الخط. تخزّن أداة الكتابة برنامج TrueType المُضمَّن بوصفه FontFile2 في واصف الخط (ISO 32000-2).
تُولَّد بادئة المجموعة الفرعية على نحو حتمي من اسم PostScript، لذا يُنتج البناء الحتمي وسمًا ثابتًا. لهذا السبب يكون ملف قابلية إعادة الإنتاج لهذه الوصفة structural. يطبّع الملف الهيكلي بادئة المجموعة الفرعية ومذيّل /ID بدلًا من التحقق منهما بايتًا ببايت.
واجهة API
قسم بعنوان «واجهة API»FontRegistry::register(string $fontFile, string $alias = '', int $fontIndex = 0): FontInfo—NextPDF\Typography\FontRegistry.setFont(string $family, string $style = '', float $size = 12.0): static—NextPDF\Core\Concerns\HasTypography؛ مرّر الاسم المستعار المُسجَّل بوصفه$family.- إنشاء المجموعة الفرعية عملية داخلية في أداة الكتابة (
NextPDF\Writer\PdfFontWriter->NextPDF\Typography\FontSubsetter). لا يوجد مفتاح عام للتشغيل أو الإيقاف: تُنشئ أداة الكتابة المجموعة الفرعية دائمًا عندما تكون النقاط الرمزية معروفة وتكون المجموعة الفرعية أصغر.
يُولَّد جدول PHPDoc الكامل من المصدر.
نموذج التعليمات البرمجية — البدء السريع
قسم بعنوان «نموذج التعليمات البرمجية — البدء السريع»<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Typography\FontRegistry;
$registry = new FontRegistry();$registry->register(__DIR__ . '/MyFont-Regular.ttf', alias: 'MyFont');
$doc = Document::createStandalone();$doc->addPage();$doc->setFont('MyFont', '', 14);$doc->cell(0, 10, 'Rendered with an embedded, subset TrueType face.', newLine: true);
$doc->save(__DIR__ . '/out.pdf');ينشئ Document::createStandalone() سجله الخاص. لاستخدام سجل عبّأته بنفسك، أنشئ المستند عبر DocumentFactory، كما هو موضّح في نموذج بيئة الإنتاج. يجعل المصنع أداة الكتابة تقرأ وجه الخط الذي سجّلته.
نموذج التعليمات البرمجية — بيئة الإنتاج
قسم بعنوان «نموذج التعليمات البرمجية — بيئة الإنتاج»هذا النموذج مكتفٍ ذاتيًا وقابل للتشغيل ضمن منظومة الاختبار. يسجّل ملف LiberationSans-Regular.ttf المُضمَّن ويعرض النص عبر DocumentFactory، لذلك يكون السجل المُعبَّأ هو المُستخدَم. يعتمد النموذج على الإنشاء التلقائي للمجموعة الفرعية عند الحفظ.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
// A bundled TrueType test fixture keeps this recipe self-contained.// Replace with a font you have the right to embed.$fontPath = __DIR__ . '/../../fonts/test-fixtures/LiberationSans/LiberationSans-Regular.ttf';if (!is_file($fontPath)) { // Fall back to the repository-relative fixture location. $fontPath = dirname(__DIR__, 2) . '/fonts/test-fixtures/LiberationSans/LiberationSans-Regular.ttf';}
$fontRegistry = new FontRegistry();$fontRegistry->register($fontPath, alias: 'LiberationSans');
$imageRegistry = new ImageRegistry(maxCacheBytes: 0);$documentFactory = new DocumentFactory($fontRegistry, $imageRegistry);
$doc = $documentFactory->create();$doc->setTitle('Embedded Subset Font');$doc->addPage();
$doc->setFont('LiberationSans', '', 20);$doc->cell(0, 14, 'Embedded TrueType face', newLine: true);
$doc->setFont('LiberationSans', '', 12);$doc->multiCell(0, 7, 'Only the glyphs used by this document are embedded. ' . 'The writer subsets the font program and rewrites the BaseFont with a ' . 'deterministic six-letter subset prefix, for example ABCDEF+LiberationSans.');
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false ? $out : __DIR__ . '/embed-and-subset-fonts.pdf');
echo "Wrote embed-and-subset-fonts.pdf\n";مخرجات STDOUT المتوقعة:
Wrote embed-and-subset-fonts.pdfللتأكد من المجموعة الفرعية، افتح الناتج وافحص قاموس الخط. يقرأ BaseFont القيمة <TAG>+LiberationSans، ويحمل الواصف FontFile2. لا يبلّغ تشغيل qpdf --check عن أي أخطاء هيكلية.
الحالات الحدية والمزالق
قسم بعنوان «الحالات الحدية والمزالق»- ملكية السجل. ينشئ
Document::createStandalone()سجله الخاص. الخط الذي سجّلته علىFontRegistryمنفصل ولا يكون مرئيًا له. استخدمDocumentFactoryلتمرير سجلك، كما يفعل نموذج بيئة الإنتاج. - حقوق التضمين. لا يغيّر إنشاء المجموعة الفرعية الترخيص. لا تضمّن سوى الخطوط المرخَّص لك تضمينها. تضبط بعض الخطوط بتات تقييد التضمين؛ ويقرأ المحلّل تلك البتات، لكن مسؤولية الامتثال تبقى على عاتقك.
- مسار CFF/OpenType. تُنشَأ المجموعة الفرعية لوجوه
.otfوCFF بواسطةCffSubsetter، وليسFontSubsetter. السلوك وإعادة كتابة وسم المجموعة الفرعية متكافئان. مسار التعليمات البرمجية وحده هو الذي يختلف. - لا اختصار في الحجم. أحيانًا لا تكون المجموعة الفرعية أصغر من الأصل. قد يحدث هذا مع الخطوط الصغيرة جدًا أو عند استخدام جميع الرسوم الحرفية. في تلك الحالة، تضمّن أداة الكتابة البرنامج الأصلي دون وسم مجموعة فرعية. هذا سلوك صحيح، وليس إخفاقًا.
- خطوط CJK. تستخدم وجوه الخطوط الصينية واليابانية والكورية (CJK) الكبيرة استراتيجية متدرجة لإنشاء المجموعة الفرعية وفق ADR-008، مع عملية فرعية معزولة وحل احتياطي أصيل بلغة PHP. راجع ضبط نص CJK بترميز مدرك لـ cmap لمعرفة تفاصيل CJK وحالة خط الأنابيب الحالية.
الأداء
قسم بعنوان «الأداء»يستغرق التحليل مرورًا واحدًا على جداول الخط، وتزداد تكلفة إنشاء المجموعة الفرعية بازدياد عدد الرسوم الحرفية. تُنشَأ المجموعة الفرعية لوجوه الخطوط اللاتينية غير CJK داخل العملية ضمن ميزانية wall_ms: 1500, peak_mb: 96. تُوجَّه وجوه خطوط CJK الكبيرة إلى عملية فرعية معزولة بمهلة زمنية فعلية مدتها ثانيتان وحل احتياطي أصيل بلغة PHP (ADR-008). يعني هذا التوجيه أن إنشاء مجموعة فرعية بطيء أو منهار لا يمكن أن يحجب المُستدعي.
ملاحظات الأمان
قسم بعنوان «ملاحظات الأمان»ملف الخط مُدخَل ثنائي غير موثوق. يرفض المحلّل مسارات مغلِّفات الدفق والبايتات الصفرية. تعمل عملية إنشاء المجموعة الفرعية لـ CJK دون أي اتصالات بقواعد البيانات أو مقابض ملفات أو حالة إطار عمل موروثة. وتعود إلى الحل الاحتياطي بأمان عند الانهيار أو انتهاء المهلة (ADR-008). تحقّق من مصدر الخطوط المقبولة من المستخدمين النهائيين.
المطابقة
قسم بعنوان «المطابقة»| البيان | المواصفة | البند | reference_id |
|---|---|---|---|
| يحمل BaseFont/FontName للمجموعة الفرعية من الخط بادئة مجموعة فرعية مكوَّنة من ستة أحرف كبيرة موصولة بعلامة زائد. | ISO 32000-2 | iso32000_2_sec9#x1.x66.p2 | |
| يُخزَّن برنامج خط TrueType المُضمَّن بوصفه FontFile2 في واصف الخط. | ISO 32000-2 | iso32000_2_sec9#x1.x65.p15 |
توضّح هذه الوصفة كيف يضمّن NextPDF وجه خط TrueType وينشئ مجموعة فرعية منه ويُصدر بادئة مجموعة فرعية مطابِقة. وهي لا تؤكد الامتثال لترخيص الخط. حقوق التضمين مسؤولية الجهة المُدمِجة.
السياق التجاري
قسم بعنوان «السياق التجاري»لا ينطبق.