จัดเตรียมฟอนต์ในการใช้งานจริง
ภาพรวมโดยสรุป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสรุป”PDF ของคุณเรนเดอร์ถูกต้องบนแล็ปท็อป แล้วส่งไปยังคอนเทนเนอร์และออกมาเป็นแถวกล่องว่าง — glyph แบบ “tofu” — หรือมีสระและอักขระที่ไม่ใช่ละตินหายไป สาเหตุแทบจะเหมือนกันเสมอ คือ ฟอนต์ที่คุณเลือกไม่มีอยู่ใน image ที่ deploy ออกไป
เอนจิน NextPDF แบบเนทีฟภายในกระบวนการแก้ฟอนต์จาก ไฟล์ฟอนต์ ที่ font registry
อ่านได้ มันไม่ค้นพบฟอนต์ของ OS หรือ fontconfig โดยอัตโนมัติ — ไฟล์ฟอนต์ที่ติดตั้ง
โดย OS จะช่วยได้ก็ต่อเมื่อคุณลงทะเบียนไฟล์เหล่านั้นอย่างชัดเจน หรือเพิ่มไดเรกทอรีที่
บรรจุไฟล์เหล่านั้นลงในพาธค้นหาของ FontRegistry คอนเทนเนอร์ที่ build จาก base
image แบบบางไม่มีฟอนต์ที่ติดตั้งด้วย apt/apk และแม้แต่เมื่อมี เอนจินเนทีฟก็
เพิกเฉยต่อมันเว้นแต่คุณจะชี้ registry ไปยังไฟล์ของมัน วิธีแก้คือบันเดิลไฟล์ฟอนต์
จริงไว้ในแอปพลิเคชันหรือ image ของคุณ และลงทะเบียนมันกับเอนจิน registry อ่านไฟล์
TrueType (.ttf), OpenType (.otf) และ TrueType Collection (.ttc) ส่วน
Type1 (.pfb) แบบ legacy ก็รับได้แต่ไม่ค่อยจำเป็นสำหรับงานใหม่
ก่อนเริ่ม ให้ยืนยันว่าชิ้นส่วนเหล่านี้พร้อมแล้ว
- ติดตั้ง NextPDF core แล้ว
- คุณมีไฟล์ฟอนต์จริงที่ตั้งใจจะใช้ และคุณได้รับอนุญาตให้ฝังมัน สิทธิ์การฝังเป็น ความรับผิดชอบของคุณ — ดู ฝังและทำ subset ฟอนต์ TrueType
- build ของคุณสามารถคัดลอกไฟล์เหล่านั้นลงใน artifact ที่ deploy ได้
นี่คือ how-to ด้านการปฏิบัติการ โค้ดมีน้อยที่สุด งานอยู่ที่ build และเลย์เอาต์ของ ระบบไฟล์ สำหรับกลไกระดับ API ของการลงทะเบียนและทำ subset หน้าฟอนต์เดียว ให้อ่าน สูตร embed-and-subset ที่ลิงก์ไว้ด้านบน หน้านี้ครอบคลุมการนำไฟล์ ขึ้นไปบนเครื่อง และชี้เอนจินไปยังมัน
ทำไมเอนจินเนทีฟจึงไม่พบฟอนต์ของ OS โดยอัตโนมัติ
หัวข้อที่มีชื่อว่า “ทำไมเอนจินเนทีฟจึงไม่พบฟอนต์ของ OS โดยอัตโนมัติ”มีเส้นทางการเรนเดอร์ที่แตกต่างกันสองเส้นทาง และเรื่องของฟอนต์ต่างกันระหว่างทั้งสอง
- เอนจินเนทีฟภายในกระบวนการ (ค่าเริ่มต้น
Document/writeHtml): เอนจิน ไม่เรียกเข้าระบบฟอนต์ของระบบปฏิบัติการหรือfontconfigเพื่อการค้นหา มันแก้ หน้าฟอนต์ผ่าน font registry ซึ่งอ่านไฟล์ฟอนต์ที่คุณลงทะเบียนไว้ หรือค้นหา ไฟล์หนึ่งภายในไดเรกทอรีที่คุณกำหนดเป็นพาธค้นหา การติดตั้งฟอนต์ด้วยapt-get install fonts-notoหรือการรันfc-cacheไม่ได้ทำอะไรด้วยตัวมันเอง — เอนจินเนทีฟเห็นไฟล์เหล่านั้นก็ต่อเมื่อคุณลงทะเบียนมันหรือเพิ่มไดเรกทอรีของมัน ลงในพาธค้นหาของ registry - Chrome bridge (ตัวเรนเดอร์ HTML-to-PDF ที่ขับเบราว์เซอร์แบบ headless):
เส้นทางนี้ ใช้ ฟอนต์ที่ติดตั้งของโฮสต์ผ่านการค้นหาฟอนต์ปกติของเบราว์เซอร์
ดังนั้นแพ็กเกจฟอนต์
apt/apkและfontconfigจึงมีความสำคัญที่นั่น
หากคุณอ่านคำแนะนำทั่วไปว่า “ติดตั้งแพ็กเกจฟอนต์ของระบบเหล่านี้ใน Dockerfile ของคุณ” มันใช้กับ Chrome bridge ไม่ใช่ กับเอนจินเนทีฟที่ครอบคลุมในหน้านี้ สำหรับการ สร้างแบบเนทีฟ ให้บันเดิลไฟล์และลงทะเบียนมัน
ขั้นที่ 1 — บันเดิลไฟล์ฟอนต์จริง
หัวข้อที่มีชื่อว่า “ขั้นที่ 1 — บันเดิลไฟล์ฟอนต์จริง”วางไฟล์ฟอนต์ไว้ในแผนผังแอปพลิเคชันของคุณเพื่อให้มันมีการกำหนดเวอร์ชันและส่งไปกับ
ทุก build ตำแหน่งตามแบบแผนคือไดเรกทอรี resources/fonts/
your-app/├── resources/│ └── fonts/│ ├── DejaVuSans.ttf│ ├── DejaVuSans-B.ttf│ └── NotoSansCJK-Regular.ttc└── src/ตั้งชื่อไฟล์เพื่อให้การค้นหาไดเรกทอรีของเอนจินหาไฟล์ได้ตามตระกูลและสไตล์ เมื่อคุณ
ลงทะเบียน ไดเรกทอรี (แทนที่จะเป็นไฟล์ที่ระบุ) แล้วเรียก
setFont('DejaVuSans', 'B', 12) ในภายหลัง เอนจินจะมองหาไฟล์เช่น
DejaVuSans-B.ttf, DejaVuSansB.ttf หรือ DejaVuSans.ttf ในแต่ละไดเรกทอรีที่
กำหนดค่าไว้ การค้นหาไดเรกทอรีสร้างชื่อผู้เข้าชิงเหล่านั้นจาก รหัสสไตล์ตัวอักษร
เดียวที่คุณส่งให้ setFont (B สำหรับตัวหนา, I สำหรับตัวเอียง, BI สำหรับ
ตัวหนาเอียง) ไม่ใช่คำที่สะกดเต็ม — ดังนั้นรูปแบบที่เชื่อถือได้คือ
Family-<StyleCode>.ttf (ตัวอย่างเช่น DejaVuSans-B.ttf หรือ
DejaVuSans-BI.ttf) ไม่ใช่ Family-Bold.ttf ไฟล์ที่ชื่อ
DejaVuSans-Bold.ttf จะไม่มีวันถูกพบโดยการค้นหาไดเรกทอรี หากต้องการใช้ไฟล์
เช่นนั้น ให้ลงทะเบียนมันอย่างชัดเจนด้วย register() — ซึ่งแยกวิเคราะห์ฟอนต์และ
จัดทำดัชนีมันภายใต้ตระกูลและสไตล์ที่อ่านจาก name table ของไฟล์เอง ดังนั้นชื่อไฟล์
ที่สะกดเต็มจึงไม่สำคัญอีกต่อไป (ดูขั้นที่ 2)
ขั้นที่ 2 — ลงทะเบียนฟอนต์กับเอนจิน
หัวข้อที่มีชื่อว่า “ขั้นที่ 2 — ลงทะเบียนฟอนต์กับเอนจิน”คุณมีสองวิธีที่เทียบเท่ากันในการทำให้ไฟล์มองเห็นได้ ทั้งสองผ่าน
NextPDF\Typography\FontRegistry ซึ่ง implement
NextPDF\Contracts\FontRegistryInterface
ลงทะเบียนไฟล์ที่ระบุภายใต้ alias เมื่อคุณควบคุมหน้าฟอนต์ที่แน่นอน
use NextPDF\Typography\FontRegistry;
$registry = new FontRegistry();$registry->register(__DIR__ . '/../resources/fonts/DejaVuSans.ttf', alias: 'DejaVuSans');register(string $fontFile, string $alias = '', int $fontIndex = 0) รับไฟล์
.ttf, .otf และ .ttc รวมถึง Type1 .pfb แบบ legacy (ซึ่งโหลด metrics
.afm คู่กันจากพาธเดียวกัน) $fontIndex เลือก sub-font ภายใน TrueType
Collection (.ttc) register() แยกวิเคราะห์ไฟล์และจัดทำดัชนีหน้าฟอนต์ตามตระกูล
และสไตล์ที่อ่านจาก name table ของมันเอง ดังนั้นชื่อไฟล์ทางกายภาพจึงไม่เกี่ยวข้อง
เมื่อลงทะเบียนแล้ว $alias ที่เป็นทางเลือกเป็นเพียงชื่อค้นหาเพิ่มเติมสำหรับ
หน้าฟอนต์ — มันไม่ใช่รหัสสไตล์และไม่เปลี่ยนสไตล์ที่ไฟล์ให้ ส่งมันเมื่อคุณต้องการ
เรียก setFont() ด้วยชื่ออื่นนอกเหนือจากชื่อตระกูลที่ฝังของฟอนต์ มันคืน
FontInfo ที่แยกวิเคราะห์แล้ว
ลงทะเบียนไดเรกทอรี เมื่อคุณต้องการให้เอนจินแก้หน้าฟอนต์ตามชื่อจากโฟลเดอร์ที่ คุณควบคุม
$registry = new FontRegistry('/var/www/app/resources/fonts');// or, equivalently, after construction:$registry->addFontDirectory('/var/www/app/resources/fonts');constructor ของ FontRegistry รับไดเรกทอรีนั้นเป็น argument แรก และ
addFontDirectory() เพิ่มพาธค้นหาเพิ่มเติม Document เปล่าๆ ก็เปิดเผย
addFontDirectory() สำหรับกรณี standalone ด้วย
หากต้องการใช้ registry ที่คุณ populate เอง ให้สร้างเอกสารผ่าน DocumentFactory
ซึ่งเชื่อม registry นั้นเข้ากับทุกเอกสารที่มันสร้าง
use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;
$factory = new DocumentFactory($registry, new ImageRegistry(maxCacheBytes: 0));
$doc = $factory->create();$doc->addPage();$doc->setFont('DejaVuSans', '', 12);$doc->cell(0, 10, 'Réndéred wîth a bundled face — no tofu.', newLine: true);$doc->save('/tmp/out.pdf');Document::createStandalone() สร้าง registry ภายใน ของตัวเอง ดังนั้น
หน้าฟอนต์ที่คุณลงทะเบียนบน FontRegistry แยกต่างหากจึงมองไม่เห็น ในการใช้งานจริง
ให้ผ่าน DocumentFactory (หรือ factory ของเฟรมเวิร์กของคุณ) เพื่อให้ registry ที่
populate แล้วเป็นตัวที่ใช้งานอยู่
การกำหนดค่าเฟรมเวิร์ก
หัวข้อที่มีชื่อว่า “การกำหนดค่าเฟรมเวิร์ก”แต่ละ integration ของเฟรมเวิร์กเปิดเผยแนวคิดสองอย่างเดียวกันเป็นการกำหนดค่า ดังนั้น
คุณจึงแทบไม่ต้องแตะ registry โดยตรง ในไฟล์ nextpdf.php ของแพ็กเกจ Laravel
fonts_path (ค่าเริ่มต้น NEXTPDF_FONTS_PATH ที่ fallback ไปยัง
resource_path('fonts')) คือไดเรกทอรีค้นหา และ preload_fonts คือรายการพาธไฟล์
ฟอนต์แบบสัมบูรณ์ที่แยกวิเคราะห์ ณ เวลา boot ของ worker ชี้ fonts_path ไปยัง
ไดเรกทอรีที่คุณบันเดิล แล้วหน้าฟอนต์ที่คุณลงทะเบียนจะแก้ได้อัตโนมัติ
ขั้นที่ 3 — จัดเตรียมฟอนต์ใน Docker image
หัวข้อที่มีชื่อว่า “ขั้นที่ 3 — จัดเตรียมฟอนต์ใน Docker image”ในคอนเทนเนอร์ ไฟล์ฟอนต์ต้องเป็นส่วนหนึ่งของเลเยอร์ image คัดลอกเข้ามา ณ เวลา build
เนื่องจากโค้ดแอปพลิเคชันและฟอนต์ส่งไปด้วยกันเมื่อคุณบันเดิลมันไว้ใต้
resources/fonts/ คำสั่ง COPY . . ปกติจึงนำมันไปด้วยอยู่แล้ว หากคุณเก็บฟอนต์ไว้
นอก build context ให้คัดลอกมันอย่างชัดเจนและตรวจสอบให้แน่ใจว่าพาธที่คุณลงทะเบียน
ตรงกับพาธภายใน image
# Native engine: NO system font packages are required.# The native engine does not discover OS-installed fonts automatically; install OS# font packages (`apt-get install fonts-*`) only if you also register them or point# the font registry's search directory at their files.FROM php:8.4-cli
WORKDIR /var/www/app
# Bundle the application, including resources/fonts/, into the image.COPY . /var/www/app
# Make the bundled directory the engine's font search path.ENV NEXTPDF_FONTS_PATH=/var/www/app/resources/fonts
CMD ["php", "bin/generate.php"]บน ระบบไฟล์ที่เปลี่ยนแปลงไม่ได้หรืออ่านอย่างเดียว (คอนเทนเนอร์
readOnlyRootFilesystem, image แบบ serverless หรือโฮสต์ที่เสริมความแข็งแกร่ง)
ไฟล์ฟอนต์ถูกอ่าน ณ เวลาสร้างและไม่เคยถูกเขียน ดังนั้น mount แบบอ่านอย่างเดียวจึง
ใช้ได้ การเขียนเดียวที่เอนจินอาจต้องการคือ cache ของฟอนต์ที่แยกวิเคราะห์แล้ว: ให้
ไดเรกทอรีนั้นเป็น writable volume ขนาดเล็ก หรือ warm และ lock registry ณ เวลา boot
(หัวข้อถัดไป) เพื่อไม่ให้มีการพยายามเขียนหรือลงทะเบียน ณ runtime
ขั้นที่ 4 — Warm up และตรวจสอบ
หัวข้อที่มีชื่อว่า “ขั้นที่ 4 — Warm up และตรวจสอบ”ใน worker ที่ทำงานยาวนาน ให้แยกวิเคราะห์ทุกหน้าฟอนต์หนึ่งครั้ง ณ เวลา boot จากนั้น lock registry เพื่อไม่ให้มีการลงทะเบียนต่อคำขอเกิดขึ้น และให้การกำหนดค่าผิด ล้มเหลวอย่างชัดเจนแทนที่จะ fallback เงียบๆ
$registry = new FontRegistry('/var/www/app/resources/fonts');$registry->warmup([ '/var/www/app/resources/fonts/DejaVuSans.ttf', '/var/www/app/resources/fonts/DejaVuSans-B.ttf',]);$registry->lock();หลัง lock() แล้ว register(), addFontDirectory() และ warmup() จะ throw
ซึ่งเปลี่ยนความผิดพลาด “พาธผิดใน image” ให้เป็นการล้มเหลวที่ boot แบบเด็ดขาด แทนที่
จะเป็นหน้า tofu ในการใช้งานจริง
เพิ่มการตรวจสอบ smoke ของการ deploy ที่เรนเดอร์หนึ่งหน้าด้วยแต่ละหน้าฟอนต์ที่ต้องการ การตรวจสอบส่วนหัวด้านล่างยืนยันเพียงว่าเอกสาร สร้างเอาต์พุต เท่านั้น — มันไม่ พิสูจน์ว่าฟอนต์แยกวิเคราะห์ ฝัง หรือแม้แต่แก้ได้ หน้าฟอนต์ที่เอนจินหาไม่พบอาจ fallback ไปยัง base font มาตรฐาน (และภายใต้พฤติกรรม non-strict ปัจจุบัน conformance profile อาจให้ตัวแทนที่บันเดิลไว้แทน) ในขณะที่ยังส่งออก PDF ที่ถูกต้อง และไม่ว่างเปล่า — ดังนั้นแม้ในจุดที่ fallback นั้นเกิดขึ้น การตรวจสอบนี้เพียงอย่าง เดียวก็จะไม่จับการเสื่อมถอยเงียบๆ ได้ อย่าพึ่งพาว่า fallback จะรับประกันหรือเงียบ ในทุกเส้นทาง ให้ตรวจสอบโปรแกรมที่ฝังโดยตรง ดังที่แสดงด้านล่าง
$doc = $factory->create();$doc->addPage();$doc->setFont('DejaVuSans', '', 12);$doc->cell(0, 10, 'warmup check', newLine: true);
$pdf = $doc->getPdfData();
// `getPdfData()` would normally throw on a real failure; this header check only// confirms serialization returned PDF bytes, not that any specific font resolved.if (!str_starts_with($pdf, '%PDF')) { throw new RuntimeException('Font warmup smoke check produced no PDF output.');}หากต้องการให้การ deploy ล้มเหลวจริงเมื่อหน้าฟอนต์หายไป ให้ตรวจสอบ PDF ที่ส่งออก
หาโปรแกรมฟอนต์ที่ฝัง หน้าฟอนต์ที่ลงทะเบียนแล้วที่แก้ได้นำพา font dictionary
ของตัวเองพร้อมโปรแกรมที่ฝัง ดังนั้นการยืนยันการมีอยู่ของมันจึงจับกรณีที่หน้าฟอนต์
ที่ร้องขอไม่เคยแก้ได้ (ไม่ว่าเอนจินจะ fallback ไปยังอะไร) ที่การตรวจสอบส่วนหัวพลาด
ไป คีย์ใดถือโปรแกรมขึ้นอยู่กับรูปแบบ outline: outline แบบ TrueType
(.ttf, .ttc) ใช้ /FontFile2, outline แบบ CFF/OpenType
(.otf ที่มี outline PostScript) ใช้ /FontFile3 และ Type1 (.pfb) แบบ legacy
ใช้ /FontFile
หากสิ่งที่คุณต้องการคือสัญญาณ “มีโปรแกรมฟอนต์ฝังอยู่บ้าง” แบบไม่ขึ้นกับรูปแบบ
ให้ทดสอบหา /FontFile เพียงตัวเดียว — เพราะ /FontFile เป็นสตริงย่อยของทั้ง
/FontFile2 และ /FontFile3 การตรวจสอบสตริงย่อยเปล่าๆ จึงตรงกับทุกประเภท outline
อยู่แล้ว และการเพิ่ม /FontFile2//FontFile3 เป็นกิ่ง || เพิ่มเติมจึงซ้ำซ้อน
if (!str_contains($pdf, '/FontFile')) { throw new RuntimeException('No embedded font program found — face fell back.');}อย่างไรก็ตาม สตริงย่อย /FontFile เปล่าๆ ไม่สามารถแยกประเภท outline ออกจากกันได้
หากต้องการแยกแยะมัน ให้จับคู่กับโทเคนที่แน่นอนพร้อม word boundary เพื่อให้
/FontFile ไม่ทำงานบน /FontFile2 หรือ /FontFile3 ด้วย
$isTrueType = preg_match('~/FontFile2\b~', $pdf) === 1; // TrueType (.ttf/.ttc)$isCffOtf = preg_match('~/FontFile3\b~', $pdf) === 1; // CFF/OpenType (.otf)$isType1 = preg_match('~/FontFile(?![23])\b~', $pdf) === 1; // Type1 (.pfb)
if (!$isTrueType && !$isCffOtf && !$isType1) { throw new RuntimeException('No embedded font program found — face fell back.');}ไม่ว่าจะวิธีใด ให้จัดการกับสิ่งนี้เป็น ฮิวริสติกแบบหยาบเท่านั้น ไม่ใช่ deploy
gate ที่เชื่อถือได้ การค้นหาไบต์ดิบบน PDF ที่ serialize แล้วไม่แม่นยำด้วยหลายเหตุผล
โปรแกรมฟอนต์อาจอยู่ภายใน compressed object stream (ที่ /FontFile* ไม่เคย
ปรากฏเป็นไบต์ธรรมดา), incremental update สามารถต่อท้ายหรือแทนที่วัตถุ,
ฟอนต์ที่ไม่ฝังหรือ standard-14 ไม่นำพาโปรแกรมฟอนต์เลยโดยชอบธรรม และ
ความแตกต่างของ serialization (ลำดับวัตถุ, whitespace, การเข้ารหัสชื่อ)
สามารถย้ายหรือซ่อนโทเคนได้ อย่างดีที่สุดมันยืนยันว่าหน้าฟอนต์ บางส่วน ฝังโปรแกรม
ไว้ — ไม่ใช่ว่าหน้าฟอนต์ ที่ระบุ ที่คุณต้องการแก้ได้
สำหรับ deploy gate จริง อย่าพึ่งพาการค้นหาไบต์ แยกวิเคราะห์ PDF ที่ส่งออกด้วย
parser หรือตัวตรวจสอบวัตถุ PDF ที่เหมาะสม และยืนยันว่าวัตถุฟอนต์สำหรับหน้าฟอนต์
เป้าหมายของคุณนำพาโปรแกรม /FontFile//FontFile2//FontFile3 ที่ฝังไว้ หรือใช้
การยืนยันการแก้ฟอนต์ที่ผลิตภัณฑ์จัดให้หากมีให้ใน integration ของคุณ regex ที่
ตระหนักถึงโทเคนด้านบนมีประโยชน์สำหรับการตรวจสอบความสมเหตุสมผลในเครื่องอย่างรวดเร็ว
แต่การตรวจสอบเชิงโครงสร้างคือสิ่งที่ควรทำให้การ deploy ล้มเหลว โครงสร้างการฝังและ
font dictionary อธิบายไว้ใน
ฝังและทำ subset ฟอนต์ TrueType
กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”createStandalone()มี registry ของตัวเอง หน้าฟอนต์ที่ลงทะเบียนบนFontRegistryแยกต่างหากจะมองไม่เห็นโดยเอกสาร standalone ใช้DocumentFactory(หรือ factory ของเฟรมเวิร์ก) เพื่อให้ registry ของคุณเป็นตัวที่ทำงานอยู่- ไฟล์สไตล์ต้องมีอยู่จริงเป็นไฟล์ เอนจินไม่สังเคราะห์ตัวหนาหรือตัวเอียงจาก
หน้าฟอนต์ปกติ หากคุณเรียก
setFont('DejaVuSans', 'B')การค้นหาไดเรกทอรีมองหาDejaVuSans-B.ttf,DejaVuSansB.ttfหรือDejaVuSans.ttf(ตัวพิมพ์เล็กและ รูปแบบ.otfด้วย) — มันสร้างผู้เข้าชิงจากรหัสสไตล์Bตามตัวอักษร ดังนั้นจึง ไม่เคยมองหาDejaVuSans-Bold.ttfไฟล์ที่มีชื่อสะกดเต็มเช่นDejaVuSans-Bold.ttfจะแก้ได้ก็ต่อเมื่อคุณลงทะเบียนมันอย่างชัดเจนด้วยregister()ซึ่งจัดทำดัชนีมัน ตามตระกูลและสไตล์ที่อ่านจาก name table ของไฟล์เองโดยไม่คำนึงถึงชื่อไฟล์ การพึ่งพา การค้นหาไดเรกทอรีเพื่อหามันทำให้พลาด หลังจากนั้นเอนจินอาจ fallback ไปยัง base font (ไม่ใช่เส้นทางที่รับประกันหรือเงียบเสมอ) — การเสื่อมถอยที่หน้านี้เตือนถึง - พาธ stream-wrapper และพาธรีโมตถูกปฏิเสธ registry ปฏิเสธพาธที่มี URI scheme
หรือ null byte ลงทะเบียนเฉพาะไฟล์ในเครื่อง สำหรับฟอนต์ที่ดึง ณ runtime ให้ใช้
registerFromBinary()พร้อมไบต์ดิบ - registry ที่ lock แล้วเปลี่ยนแปลงไม่ได้ เมื่อคุณเรียก
lock()แล้วregister(),addFontDirectory()หรือwarmup()ใดในภายหลังจะ throw เมธอด การค้นหายังคงใช้ได้ ลงทะเบียนและ warm up ทุกอย่างก่อน lock - CJK collection มีขนาดใหญ่ ลงทะเบียน sub-font ที่ถูกต้องของ
.ttcด้วย$fontIndexและเผื่อสำหรับ subset ที่ฝังขนาดใหญ่กว่า ดูหมายเหตุ CJK ในสูตร embed-and-subset
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”- ไฟล์ฟอนต์เป็นอินพุตไบนารีที่ไม่น่าเชื่อถือ บันเดิลเฉพาะฟอนต์จากแหล่งที่คุณเชื่อถือ และตรวจสอบที่มาของหน้าฟอนต์ใดก็ตามที่รับจากผู้ใช้ปลายทาง
- การ lock registry หลัง warmup ลบพื้นผิวการกลายพันธุ์ ณ runtime และทำให้ ความผิดพลาดของพาธล้มเหลวที่ boot แทนที่จะเสื่อมเอาต์พุตเงียบๆ
- อย่าแทรกอินพุตของผู้ใช้ลงในพาธไฟล์ที่ลงทะเบียน ลงทะเบียนชุดของหน้าฟอนต์ที่บันเดิล ตายตัว อย่าให้คำขอเลือกพาธของระบบไฟล์ตามอำเภอใจ
ความสอดคล้องตามมาตรฐาน
หัวข้อที่มีชื่อว่า “ความสอดคล้องตามมาตรฐาน”คู่มือนี้ไม่อ้างเรื่องมาตรฐานเชิงบรรทัดฐาน ทุกสัญลักษณ์ที่แสดงเป็นพื้นผิวสาธารณะที่
ตรวจสอบแล้ว: NextPDF\Typography\FontRegistry (register(),
addFontDirectory(), warmup(), lock(), argument constructor ของไดเรกทอรี),
contract NextPDF\Contracts\FontRegistryInterface ของมัน,
NextPDF\Core\DocumentFactory::create() และ NextPDF\Core\Document::setFont()
/ addFontDirectory() คีย์ fonts_path และ preload_fonts ของ Laravel คือ
การกำหนดค่าที่บันทึกไว้ของแพ็กเกจ nextpdf/laravel พฤติกรรมการฝังและ subset-tag
พร้อมการอ้างอิง ISO 32000-2 ของมัน บันทึกไว้ในสูตร embed-and-subset ที่ลิงก์ไว้
ใต้ดูเพิ่มเติม
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- ฝังและทำ subset ฟอนต์ TrueType: สูตรระดับ API สำหรับการลงทะเบียนหน้าฟอนต์หนึ่งหน้าและ subset อัตโนมัติ ณ การบันทึก
- เรนเดอร์ HTML เป็นหน้า PDF: เส้นทาง HTML เนทีฟ ซึ่งแก้ฟอนต์ผ่าน registry เดียวกัน
- คืน PDF ที่สร้างขึ้นจาก controller: เชื่อมเอกสารที่สร้างด้วย factory เข้ากับ response ของเฟรมเวิร์ก
- การใช้งานจริงของ Laravel: การกำหนดค่าฟอนต์ของเฟรมเวิร์กและ warmup ณ เวลา boot ของ worker