Repository navigation
Strip TrueType hinting from the packaged fonts whose licences allow it - #853
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gravitypdf-bot
force-pushed
the
chore/dehint-fonts
branch
from
November 5, 2026 01:38
0a01984 to
2f975f6
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 tasks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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
Ports #850 from
gravitypdf-v6togravitypdf. The packaged fonts carry TrueType hinting that mPDF copies into every PDF embedding them. This strips it from the 51 fonts with real hinting and a licence that allows the change, which takes 10.94 MB (24.3%) off those files and about 24% off sampled PDFs using them.DSIGfrom 51 fonts inpackages/: Aboriginal Sans, Ayar, DejaVu, GNU FreeFont, Garuda, Khmer OS, Lohit Kannada, MPH 2B Damase, Pothana 2000, UnBatang and XB Riyaz.utils/dehint_fonts.py, which holds the vetted font list by package and the reason the others are left out.sizechanged. Their character ranges are the same.AddFontTestcomparelength1with the font's real size instead of a hardcoded number.composer.jsonand the bundle READMEs.CHANGELOG-GRAVITYPDF.md, and a line to the README of each changed package saying its fonts are modified.Check before merging: a family registered from a font package whose font is then loaded as a hinted copy from elsewhere now logs a size warning. A family in plain
fontdatadoesn't. This matters only if the plugin moves to this branch and registers those fonts as packages. See "Ranges warning" below.Try it
Rebuilds the fonts and ranges from the script. The tree should stay clean.
Test plan
unicode-zero-width-space, looks acceptableMore info
How this differs from #850
gravitypdf-v6(#850)gravitypdf(this PR)ttfonts/packages/<package>/fonts/data/character-ranges/packages/<package>/fonts/<font file>.ranges.php, written bycomposer ranges:updatefrom the registered packagesCHANGELOG.mdCHANGELOG-GRAVITYPDF.md, becauseCHANGELOG.mdis kept identical to upstream'sGaruda.ttf.AboriginalSansREGULAR.ttfis a newer build here (9.602 against 9.601, 1,445,592 bytes against 800,480). Same licence, so it's kept on the list.UnBatang_0613.ttfisn't here.UnBatang.ttfandUnBatangBold.ttftake its place, both GPL, so both are stripped. They give 4.2 MB of the saving.Quivira.otfdiffers from v6's but has no hinting either.0.1, not published yet andexport-ignored from archives. No manifest, size or hash other than the ranges files records the fonts.AGENTS.mddoesn't exist ongravitypdf, so I followed v6's copy andCHANGELOG-GRAVITYPDF.md's own conventions.Why the fixtures changed
On v6, snapshot tests compare pixels, so the old fixtures keep passing. Here
Snapshotcompares bytes, then objects, then pages.composer testruns the snapshots too, andtests.ymlinstalls no Imagick, so a fixture whose font stream changed fails there: withCI=1and no Imagick,TableBackgroundSnapshotTestfails with "Imagick is not installed".So 218 of the 235 snapshot tests needed new fixtures, and the suite's own notice asks for that (
composer snapshot:update). They were checked against the old fixtures before being replaced:/Length1, the font streams' size and hash, and, in documents with XMP metadata, the document UUID that follows from them. No page content, widths or font dictionaries moved.unicode-zero-width-spacediffers (RMSE 0.0075). Only its rotatedtextcirclewords in DejaVu Sans change: Ghostscript drew them thinner with the hints. Poppler gives the same pixels for the old and new document. That change is the only one a reader of the fixtures could see, and I looked at it enlarged: the text is correct, and slightly heavier.khmer-coengis the 218th, added with the second commit. Poppler renders it pixel-identically, and regenerating every fixture afterwards changed no other file. The refreshed fixtures are 1.43 MB smaller in total.exif-orientation,exif-orientation-greyscaleandpng-transparencygo through GD and were written on macOS. They were byte-identical on this machine before this change, so they should behave on CI as they did.Verification
fontTools 4.68.0, Ghostscript and poppler
pdftoppm, PHP 8.5.12 on macOS.glyf,locaheadandmaxpcheckSumAdjustment,maxSizeOfInstructionsand, in one font,indexToLocFormatdiffercomposer ranges:updatesizelines, 17 filesvendor/bin/phpunit --no-coverage, with ImagickCI=1and no Imagick, astests.ymlruns itphpcsonAddFontTest.phpTableChecksumTest::testMatchesTheChecksumsAFontStates, which asserts once per table of the font. The font has lostcvt,fpgm,prepandgasp. Per-test JUnit output on both trees shows no other change.useOTLoff: 3,101,313 to 2,367,633 bytes (23.7%). Real documents will vary, and complex-script shaping isn't covered by that comparison.src/changes), Acrobat or browser viewers.Ranges warning
I ran this with a
fontFileFinderhanding back the hinted originals:garudafrom its registered package, as a backup font, loaded from outside the package... may have moved text into the wrong font: it was written for a font of 39092 bytes, but the "garuda" font loaded is 55756 bytes. Write the file again with vendor/bin/mpdf-font-ranges.fontdata, with no packageThe ranges are the same either way, so the warning is noise, but its wording suggests a real problem. It differs from v6, where any shipped family and file name match
data/character-ranges/. Here it applies only to families registered from a package.The plugin requires
dev-gravitypdf-v6today, so nothing changes for it yet. When it moves to this branch, this depends on how it registers its fonts. Itsfonts/core-fonts.jsonalso recordsmpdf-core-fontsv1.0.0's sizes and hashes, which stay hinted and aren't touched here. I've left the decision open.Licence questions
LICENSE.txthere say LGPL 2.1, with a trademark notice and no Reserved Font Name. The v6 branch also has aKhmerOFL.txtreserving the name "Khmer", dated 2010, which is why Strip TrueType hinting from the bundled fonts whose licences allow it #850 excluded it. This file is version 3.01 from 2005 and states LGPL itself, so I read that text as belonging to a different font. That's an inference, and the maintainer has accepted it.All three files match
mpdf-core-fontsv1.1.0, which still has them hinted.Size figures
composer.jsonand the bundle READMEs now give the installed size of each package's files: Font Bundle All goes from 110MB to 99MB, Font Bundle Lite from 30MB to 26MB, and DejaVu from 10MB to 9MB.