generated from jric11/baseProject
196 lines
9.2 KiB
PHP
196 lines
9.2 KiB
PHP
<?php
|
||
|
||
/**
|
||
* E052_custom_fonts_fallback.php
|
||
*
|
||
* Demonstrates custom font selection, Unicode coverage strategy, and
|
||
* font-family fallback across multiple scripts.
|
||
*
|
||
* What this demonstrates:
|
||
* - font->insert(): loading built-in and extended font families.
|
||
* - Subset vs full-embed tradeoff (constructor $subsetfont flag).
|
||
* - Choosing fonts by Unicode coverage: helvetica (Latin), dejavusans
|
||
* (Latin + Greek + Cyrillic + IPA), unifont (full Unicode BMP).
|
||
* - HTML font-family CSS mapping to pre-loaded font slots.
|
||
* - Per-script font selection in addHTMLCell markup.
|
||
*
|
||
* Companion libraries: tc-lib-pdf-font, tc-lib-unicode, tc-lib-unicode-data.
|
||
*
|
||
* @since 2026-05-01
|
||
* @category Library
|
||
* @package Pdf
|
||
* @author Nicola Asuni <info@tecnick.com>
|
||
* @copyright 2002-2026 Nicola Asuni - Tecnick.com LTD
|
||
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
|
||
* @link https://github.com/tecnickcom/tc-lib-pdf
|
||
*
|
||
* This file is part of tc-lib-pdf software library.
|
||
*/
|
||
|
||
// NOTE: local file reads (images, fonts, attachments) are restricted to an allowlist of
|
||
// trusted paths that covers this package tree, so run the examples in place. To read assets
|
||
// from other locations, list them in the 'allowedPaths' entry of the fileOptions constructor
|
||
// parameter (see E047_remote_resources_security.php).
|
||
|
||
// NOTE: run make fonts in the project root to generate the dependencies and example fonts.
|
||
|
||
require __DIR__ . '/../vendor/autoload.php';
|
||
|
||
// K_PATH_FONTS must point to the directory holding .z and .php font metric files.
|
||
define('K_PATH_FONTS', (string) realpath(__DIR__ . '/../vendor/tecnickcom/tc-lib-pdf-font/target/fonts'));
|
||
|
||
// Subset font embedding: when $subsetfont = true (constructor arg 3), only the
|
||
// glyphs actually used in the document are embedded. This produces smaller PDFs
|
||
// but makes the font unsuitable for later editing. Set to false for archival PDFs
|
||
// (PDF/A, PDF/UA) or whenever the full character set must be available.
|
||
$pdf = new \Com\Tecnick\Pdf\Tcpdf(
|
||
unit: \Com\Tecnick\Pdf\Page\Unit::Millimeter,
|
||
isunicode: true,
|
||
subsetfont: false,
|
||
compress: true,
|
||
mode: \Com\Tecnick\Pdf\PdfConformance::None,
|
||
objEncrypt: null,
|
||
);
|
||
|
||
$pdf->setCreator('tc-lib-pdf');
|
||
$pdf->setAuthor('Nicola Asuni');
|
||
$pdf->setSubject('tc-lib-pdf example: 052');
|
||
$pdf->setTitle('Custom Fonts & Unicode Fallback');
|
||
$pdf->setKeywords('TCPDF tc-lib-pdf font unicode multilingual fallback subset dejavusans unifont');
|
||
$pdf->setPDFFilename('052_custom_fonts_fallback.pdf');
|
||
$pdf->setViewerPreferences(['DisplayDocTitle' => true]);
|
||
$pdf->enableDefaultPageContent();
|
||
|
||
// ----------
|
||
// Pre-load all font families that will be used in the document.
|
||
// font->insert() returns a font descriptor array. The 'out' key contains
|
||
// the PDF operator stream that must be injected onto a page before the
|
||
// font is used. Loading fonts before addPage() registers them in the
|
||
// font object pool; injecting 'out' at the start of each page activates
|
||
// the font for that page.
|
||
|
||
// Helvetica: core Type-1, no embedding required, Latin + standard symbols only.
|
||
$fHelvetica = $pdf->font->insert($pdf->pon, 'helvetica', '', 11);
|
||
$fHelveticaB = $pdf->font->insert($pdf->pon, 'helvetica', 'B', 11);
|
||
|
||
// Times New Roman (core): serif alternative for body text, Latin only.
|
||
$fTimes = $pdf->font->insert($pdf->pon, 'times', '', 11);
|
||
|
||
// Courier (core): monospaced, Latin only; good for code samples.
|
||
$fCourier = $pdf->font->insert($pdf->pon, 'courier', '', 10);
|
||
|
||
// DejaVu Sans: TrueType, Latin + Greek + Cyrillic + IPA + many other scripts.
|
||
// Covers most Western European, Eastern European, and Slavic languages.
|
||
$fDejavu = $pdf->font->insert($pdf->pon, 'dejavusans', '', 11);
|
||
|
||
// Unifont: TrueType, very broad Unicode BMP (plane 0) coverage including Arabic,
|
||
// Hebrew, Thai, Devanagari, and many additional scripts.
|
||
// File size is large; use subset=true when embedding it in production PDFs.
|
||
$fUnifont = $pdf->font->insert($pdf->pon, 'unifont', '', 11);
|
||
|
||
// ===| Page 1 – Font Coverage Overview |=====================================
|
||
|
||
$pdf->addPage(['format' => 'A4']);
|
||
$pdf->page->addContent($fHelvetica['out']);
|
||
|
||
$overviewHtml = '<h1 style="font-family: helvetica;">Font Selection & Unicode Fallback</h1>
|
||
<p style="font-family: helvetica; font-size: 10pt;">
|
||
PDF viewers cannot substitute fonts automatically — every glyph must come from
|
||
an embedded font resource. The strategy is:
|
||
</p>
|
||
<ol style="font-family: helvetica; font-size: 10pt;">
|
||
<li>Use <strong>core Type-1 fonts</strong> (helvetica, times, courier) for Latin-only text to
|
||
avoid embedding overhead.</li>
|
||
<li>Upgrade to <strong>DejaVu Sans</strong> for pages that mix Latin with Greek, Cyrillic, or
|
||
extended Latin (diacritics, IPA).</li>
|
||
<li>Use <strong>Unifont</strong> for pages that require full Unicode BMP coverage (Arabic, Hebrew,
|
||
Thai, Devanagari, Hangul, CJK).</li>
|
||
</ol>
|
||
<p style="font-family: helvetica; font-size: 10pt;">
|
||
In HTML cells, specify the font via <code>style="font-family: dejavusans"</code> or
|
||
<code>style="font-family: unifont"</code>.
|
||
The name must match the lowercase font identifier known to tc-lib-pdf-font.
|
||
</p>
|
||
<hr/>
|
||
<h2 style="font-family: helvetica;">Core Type-1 Fonts (Latin)</h2>
|
||
<p style="font-family: helvetica; font-size: 11pt;">
|
||
<span style="font-family: helvetica;">Helvetica — The quick brown fox jumps over the lazy dog.</span>
|
||
</p>
|
||
<p style="font-family: times; font-size: 11pt;">
|
||
<span style="font-family: times;">Times — The quick brown fox jumps over the lazy dog.</span>
|
||
</p>
|
||
<p style="font-family: courier; font-size: 10pt;">
|
||
<span style="font-family: courier;">Courier — The quick brown fox jumps over the lazy dog.</span>
|
||
</p>';
|
||
$pdf->addHTMLCell(html: $overviewHtml, posx: 15, posy: 20, width: 175);
|
||
|
||
// ===| Page 2 – DejaVu Sans: Latin + Greek + Cyrillic |======================
|
||
|
||
$pdf->addPage(['format' => 'A4']);
|
||
$pdf->page->addContent($fDejavu['out']);
|
||
|
||
$dejavuHtml = '<h2 style="font-family: dejavusans;">DejaVu Sans — Extended Coverage</h2>
|
||
<p style="font-family: dejavusans; font-size: 10pt;">
|
||
DejaVu Sans covers Latin, Greek, Cyrillic, Armenian, Georgian, Hebrew,
|
||
Arabic (basic), and many more. Use it when helvetica glyphs are missing.
|
||
</p>
|
||
<h3 style="font-family: dejavusans;">Latin Extended</h3>
|
||
<p style="font-family: dejavusans; font-size: 11pt;">
|
||
Héllo Wörld — café, naïve, résumé, Ångström, façade, Ñoño.
|
||
</p>
|
||
<h3 style="font-family: dejavusans;">Greek (Ελληνικά)</h3>
|
||
<p style="font-family: dejavusans; font-size: 11pt;">
|
||
Ξεσκεπάζω την ψυχοφθόρα βδελυγμία.
|
||
</p>
|
||
<h3 style="font-family: dejavusans;">Cyrillic (Русский)</h3>
|
||
<p style="font-family: dejavusans; font-size: 11pt;">
|
||
Съешь же ещё этих мягких французских булок, да выпей чаю.
|
||
</p>
|
||
<h3 style="font-family: dejavusans;">IPA Phonetics</h3>
|
||
<p style="font-family: dejavusans; font-size: 11pt;">
|
||
/ˌɪntəˈnæʃənl/ · /fəˈnɛtɪk/ · /ˈælfəbɪt/
|
||
</p>
|
||
<hr/>
|
||
<p style="font-family: dejavusans; font-size: 9pt; color: #555555;">
|
||
Subset tip: dejavusans is ~750 KB uncompressed. With <code>$subsetfont = true</code> and
|
||
only the glyphs used in this page, the embedded subset would be much smaller.
|
||
For documents mixing many scripts across many pages, subset embedding is recommended.
|
||
</p>';
|
||
$pdf->addHTMLCell(html: $dejavuHtml, posx: 15, posy: 20, width: 175);
|
||
|
||
// ===| Page 3 – Unifont: Full BMP |==========================================
|
||
|
||
$pdf->addPage(['format' => 'A4']);
|
||
$pdf->page->addContent($fUnifont['out']);
|
||
|
||
$unifontHtml = '<h2 style="font-family: unifont; font-size: 11pt; font-weight: normal;">Unifont — Full Unicode BMP Coverage</h2>
|
||
<p style="font-family: unifont; font-size: 11pt;">
|
||
Unifont offers very broad Unicode Plane 0 (BMP) coverage.
|
||
Use it as a last-resort fallback for scripts not covered by DejaVu.
|
||
Production PDFs should always use <code>$subsetfont = true</code> with Unifont.
|
||
</p>
|
||
<h3 style="font-family: unifont; font-size: 11pt; font-weight: normal;">Arabic (العربية) — RTL</h3>
|
||
<p style="font-family: unifont; font-size: 11pt; text-align: right;">
|
||
صِف خَلقَ خَودِكِ كَمِثلِ الشَّمسِ إِذ بَزَغَت
|
||
</p>
|
||
<h3 style="font-family: unifont; font-size: 11pt; font-weight: normal;">Hebrew (עברית) — RTL</h3>
|
||
<p style="font-family: unifont; font-size: 11pt; text-align: right;">
|
||
דג סקרן שט בים מאוכזב ולפתע מצא חברה
|
||
</p>
|
||
<h3 style="font-family: unifont; font-size: 11pt; font-weight: normal;">Devanagari (हिन्दी)</h3>
|
||
<p style="font-family: unifont; font-size: 11pt;">
|
||
ऋषि सुयश ने प्रख्यात ग्रंथ की रचना करके हमें ज्ञान दिया।
|
||
</p>
|
||
<hr/>
|
||
<p style="font-family: unifont; font-size: 11pt; color: #555555;">
|
||
Fallback strategy: attempt to render with the most specific font first.
|
||
Only escalate to Unifont for code points absent from narrower families.
|
||
This minimises file size while ensuring every glyph is available.
|
||
</p>';
|
||
$pdf->addHTMLCell(html: $unifontHtml, posx: 15, posy: 20, width: 175);
|
||
|
||
// ----------
|
||
|
||
$rawpdf = $pdf->getOutPDFString();
|
||
$pdf->renderPDF(rawpdf: $rawpdf);
|