Repository navigation
Add an option to strip embedded fonts - #49
Merged
Merged
Conversation
A producer embeds a subset of whichever copy of a font the machine has installed, so two machines with different versions of one font render the same document to different bytes. stripEmbeddedFonts removes the font programs and the descriptor entries pointing at them, and repairs the cross-reference table or stream.
This was referenced Oct 9, 2026
This was referenced Oct 9, 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.
Problem
A producer embeds a subset of whichever copy of a font the machine has installed. A developer machine with Arial 7.06 and a build agent with Arial 7.01 therefore render the same document to different bytes. The two font programs draw the same glyphs, but they differ in content and in length, and being compressed they hold nothing that could be zeroed. Aspose.Words, Aspose.Cells and Aspose.PDF all behave this way.
Change
Every
Normalize/NormalizeAsyncoverload gains a counterpart takingbool stripEmbeddedFonts. They are new overloads rather than an optional parameter, so this is not a binary break. It is off by default because it is lossy: a viewer opening the result substitutes fonts of its own.For each font descriptor entry
/FontFile,/FontFile2or/FontFile3:/Length,/Length1,/Length2and/Length3are restated as0, in the dictionary or in the object an indirect one refers to.0too. Aspose.PDF leaves one behind even when the dictionary states the length directly.The stream sits in the middle of the body, so the cross-reference section is repaired:
Fonts are left embedded when the document cannot be safely rewritten: an incremental update, a hybrid table (
/XRefStm), a cross-reference stream with a predictor (/DecodeParms) or a filter other than/FlateDecode, or a font descriptor held in an/ObjStm.The pass runs last, so every other pass sees the document as the producer wrote it. Each removed entry is reported under its key (
/FontFile2).Version bumped to 2.2.0.
Testing
StripEmbeddedFontsTests.cs, each run against both a classic table and a cross-reference stream where that matters: differing font programs collapse to the same output, the offsets are read back and checked against the objects they point at, the pass is idempotent, and an incrementally updated document is left alone.