Repository navigation
Fetch large font files in the background when a PDF needs them - #2014
Merged
Merged
Conversation
Contributor
|
Coverage report for commit: ef4857f Summary - Lines: 93.99% | Methods: 90.96% | Branches: 85.58%
🤖 Jest coverage report |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Contributor
|
Coverage report for commit: ef4857f Summary - Lines: 90.27% | Methods: 95.90%
🤖 PHPUnit coverage report |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 of 6 tasks
gravitypdf-bot
force-pushed
the
feature/fetch-cjk-substitutes
branch
from
November 6, 2026 00:33
5c07450 to
09d16ab
Compare
gravitypdf-bot
changed the base branch from
feature/core-font-upgrade-prune
to
feature/font-file-conflict-rename
November 6, 2026 00:34
jakejackson1
force-pushed
the
feature/font-file-conflict-rename
branch
from
November 6, 2026 03:06
f7acf3e to
74c3b06
Compare
gravitypdf-bot
force-pushed
the
feature/font-file-conflict-rename
branch
from
November 9, 2026 05:30
74c3b06 to
1ad0a3c
Compare
gravitypdf-bot
force-pushed
the
feature/font-file-conflict-rename
branch
2 times, most recently
from
November 9, 2026 06:09
62cbe50 to
38e02af
Compare
Base automatically changed from
feature/font-file-conflict-rename
to
development
November 9, 2026 06:13
gravitypdf-bot
force-pushed
the
feature/fetch-cjk-substitutes
branch
2 times, most recently
from
November 10, 2026 05:42
1f8e648 to
9aafcec
Compare
A downloadable font file over 5 MB (Model_Font_Sources::LARGE_FILE_SIZE, read from the manifest's size, so it covers plugin-added sources and later manifests too) is never downloaded mid-render. On today's manifest that's Sun-ExtA (23 MB), Sun-ExtB (17.6 MB) and Aegyptus (5.8 MB); UnBatang (4.97 MB) is just under. When mPDF asks the on-demand finder for a missing large file, Model_Font_Downloader::download_or_queue() adds it to a "wanted" list (gfpdf_font_wanted, a network option like the failure record) and queues the background sync, marks the render degraded through Helper_Render_Health and returns the fallback font. The sync fetches required + wanted files with the same retry, give-up and failure notice, and the 6.19 upgrade cleanup keeps wanted files. A file whose downloads are off, or that gave up, isn't queued and the render is cached as before. Debug Mode falls back for a queued file too, since it isn't an error; a large file that can't download still throws there. Because the finder no longer downloads a large file mid-render, Sun-ExtA is listed in backupSubsFont and Sun-ExtB left as mPDF's backupSIPFont (with Sun-ExtA's sip-ext link) whether or not they're on disk. mPDF's FontSubstitution (GravityPDF/mpdf#827, #837) already picks a substitute from the ranges files the fork ships, without loading the font, and asks the finder only when a character needs it. That is the detection: an English site rendering CJK text queues Sun-ExtA, a CJK Extension B character queues Sun-ExtB, and Extension E (no core font has it), Latin or emoji text queues nothing. A selected or CSS font that's a large file goes the same way. An earlier draft scanned the HTML before the render against the ranges files; it duplicated mPDF's scan rules (skipped blocks, Plane 2, ranges parsing) and added an HTML pass to every render, so it was dropped for this. Degraded rather than a cache-generation bump when the download completes: the render that lacked the font is never cached, so nothing needs invalidating, and other PDFs' cached copies aren't thrown away when a font arrives. A large file whose name another font holds (a hand-replaced Sun-ExtA, found by size alone) follows the same rule: the finder queues the manifest's, marks the render degraded and keeps the file at the name in use for that render. A hashed copy of a large file is used without queueing, whether or not the plain file is there. The wanted list is a main-network option, as the failure record is. The gfpdf-dejavu-symbols stand-in for backupSIPFont is gone: mPDF's default Sun-ExtB is always the SIP font now. Jomolhari and Quivira stay off the substitution list (follow-up). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gravitypdf-bot
force-pushed
the
feature/fetch-cjk-substitutes
branch
from
November 10, 2026 05:54
6d53090 to
ef4857f
Compare
This was referenced Nov 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Font files over 5 MB are no longer downloaded in the middle of a PDF render. When a PDF needs one, it renders without that font, the file goes into the background font sync, and that render isn't cached, so the next view after the download draws the missing characters. Until now, an English site rendering CJK entry text never got Sun-ExtA, and Sun-ExtB was never fetched at all. A file counts as large by the manifest's
size, so plugin-added sources and later manifests are covered without a hard-coded list. On today's manifest that's Sun-ExtA (23 MB), Sun-ExtB (17.6 MB) and Aegyptus (5.8 MB); UnBatang (4.97 MB) is just under. Answers #2005's render-cache question.Model_Font_Downloader::download_or_queue()queues a missing large file instead of downloading it and marks the render degraded (Helper_Render_Health). The on-demand finder calls it in place ofdownload()and returns the fallback font. Debug Mode falls back too for a queued file; a large file that can't be downloaded (downloads off, or it gave up) still throws there.Model_Font_Downloaderhas a "wanted" list (gfpdf_font_wanted, a main-network option like the failure record). The sync fetches required + wanted files with the same retry, give-up and failure notice, and the queued 6.19 upgrade cleanup keeps wanted files. An outdated Sun-ExtA or Sun-ExtB is still removed, and the sync fetches the current one.backupSubsFont. Sun-ExtB stays as mPDF'sbackupSIPFontand Sun-ExtA'ssip-ext, on disk or not.FontSubstitutionalready reads each substitute's ranges file without loading the font. It now drives detection: mPDF reaches the finder only when a character needs that font.gfpdf-dejavu-symbolsstand-in forbackupSIPFontis removed.Try it
Sun-ExtA.ttf), view a PDF of an entry with Japanese text, e.g.日本語.wp cron event run gfpdf_core_font_sync).Sun-ExtA.ttfappears in the fonts folder.𠀀(CJK Extension B), which queuesSun-ExtB.ttf.add_filter( 'gfpdf_auto_install_fonts', '__return_false' ), nothing is queued and the PDF is cached as before.Test plan
Test_Font_Rendering,Test_Model_Font_Sources,Test_Model_Font_Downloader,Test_On_Demand_Font_File_Finder,Test_Helper_PDF,Test_Uninstaller,Test_Model_Required_Fonts,Test_Model_Pdf_Render_Cache,Test_System_Report,Test_Controller_Font_Downloader,Test_Controller_Upgrade_Routines,Test_Git_Blob,Test_Downloaded_Fonts.test_an_unwritable_folder_fails_without_a_requestx2,Test_Git_Blob::test_an_unreadable_file_has_no_hash,test_the_kill_switch_constant_turns_downloads_off.src/files.More info
Threshold.
Model_Font_Sources::LARGE_FILE_SIZE = 5 * MB_IN_BYTES, compared with the manifest entry'ssizeinis_large_file(). The manifest is only read on a finder miss, as before, so a render with its fonts on disk still never loads it.Detection. An earlier draft scanned the HTML before the render against the fork's ranges files. It had to copy mPDF's rules: the Arabic/Indic blocks it never substitutes, Plane 2 going to
backupSIPFont, ranges parsing. It also added an HTML pass to every render. Once the finder stopped downloading large files mid-render, there was no reason to keep large substitutes out of the lists. mPDF'sFontSubstitution(GravityPDF/mpdf#827, #837) already picks a substitute from the shipped ranges files without loading it, and only asks the finder when a character needs it. So:backupSIPFontor Sun-ExtA'ssip-ext.Detection needs no ranges file for a selected font. A large substitute needs one, and all three large core files have one. A plugin-added large file without one is only reached as a selected font.
Cache. The render is marked degraded instead of bumping the cache generation when a download completes. The render that lacked the font is never cached, so there's nothing to invalidate, and other PDFs' cached copies survive a font arriving.
Side effects to know about:
Follow-ups, not in this PR: Jomolhari (2.2 MB Tibetan) and Quivira (1.4 MB symbols) on the substitution list.