ลดขนาดไฟล์ PDF ด้วยการบีบอัดและการทำซับเซต
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”คุณต้องการไฟล์ PDF ที่มีขนาดเล็กที่สุดเท่าที่เนื้อหาจะเอื้ออำนวย โดยไม่สูญเสียความเที่ยงตรง NextPDF มีตัวควบคุมขนาดไฟล์สองส่วน และทั้งสองส่วนเปิดใช้งานตามค่าเริ่มต้น:
- การบีบอัดสตรีม ตัวเขียนจะห่อสตรีมเนื้อหาของทุกหน้าและโปรแกรมฟอนต์ที่ฝังทุกตัวไว้ในสตรีม FlateDecode (zlib) ตัว
NextPDF\Core\Configมีแฟล็กcompressสำหรับเก็บการตั้งค่านี้ อ่านค่ากลับได้ด้วยตัว witherwithCompress()เมื่อคุณสร้างเอกสารแบบสตรีมมิง - การทำซับเซตฟอนต์ เมื่อคุณฝังฟอนต์ TrueType หรือ CFF ตัวเขียนจะสร้างโปรแกรมฟอนต์ขึ้นใหม่ให้มีเฉพาะกลิฟที่เอกสารใช้ จากนั้นบีบอัดผลลัพธ์ด้วย FlateDecode กระบวนการนี้เกิดขึ้นโดยอัตโนมัติ ไม่มีแฟล็กที่ต้องตั้งค่าและไม่มีการเรียกใช้ที่ต้องเพิ่ม ฟอนต์ CJK ขนาด
20,000กลิฟ ซึ่งนำกลิฟมาใช้ในเอกสารเพียงไม่กี่ร้อยตัว จะถูกฝังด้วยขนาดเพียงเศษเสี้ยวของขนาดบนดิสก์
มีข้อจำกัดสำคัญที่ควรรู้ก่อน: NextPDF Core ไม่เปิดให้ใช้การสุ่มตัวอย่างภาพใหม่ ปุ่มปรับคุณภาพภาพ สวิตช์เปิดปิดออบเจกต์สตรีม หรือการตั้งค่าการลดข้อมูลทรัพยากรที่ซ้ำกัน ตัวควบคุมสองอย่างข้างต้นเป็นตัวควบคุมขนาดเพียงอย่างเดียว ส่วนที่เหลือของเรซิพีนี้จะแสดงวิธีใช้งานทั้งสองอย่างให้ถูกต้อง และอธิบายว่าสิ่งเหล่านี้ไม่ครอบคลุมอะไรบ้าง
ข้อกำหนดเบื้องต้น: ต้องมีการติดตั้ง Core (composer require nextpdf/core:^3) และสำหรับเส้นทางการทำซับเซต ต้องมีไฟล์ฟอนต์ที่คุณได้รับอนุญาตให้ฝัง
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”PDF คือโครงสร้างต้นไม้ของออบเจกต์ ออบเจกต์ที่ใหญ่ที่สุดมักเป็นสตรีมเนื้อหา (ตัวดำเนินการวาดสำหรับแต่ละหน้า) และโปรแกรมฟอนต์ (เส้นโครงร่างกลิฟที่ฝัง) ทั้งสองอย่างบีบอัดได้ดี ดังนั้นตัวควบคุมขนาดที่ได้ผลที่สุดคือการบีบอัดด้วย FlateDecode FlateDecode เป็นชื่อในมาตรฐาน PDF 2.0 สำหรับสตรีม DEFLATE ที่ห่อด้วย zlib (ISO 32000-2:2020 §7.4.4) และเป็นฟิลเตอร์ที่ NextPDF สร้างในเอาต์พุต
ตัวเขียนตรึงระดับการบีบอัด DEFLATE ไว้ที่ 9 ซึ่งเป็นค่าสูงสุดตาม RFC 1951 ผ่าน NextPDF\Writer\PinnedZlibCompressor ระดับ 9 ใช้ CPU เพิ่มขึ้นเล็กน้อยเพื่อแลกกับสตรีมที่เล็กที่สุด การตรึงระดับไว้ยังทำให้เอาต์พุตคงที่ เพราะส่วนหัว zlib เข้ารหัสระดับนั้นไว้ และระดับที่เปลี่ยนไปจะทำให้ไบต์เปลี่ยน คุณไม่ได้เลือกระดับเอง เอนจินตรึงค่านี้ไว้เพื่อให้การรันสองครั้งบนอินพุตเดียวกันสร้างสตรีมที่มีไบต์เหมือนกันทุกประการ
กลไกที่สองคือการทำซับเซตฟอนต์ ไฟล์ฟอนต์บนดิสก์มีกลิฟทุกตัวที่แบบอักษรกำหนดไว้ แต่เอกสารที่แสดงข้อความ “Invoice 2026” ต้องใช้เพียงไม่กี่ตัวเท่านั้น NextPDF\Typography\FontSubsetter (สำหรับ TrueType) และ NextPDF\Typography\CffSubsetter (สำหรับ CFF / OpenType) จะไล่ตรวจโค้ดพอยต์ที่เอกสารเรนเดอร์จริง แก้ไขการพึ่งพาของกลิฟแบบประกอบ และสร้างเฉพาะตารางฟอนต์ที่จำเป็นขึ้นใหม่ ทั้งสองตัวสร้างไบนารีฟอนต์ซับเซตที่ถูกต้องพร้อมแท็กคำนำหน้าซับเซตแบบหกตัวอักษรที่กำหนดได้แน่นอน (ISO 32000-2:2020 §9.9) ตัวเขียนจะใช้สิ่งนี้เมื่อใดก็ตามที่ทราบชุดกลิฟที่ใช้งานของฟอนต์ที่ฝัง จากนั้นบีบอัดซับเซตด้วย FlateDecode ถ้าการทำซับเซตของแบบอักษรหนึ่ง ๆ จะช่วยประหยัดได้น้อยกว่าสิบเปอร์เซ็นต์ ตัวทำซับเซตจะคืนโปรแกรมต้นฉบับแทน เพราะต้นทุนการสร้างใหม่ไม่คุ้มกับผลที่ได้เพียงเล็กน้อย
ข้อสรุปสำคัญ: คุณลดขนาดไฟล์ PDF ได้ด้วยการเปิดการบีบอัดไว้ (ค่าเริ่มต้น) และฝังไฟล์ฟอนต์จริง (เพื่อให้การทำซับเซตมีสิ่งที่จะลดขนาดได้) ไม่ใช่ด้วยการไล่ปรับตัวเลือกจำนวนมาก
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”ตัวควบคุมขนาดเพียงอย่างเดียวที่คุณตั้งค่าได้อยู่บนออบเจกต์การกำหนดค่า
NextPDF\Core\Config เป็น value object ที่ไม่เปลี่ยนแปลงและเป็น final readonly พร้อมเมท็อด wither ที่กำหนดชนิดไว้ สมาชิกที่เกี่ยวข้องกับขนาดคือ:
compress(boolค่าเริ่มต้นtrue) เปิดใช้งานการบีบอัด FlateDecode อ่านค่ากลับด้วยwithCompress(bool $compress): selfซึ่งคืนConfigตัวใหม่ที่เปลี่ยนแฟล็กแล้วและคงฟิลด์อื่นทุกตัวไว้
แนบ Config เข้ากับเอกสารเมื่อตอนสร้างอินสแตนซ์:
NextPDF\Core\Document::createStandalone(?Config $config = null): selfสร้างเอกสารด้วยรีจิสทรีชั่วคราวสำหรับสคริปต์ CLI หรือโพรเซสอายุสั้น โดยใช้Configของคุณ
สมาชิกสองตัวกำหนดสิ่งที่ตัวควบคุมขนาดใช้ทำงาน แต่ตัวมันเองไม่ใช่ตัวควบคุมการบีบอัด:
imageCacheBytes(intค่าเริ่มต้น52_428_800) จำกัดขนาดแคชภาพในหน่วยความจำ และwithImageCacheBytes(int $bytes): selfเปลี่ยนค่านี้ ค่านี้จำกัดขอบเขตหน่วยความจำสูงสุดระหว่างการสร้าง แต่ไม่ได้สุ่มตัวอย่างใหม่ บีบอัดซ้ำ หรือลดขนาดภาพที่คุณฝังด้วยวิธีอื่นใด เป็นเพดานหน่วยความจำ ไม่ใช่ตัวควบคุมขนาดเอาต์พุตfontsDirectory(string) และwithFontsDirectory(string $dir): selfกำหนดเส้นทางค้นหาเริ่มต้นสำหรับไฟล์ฟอนต์ ซึ่งป้อนให้เส้นทางการทำซับเซต
งานเกี่ยวกับฟอนต์เกิดขึ้นผ่านพื้นผิวการพิมพ์ของเอกสาร:
setFont(string $family, string $style = '', float $size = 12.0): staticเลือกแบบอักษร เมื่อตระกูลฟอนต์ถูกจับคู่กับไฟล์ฟอนต์ที่ฝังได้ ตัวเขียนจะบันทึกโค้ดพอยต์ที่คุณเรนเดอร์ เพื่อให้สามารถทำซับเซตแบบอักษรนั้นได้ตอนบันทึกaddFontDirectory(string $directory): staticลงทะเบียนไดเรกทอรีเพิ่มเติมเพื่อค้นหาไฟล์ฟอนต์
เอาต์พุตใช้เมท็อดมาตรฐานสามรายการ: getPdfData(): string คืนค่าไบต์ save(string $path): void เขียนไบต์เหล่านั้นแบบอะตอมมิก และ output(?string $filename, OutputDestination $dest): string จัดการการส่งผ่านทาง HTTP
การทำซับเซตไม่มีเมท็อดสาธารณะและไม่มีแฟล็ก เป็นคุณสมบัติที่เกิดขึ้นเองจากการฝังฟอนต์และการเรนเดอร์ข้อความ ตัวเขียนจะขับเคลื่อน FontSubsetter / CffSubsetter ภายใน NextPDF\Writer\PdfFontWriter ให้คุณ
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”ตัวอย่างนี้สร้างเอกสารโดยเปิดการบีบอัดอย่างชัดเจน ใช้ฟอนต์ที่ฝังและทำซับเซตได้ จากนั้นเขียนไบต์ออกมา ตัวอย่างนี้ละเว้นการจัดการข้อผิดพลาดเพื่อให้รูปแบบการเรียกใช้ชัดเจน ตัวอย่างสำหรับการใช้งานจริงด้านล่างเพิ่มการป้องกันครบถ้วน
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;
// compress defaults to true; setting it explicitly documents intent.$config = (new Config())->withCompress(true);
$doc = Document::createStandalone($config);$doc->addFontDirectory(__DIR__ . '/fonts');$doc->addPage();
// Selecting an embeddable face records the glyphs used, so the writer// subsets this font automatically when the document is built.$doc->setFont('LiberationSans', '', 12);$doc->cell(0, 10, 'Invoice 2026 - subsetted, compressed output.', newLine: true);
$pdf = $doc->getPdfData();
file_put_contents(__DIR__ . '/small.pdf', $pdf);
printf("Wrote %d bytes.\n", strlen($pdf));ตัวอย่างโค้ด — สำหรับการใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — สำหรับการใช้งานจริง”นี่คือโปรแกรมแบบสมบูรณ์ในตัวเอง โปรแกรมสร้างเอกสารโดยเปิดการบีบอัด ฝังฟอนต์จากไดเรกทอรีที่คุณควบคุม เรนเดอร์ข้อความเพื่อให้ตัวทำซับเซตมีชุดกลิฟที่ใช้งาน และเขียนผลลัพธ์แบบอะตอมมิก โปรแกรมดักจับข้อยกเว้นของ NextPDF ที่เจาะจงที่สุดซึ่งเส้นทางการสร้างและการบันทึกยกขึ้น จากนั้นโยนข้อยกเว้นนั้นซ้ำพร้อมบริบทแทนการกลืนข้อผิดพลาด กำหนด NEXTPDF_FONT_DIR ให้ชี้ไปยังไดเรกทอรีที่เก็บแบบอักษร TrueType หรือ CFF ที่คุณได้รับอนุญาตให้ฝัง โปรแกรมจะตรวจสอบความถูกต้องของเส้นทางก่อนฝัง
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;use NextPDF\Exception\CompressionException;use NextPDF\Exception\InvalidConfigException;
/** * Resolve and validate the font directory from a server-controlled source. * * Reading the directory from the environment keeps the path off the request * surface. The function rejects a missing or unreadable directory so the * embedding path never runs against untrusted or absent input. */function resolveFontDirectory(): string{ $configured = getenv('NEXTPDF_FONT_DIR'); $dir = $configured !== false && $configured !== '' ? $configured : __DIR__ . '/fonts';
$real = realpath($dir); if ($real === false || !is_dir($real) || !is_readable($real)) { throw new RuntimeException(sprintf('Font directory "%s" is not a readable directory.', $dir)); }
return $real;}
/** * Build a compressed, font-subsetted document and return its bytes. * * @param non-empty-string $fontDirectory Validated directory of embeddable fonts. * * @return string Raw PDF bytes. */function buildCompactPdf(string $fontDirectory): string{ // compress is true by default; pin it so the intent is explicit and the // streaming writer path honours it regardless of any wrapper defaults. $config = (new Config()) ->withCompress(true) ->withFontsDirectory($fontDirectory) // Bound the image cache so a build cannot exhaust memory. This is a // memory ceiling, not an output-size control. ->withImageCacheBytes(16 * 1024 * 1024);
$doc = Document::createStandalone($config); $doc->addFontDirectory($fontDirectory); $doc->addPage();
// Rendering with an embeddable face records the used codepoints, which the // writer turns into a font subset at build time. $doc->setFont('LiberationSans', '', 12); $doc->cell(0, 10, 'Invoice 2026', newLine: true); $doc->cell(0, 10, 'Compressed streams plus an automatic font subset.', newLine: true);
// getPdfData() triggers the build: page streams and the subset font program // are FlateDecode-compressed before the bytes are returned. return $doc->getPdfData();}
try { $fontDirectory = resolveFontDirectory(); $pdf = buildCompactPdf($fontDirectory);} catch (CompressionException $e) { // Raised if the zlib encoder hard-fails while compressing a stream. throw new RuntimeException( sprintf('Compression failed for a %s stream.', $e->getAlgorithm()), previous: $e, );} catch (InvalidConfigException $e) { // Raised by the output path for an invalid destination configuration. throw new RuntimeException( sprintf('Output configuration "%s" was rejected.', $e->getConfigKey()), previous: $e, );}
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$path = $out !== false && $out !== '' ? $out : __DIR__ . '/small.pdf';
if (file_put_contents($path, $pdf) === false) { throw new RuntimeException(sprintf('Could not write PDF to "%s".', $path));}
printf("Wrote %d bytes to %s.\n", strlen($pdf), $path);เอาต์พุต STDOUT ที่คาดหวัง (จำนวนไบต์ขึ้นอยู่กับฟอนต์และการสร้าง):
Wrote <n> bytes to <path>.กรณีขอบและจุดที่ต้องระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและจุดที่ต้องระวัง”- การบีบอัดเปิดอยู่ตามค่าเริ่มต้น
Configที่สร้างขึ้นใหม่มีcompressตั้งค่าเป็นtrueคุณแทบไม่จำเป็นต้องใช้withCompress()เลย ตั้งค่าอย่างชัดเจนเพียงเพื่อบันทึกเจตนา หรือเพื่อปิดใช้ในการสร้างสำหรับดีบักเมื่อต้องการอ่านสตรีมดิบ - การปิดการบีบอัดทำให้ไฟล์ใหญ่ขึ้น ไม่ใช่เล็กลง
withCompress(false)เป็นเครื่องมือวินิจฉัยสำหรับตรวจสอบสตรีมที่ไม่ได้บีบอัด ไม่เคยเป็นการปรับให้เหมาะสมด้านขนาด เมื่อนำส่งจริง ให้เปิดการบีบอัดไว้ - การทำซับเซตต้องใช้ฟอนต์ที่ฝังจริง ฟอนต์มาตรฐาน Base14 (Helvetica, Times, Courier และตระกูลที่เกี่ยวข้อง) ถูกอ้างอิงด้วยชื่อและไม่ได้บรรจุโปรแกรมฟอนต์ที่ฝังในเอกสารธรรมดา จึงไม่มีอะไรให้ทำซับเซต การทำซับเซตลดขนาดได้เฉพาะแบบอักษรที่คุณฝังจากไฟล์ฟอนต์เท่านั้น
- การทำซับเซตเกิดขึ้นอัตโนมัติและไม่มีการยืนยัน ไม่มีแฟล็ก ไม่มีเมท็อด และไม่มีการยืนยัน ถ้าคุณฝังฟอนต์และเรนเดอร์ข้อความด้วยฟอนต์นั้น ตัวเขียนได้ทำซับเซตให้แล้ว โปรแกรมที่ฝังมีแท็กคำนำหน้าซับเซตหกตัวอักษร (ตัวอย่างเช่น
ABCDEF+LiberationSans) เพื่อให้ตัวอ่านแยกซับเซตออกจากการฝังแบบเต็มได้ - การประหยัดเพียงเล็กน้อยจะคงฟอนต์เต็มไว้ เมื่อการทำซับเซตจะประหยัดได้น้อยกว่าสิบเปอร์เซ็นต์ของขนาดโปรแกรม ตัวทำซับเซตจะคืนต้นฉบับกลับมา นี่เป็นขีดจำกัดล่างที่จงใจ: ต้นทุนการสร้างใหม่ไม่คุ้มกับผลที่ได้เพียงเล็กน้อย การฝังแบบอักษรที่มีขนาดเล็กอยู่แล้ว หรือการเรนเดอร์กลิฟเกือบทั้งหมดของแบบอักษรนั้น อาจตกอยู่ในกรณีนี้ได้
imageCacheBytesไม่ใช่ปุ่มปรับขนาดภาพ จำกัดหน่วยความจำ ไม่ใช่ไบต์เอาต์พุต NextPDF Core ฝังข้อมูลภาพที่คุณให้มา ไม่มีขั้นตอนการสุ่มตัวอย่างใหม่ การลดความละเอียด หรือการเข้ารหัสใหม่ ถ้าคุณต้องการภาพที่เล็กลง ให้ปรับขนาดและเข้ารหัสใหม่ก่อนฝัง- ไม่มีการตั้งค่าออบเจกต์สตรีมหรือการลดข้อมูลซ้ำ NextPDF Core ไม่เปิดให้ใช้สวิตช์เปิดปิดสำหรับออบเจกต์สตรีมของ PDF 2.0 หรือสำหรับการลดข้อมูลทรัพยากรที่ซ้ำกัน จึงไม่มีตัวเลือกดังกล่าวให้ใช้ ตัวควบคุมขนาดมีเพียงการบีบอัดสตรีมและการทำซับเซตฟอนต์
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”การบีบอัดที่ระดับ 9 เป็นส่วนที่ใช้ CPU หลักของการเขียนสตรีม โดยเพิ่มเวลาในการสร้างไม่กี่เปอร์เซ็นต์เพื่อแลกกับเอาต์พุตที่เล็กที่สุด ต้นทุนแปรผันตรงตามจำนวนไบต์ที่ยังไม่ได้บีบอัด ดังนั้นจำนวนหน้าและปริมาณข้อมูลฟอนต์ที่ฝังจึงเป็นตัวกำหนดงบประมาณ การทำซับเซตเพิ่มการประมวลผลครั้งเดียวต่อแบบอักษรที่ฝังหนึ่งตัว โดยแจงไดเรกทอรีตารางของฟอนต์ แก้ไขโคลสเชอร์ของกลิฟที่ใช้งาน และสร้างตารางที่จำเป็นขึ้นใหม่ สำหรับแบบอักษร CJK ขนาดใหญ่ นี่เป็นกลไกที่มีต้นทุนสูงกว่าในสองส่วนนี้ แต่ทำงานครั้งเดียวต่อฟอนต์ ไม่ใช่ครั้งเดียวต่อหน้า ขีดจำกัดล่างการประหยัดสิบเปอร์เซ็นต์มีอยู่ส่วนหนึ่งเพื่อกันการประมวลผลนั้นออกจากเส้นทางที่ถูกเรียกบ่อยเมื่อจะไม่คุ้มค่า เอกสารขนาดเล็กที่มีซับเซตที่ฝังหนึ่งชุดมักอยู่ภายในงบเวลา wall-clock 1500 ms และหน่วยความจำสูงสุด 96 MB ได้สบาย จำกัด imageCacheBytes ให้อยู่ในเพดานจริงของระบบของคุณ เพื่อให้การสร้างที่ฝังภาพจำนวนมากล้มเหลวเร็วด้วยข้อจำกัดหน่วยความจำแทนที่จะเข้าสู่การสว็อป
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”การสร้างทำงานภายในโพรเซส ไม่มีไบต์ของเอกสารออกจากโฮสต์และไม่มีการเรียกใช้เครือข่าย ถือว่าฟอนต์หรือภาพใด ๆ ที่มาจากภายนอกเป็นอินพุตที่ไม่น่าเชื่อถือ:
- ตรวจสอบความถูกต้องของไดเรกทอรีฟอนต์ ตัวอย่างสำหรับการใช้งานจริงอ่านเส้นทางฟอนต์จากตัวแปรสภาพแวดล้อมที่เซิร์ฟเวอร์ควบคุม และปฏิเสธไดเรกทอรีที่หายไปหรืออ่านไม่ได้ก่อนฝัง ห้ามรับเส้นทางฟอนต์จากฟิลด์ของคำขอโดยเด็ดขาด
- ฝังเฉพาะฟอนต์ที่คุณได้รับอนุญาตให้แจกจ่ายซ้ำ ซับเซตยังคงเป็นโปรแกรมฟอนต์แบบฝัง ยืนยันว่าใบอนุญาตอนุญาตให้ฝังได้ก่อนที่คุณจะนำส่งเอกสารที่บรรจุแบบอักษรนั้น
- ฟอนต์ที่มีรูปแบบไม่ถูกต้องจะยกข้อยกเว้น ไม่ได้ทำให้เสียหายอย่างเงียบ ๆ ไฟล์ฟอนต์ที่แยกวิเคราะห์ไม่สำเร็จจะยก
NextPDF\Exception\FontParsingExceptionและความล้มเหลวร้ายแรงของ zlib จะยกNextPDF\Exception\CompressionExceptionดักจับข้อยกเว้นที่เจาะจงที่สุดและจัดการข้อยกเว้นนั้น อย่าห่อการสร้างไว้ในบล็อกcatchที่ว่างเปล่าเด็ดขาด - อย่าแทรกค่าอินพุตของผู้ใช้เข้าไปในเส้นทางเอาต์พุตเด็ดขาด ตัวอย่างเขียนไปยังเส้นทางที่กำหนดตายตัวหรือช่องทางแยกที่เซิร์ฟเวอร์ควบคุม และปฏิเสธ stream wrapper และไบต์ว่าง (null byte) ผ่านตัวเขียนแบบอะตอมมิกใน
save()ให้เส้นทางเอาต์พุตมาจากค่าที่เซิร์ฟเวอร์ควบคุมเพื่อหลีกเลี่ยงการเจาะผ่านเส้นทาง (path traversal) - ห้ามมีความลับในเอกสาร อย่าฝังข้อมูลรับรอง โทเค็น หรือตัวระบุภายในไว้ในเอกสารที่สร้างขึ้นซึ่งคุณส่งคืนให้ไคลเอนต์
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”เรซิพีนี้ไม่ได้อ้างว่าเป็นไปตามมาตรฐานบังคับใด ๆ ด้วยตัวเอง กลไกที่ใช้ถูกกำหนดไว้ในข้อกำหนด PDF 2.0: การบีบอัดสตรีม FlateDecode (ISO 32000-2:2020 §7.4.4) และการตั้งชื่อซับเซตฟอนต์ด้วยคำนำหน้าซับเซตหกตัวอักษร (ISO 32000-2:2020 §9.9) NextPDF สร้างทั้งสองอย่างเป็นส่วนหนึ่งของเส้นทางการเขียนมาตรฐาน คุณไม่ได้กำหนดค่าใด ๆ นอกเหนือจากแฟล็ก compress โปรไฟล์การทำซ้ำได้แบบ structural ที่หน้านี้ประกาศสะท้อนว่าตัวเขียนตรึงระดับ DEFLATE ไว้ ดังนั้นสตรีมที่บีบอัดจึงกำหนดได้แน่นอน ขณะที่ตัวระบุระดับเอกสารอาจยังต่างกันระหว่างการรัน เว้นแต่คุณจะกำหนดการตั้งค่าแบบกำหนดได้แน่นอนด้วย สำหรับกลไกการฝังที่อยู่เบื้องหลังการทำซับเซต โปรดดูเรซิพี embed-and-subset ที่ลิงก์ไว้ด้านล่าง
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- ฝังและทำซับเซตฟอนต์ TrueType — ลงทะเบียนแบบอักษร เรนเดอร์ด้วยแบบอักษรนั้น และตรวจสอบแท็กซับเซตที่ฝัง
- ประกอบข้อความและฟอนต์ — พื้นผิวการประกอบข้อความและฟอนต์ที่กว้างกว่าซึ่งป้อนให้เส้นทางการทำซับเซต
- เอกสารอ้างอิงโมดูลการกำหนดค่า — value object
Configฉบับเต็ม เมท็อด wither และค่าเริ่มต้นของแต่ละตัว - การจัดการข้อผิดพลาดที่รับรู้ข้อยกเว้น — ลำดับชั้นข้อยกเว้นของ NextPDF ที่รองรับ
CompressionException,FontParsingExceptionและInvalidConfigExceptionทั้งหมด