Skip to content

Conversation

Hoolean
Copy link
Contributor

@Hoolean Hoolean commented Apr 6, 2025

This saves a handful of bytes for the common case where a font is variable but has no variation in its advances (e.g. for some monospace fonts across wght), and we include an empty metrics variation table so that the shaper can immediately ascertain this without interpolating phantom points.

e.g. a direct mapping is now preferred for the font in the included test case, shrinking the table from 47 to 42 bytes

--- before.xml
+++ after.xml
@@ -1,19 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Version value="0x00010000"/>
 <VarStore Format="1">
   <Format value="1"/>
   <VarRegionList>
     <!-- RegionAxisCount=1 -->
     <!-- RegionCount=0 -->
   </VarRegionList>
   <!-- VarDataCount=1 -->
   <VarData index="0">
     <!-- ItemCount=1 -->
     <NumShorts value="0"/>
     <!-- VarRegionCount=0 -->
     <Item index="0" value="[]"/>
   </VarData>
 </VarStore>
-<AdvWidthMap>
-  <Map glyph="A" outer="0" inner="0"/>
-</AdvWidthMap>

This optimisation is mostly relevant as it brings fontTools in line with fontc's compilation of direct mappings (see googlefonts/fontc#1388).

This area of the API is a bit new to me though - would someone be willing to confirm that I am holding the prune_regions() function correctly?

Note: this is a personal contribution independent of my employer, and so I've submitted from a fork under my personal profile and email to make this distinction

@Hoolean Hoolean force-pushed the optimal-direct-vhvar branch from edb2a4b to b8ef67e Compare April 6, 2025 15:45
This saves a handful of bytes for the common case where a font is
variable but has no variation in its advances (e.g. for some monospace
fonts across `wght`), and we include an empty metrics variation table so
that the shaper can immediately ascertain this without interpolating
phantom points.
@Hoolean
Copy link
Contributor Author

Hoolean commented Apr 6, 2025

I've rebased to fix TTX snapshots tests that needed updating, as the direct store is preferred over the indirect store in further cases now that region pruning makes it smaller.

@behdad
Copy link
Member

behdad commented Apr 6, 2025

On the surface sounds right to me.

@Hoolean
Copy link
Contributor Author

Hoolean commented Apr 9, 2025

Cheers Behdad :)

For good measure, I've hardcoded useDirect to build Roboto Flex with and without a direct HVAR and compared with diffenator3 at the default instances, and no differences were found:

$ ttx -l variable_direct/RobotoFlex-VF.ttf 
Listing table info for "variable_direct/RobotoFlex-VF.ttf":
    tag     checksum    length    offset
    ----  ----------  --------  --------
    GDEF  0xC8A1A16B     33475     65904
    GPOS  0x723EEDAE     53842     99380
    GSUB  0x6D331840      1014    153224
    HVAR  0x6E496267    109750    154240
    MVAR  0x63F72F2D      2033    263992
    OS/2  0xA206B3ED        96       440
    STAT  0xEEEA60CA       124    266028
    avar  0x5C2D2D6A       198    266152
    cmap  0xEE6B7E4F      1330      4328
    fvar  0x4B7B6DF4      1396    266352
    glyf  0x10192E34     45776      7560
    gvar  0x0C1FADA4   1366130    267748
    head  0x10F8F275        54       316
    hhea  0x102A0AB2        36       372
    hmtx  0x7E4C67E5      3792       536
    loca  0x80FB5567      1898      5660
    maxp  0x03C700A4        32       408
    name  0x73CE5D82      2256     53336
    post  0xC39C296C     10310     55592
$ ttx -l variable_indirect/RobotoFlex-VF.ttf 
Listing table info for "variable_indirect/RobotoFlex-VF.ttf":
    tag     checksum    length    offset
    ----  ----------  --------  --------
    GDEF  0xC8A1A16B     33475     65904
    GPOS  0x723EEDAE     53842     99380
    GSUB  0x6D331840      1014    153224
    HVAR  0xEEB84E58     35711    154240
    MVAR  0x63F72F2D      2033    189952
    OS/2  0xA206B3ED        96       440
    STAT  0xEEEA60CA       124    191988
    avar  0x5C2D2D6A       198    192112
    cmap  0xEE6B7E4F      1330      4328
    fvar  0x4B7B6DF4      1396    192312
    glyf  0x10192E34     45776      7560
    gvar  0x0C1FADA4   1366130    193708
    head  0x10F8F301        54       316
    hhea  0x102A0AB2        36       372
    hmtx  0x7E4C67E5      3792       536
    loca  0x80FB5567      1898      5660
    maxp  0x03C700A4        32       408
    name  0x73CE5D82      2256     53336
    post  0xC39C296C     10310     55592
$ diffenator3 --no-tables variable_direct/RobotoFlex-VF.ttf variable_indirect/RobotoFlex-VF.ttf --json
Diffing kerning
Testing Thin
Testing ExtraLight
Testing Light
Testing Regular
Testing Medium
Testing SemiBold
Testing Bold
Testing ExtraBold
Testing Black
Testing ExtraBlack
Testing Thin Italic
Testing ExtraLight Italic
Testing Light Italic
Testing Italic
Testing Medium Italic
Testing SemiBold Italic
Testing Bold Italic
Testing ExtraBold Italic
Testing Black Italic
Testing ExtraBlack Italic
{"cmap_diff":{}}

@Hoolean
Copy link
Contributor Author

Hoolean commented Apr 9, 2025

Anything else to test, or are we confident enough to merge?

@behdad behdad merged commit 6120962 into fonttools:main Apr 9, 2025
11 checks passed
@Hoolean Hoolean deleted the optimal-direct-vhvar branch April 9, 2025 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants