@@ -13,7 +13,9 @@ Date Author Change
1313using EPPlus . Fonts . OpenType . Tables . Glyph ;
1414using EPPlus . Fonts . OpenType . Tables . Head ;
1515using EPPlus . Fonts . OpenType . Tables . Loca ;
16+ using System ;
1617using System . Collections . Generic ;
18+ using System . IO ;
1719
1820namespace EPPlus . Fonts . OpenType . Subsetting
1921{
@@ -36,7 +38,6 @@ public void Discover(FontSubsettingContext context)
3638
3739 public void Rewrite ( FontSubsettingContext context )
3840 {
39- // NewToOldGlyphId is sorted by new IDs (0, 1, 2...)
4041 var sortedOldIds = context . NewToOldGlyphId ;
4142 List < Glyph > newGlyphs = new List < Glyph > ( sortedOldIds . Count ) ;
4243
@@ -58,20 +59,32 @@ public void Rewrite(FontSubsettingContext context)
5859 // 2. Save the new glyf table
5960 context . SubsetFont . AddOrReplaceTable ( new GlyfTable ( newGlyphs ) ) ;
6061
61- // 3. Build loca table with 4-byte alignment
62+ // 3. Build loca by ACTUALLY measuring serialized glyphs
6263 List < uint > offsets = new List < uint > { 0 } ;
63- uint currentOffset = 0 ;
6464
65- foreach ( Glyph g in newGlyphs )
65+ using ( var ms = new MemoryStream ( ) )
66+ using ( var writer = new FontsBinaryWriter ( ms ) )
6667 {
67- int size = g . GetSize ( ) ;
68- uint paddedSize = ( uint ) ( ( size + 3 ) & ~ 3 ) ; // Align to 4 bytes
69- currentOffset += paddedSize ;
70- offsets . Add ( currentOffset ) ;
68+ foreach ( Glyph g in newGlyphs )
69+ {
70+ long startPos = ms . Position ;
71+ g . Serialize ( writer ) ;
72+ long endPos = ms . Position ;
73+
74+ int writtenLength = ( int ) ( endPos - startPos ) ;
75+ int padding = ( 4 - ( writtenLength % 4 ) ) % 4 ;
76+
77+ for ( int p = 0 ; p < padding ; p ++ )
78+ writer . Write ( ( byte ) 0 ) ;
79+
80+ offsets . Add ( ( uint ) ms . Position ) ;
81+ }
82+
83+ Console . WriteLine ( $ "Total glyf table size: { ms . Position } bytes, loca last offset: { offsets [ offsets . Count - 1 ] } ") ;
7184 }
7285
73- // 4. Update head table format and add loca table
74- bool useShortOffsets = currentOffset <= 131070 ;
86+ // 4. Update head and create loca
87+ bool useShortOffsets = offsets [ offsets . Count - 1 ] <= 131070 ;
7588 context . SubsetFont . HeadTable . IndexToLocFormat = useShortOffsets
7689 ? HeadTable . IndexToLocFormats . Offset16
7790 : HeadTable . IndexToLocFormats . Offset32 ;
0 commit comments