Skip to content

Commit

Permalink
Merge pull request #773 from googlefonts/sparse-notdef
Browse files Browse the repository at this point in the history
Make sparse layers without .notdef not participate in gvar/CFF2/HVAR
  • Loading branch information
anthrotype authored Aug 2, 2023
2 parents c0e8aa1 + 85e28b7 commit d1c5ad4
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 45 deletions.
6 changes: 3 additions & 3 deletions Lib/ufo2ft/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
TTFPreProcessor,
)
from ufo2ft.util import (
_getDefaultNotdefGlyph,
_notdefGlyphFallback,
colrClipBoxQuantization,
ensure_all_sources_have_names,
init_kwargs,
Expand Down Expand Up @@ -408,7 +408,7 @@ def compileInterpolatableTTFsFromDS(designSpaceDoc, **kwargs):
kwargs["skipExportGlyphs"] = designSpaceDoc.lib.get("public.skipExportGlyphs", [])

if kwargs["notdefGlyph"] is None:
kwargs["notdefGlyph"] = _getDefaultNotdefGlyph(designSpaceDoc, empty=True)
kwargs["notdefGlyph"] = _notdefGlyphFallback(designSpaceDoc)

kwargs["extraSubstitutions"] = defaultdict(set)
for rule in designSpaceDoc.rules:
Expand Down Expand Up @@ -479,7 +479,7 @@ def compileInterpolatableOTFsFromDS(designSpaceDoc, **kwargs):
kwargs["skipExportGlyphs"] = designSpaceDoc.lib.get("public.skipExportGlyphs", [])

if kwargs["notdefGlyph"] is None:
kwargs["notdefGlyph"] = _getDefaultNotdefGlyph(designSpaceDoc)
kwargs["notdefGlyph"] = _notdefGlyphFallback(designSpaceDoc)

kwargs["extraSubstitutions"] = defaultdict(set)
for rule in designSpaceDoc.rules:
Expand Down
28 changes: 16 additions & 12 deletions Lib/ufo2ft/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,17 @@ def getDefaultMasterFont(designSpaceDoc):
return defaultSource.font


def _getDefaultNotdefGlyph(designSpaceDoc, empty=False):
def _notdefGlyphFallback(designSpaceDoc):
"""Return an empty glyph to be used as .notdef for sparse layer masters.
Sparse layers usually do not contain a .notdef glyph, however in order to
compile valid TTFs to be used as master in varLib.build, a .notdef at index 0 is
required. We can't use the auto-generated .notdef glyph because it may be
incompatible with the one already present in the other masters. So we make
an empty glyph which will be ignored when building gvar or HVAR.
If the default master does not contain a .notdef either, return None since
the auto-generated .notdef can be used.
"""
from ufo2ft.errors import InvalidDesignSpaceData

try:
Expand All @@ -489,17 +499,11 @@ def _getDefaultNotdefGlyph(designSpaceDoc, empty=False):
except KeyError:
notdefGlyph = None
else:
if empty:
# create a new empty .notdef glyph with the same width/height
# as the default master's .notdef glyph to be use for sparse layer
# master TTFs, so that it won't participate in gvar interpolation
# TODO(anthrotype): Use sentinel values for width/height to
# mark the glyph as non-participating for HVAR if/when fonttools
# supports that, https://github.com/googlefonts/ufo2ft/issues/501
emptyGlyph = _getNewGlyphFactory(notdefGlyph)(".notdef")
emptyGlyph.width = notdefGlyph.width
emptyGlyph.height = notdefGlyph.height
notdefGlyph = emptyGlyph
notdefGlyph = _getNewGlyphFactory(notdefGlyph)(".notdef")
# sentinel value for varLib that means this advance does not participate
# https://github.com/fonttools/fonttools/pull/3235
notdefGlyph.width = 0xFFFF
notdefGlyph.height = 0xFFFF
return notdefGlyph


Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fonttools[lxml,ufo]==4.40.0
fonttools[lxml,ufo]==4.42.0
defcon==0.10.2
compreffor==0.5.3
booleanOperations==0.9.0
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
setup_requires=pytest_runner + wheel + ["setuptools_scm"],
tests_require=["pytest>=2.8"],
install_requires=[
"fonttools[ufo]>=4.40.0",
"fonttools[ufo]>=4.42.0",
"cffsubr>=0.2.8",
"booleanOperations>=0.9.0",
],
Expand Down
8 changes: 4 additions & 4 deletions tests/data/TestVariableFont-CFF2-cffsubr.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -471,20 +471,20 @@
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="1">
<VarRegionAxis index="0">
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="2">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
Expand Down
8 changes: 4 additions & 4 deletions tests/data/TestVariableFont-CFF2-post3.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -448,20 +448,20 @@
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="1">
<VarRegionAxis index="0">
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="2">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
Expand Down
182 changes: 182 additions & 0 deletions tests/data/TestVariableFont-CFF2-sparse-notdefGlyph.ttx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont>

<CFF2>
<major value="2"/>
<minor value="0"/>
<CFFFont name="CFF2Font">
<FontMatrix value="0.001 0 0 0.001 0 0"/>
<FDArray>
<FontDict index="0">
<Private>
<BlueScale value="0.039625"/>
<BlueShift value="7"/>
<BlueFuzz value="1"/>
<LanguageGroup value="0"/>
<ExpansionFactor value="0.06"/>
</Private>
</FontDict>
</FDArray>
<CharStrings>
<CharString name=".notdef">
50 -250 rmoveto
400 1000 -400 hlineto
50 -950 rmoveto
900 300 -900 vlineto
100 500 1 blend
200 rmoveto
278 -112 222 -138 -138 -112 -222 -278 277 -112 223 -138 -138 -112 -223 -277 8 blend
vhcurveto
</CharString>
<CharString name="a">
468 -1 rmoveto
-21 435 -233 70 -205 -76 27 -91 -56 1 blend
172 60 155 -40 -59 2 2 blend
3 -360 56 1 blend
rlineto
12 266 59 -2 2 blend
rmoveto
-352 -23 3 -218 139 -34 221 83 -6 63 -222 -60 -75 52 15 40 13 37 -21 5 blend
2 46 294 35 -78 -30 2 blend
rlineto
</CharString>
<CharString name="dotabovecomb">
-21 597 -8 28 2 blend
rmoveto
-16 -94 78 -2 9 88 -19 -48 44 7 -4 29 6 blend
rlineto
</CharString>
<CharString name="e">
1 vsindex
127 228 -1 70 -25 1 2 blend
rmoveto
449 -2 1 -45 -2 -2 2 blend
-5 79 -255 208 -276 -252 148 -279 338 63 -17 84 -280 -54 -82 188 170 153 163 -124 -355 6 27 0 0 -27 0 36 0 -29 0 -34 0 31 0 -1 0 2 0 -45 -2 13 28 100 37 0 13 0 -2 55 -40 -54 -32 -86 -30 -57 -85 -60 34 57 84 146 -5 0 21 blend
rlineto
</CharString>
<CharString name="edotabove">
127 228 70 1 2 blend
rmoveto
449 -2 -45 -2 2 blend
-5 79 -255 208 -276 -252 148 -279 338 63 -17 84 -27 36 -29 -34 31 -1 2 -45 13 100 10 blend
-280 -54 -82 188 170 153 163 -124 -355 55 -54 -86 -57 -60 57 146 7 blend
6 rlineto
167 395 -84 118 2 blend
rmoveto
-16 -94 78 -2 9 88 -19 -48 44 7 -4 29 6 blend
rlineto
</CharString>
<CharString name="s">
559 459 rmoveto
-235 71 -286 -187 389 -188 -145 -79 -229 98 -28 -91 279 -96 278 187 -369 192 113 76 -22 55 -58 -61 19 49 34 9 9 -56 -2 -41 46 12 29 24 -57 -31 18 blend
213 -66 rlineto
</CharString>
</CharStrings>
<VarStore Format="1">
<Format value="1"/>
<VarRegionList>
<!-- RegionAxisCount=1 -->
<!-- RegionCount=3 -->
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="1">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="2">
<VarRegionAxis index="0">
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
</VarRegionList>
<!-- VarDataCount=2 -->
<VarData index="0">
<!-- ItemCount=0 -->
<NumShorts value="0"/>
<!-- VarRegionCount=1 -->
<VarRegionIndex index="0" value="0"/>
</VarData>
<VarData index="1">
<!-- ItemCount=0 -->
<NumShorts value="0"/>
<!-- VarRegionCount=2 -->
<VarRegionIndex index="0" value="1"/>
<VarRegionIndex index="1" value="2"/>
</VarData>
</VarStore>
</CFFFont>

<GlobalSubrs>
<!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
</GlobalSubrs>
</CFF2>

<hmtx>
<mtx name=".notdef" width="500" lsb="0"/>
<mtx name="a" width="600" lsb="9"/>
<mtx name="dotabovecomb" width="0" lsb="-37"/>
<mtx name="e" width="600" lsb="40"/>
<mtx name="edotabove" width="600" lsb="40"/>
<mtx name="s" width="600" lsb="25"/>
</hmtx>

<HVAR>
<Version value="0x00010000"/>
<VarStore Format="1">
<Format value="1"/>
<VarRegionList>
<!-- RegionAxisCount=1 -->
<!-- RegionCount=3 -->
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="1">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="2">
<VarRegionAxis index="0">
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
</VarRegionList>
<!-- VarDataCount=1 -->
<VarData index="0">
<!-- ItemCount=2 -->
<NumShorts value="1"/>
<!-- VarRegionCount=1 -->
<VarRegionIndex index="0" value="0"/>
<Item index="0" value="[0]"/>
<Item index="1" value="[500]"/>
</VarData>
</VarStore>
<AdvWidthMap>
<Map glyph=".notdef" outer="0" inner="1"/>
<Map glyph="a" outer="0" inner="0"/>
<Map glyph="dotabovecomb" outer="0" inner="0"/>
<Map glyph="e" outer="0" inner="0"/>
<Map glyph="edotabove" outer="0" inner="0"/>
<Map glyph="s" outer="0" inner="0"/>
</AdvWidthMap>
</HVAR>

</ttFont>
8 changes: 4 additions & 4 deletions tests/data/TestVariableFont-CFF2-useProductionNames.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -465,20 +465,20 @@
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="1">
<VarRegionAxis index="0">
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="2">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
Expand Down
8 changes: 4 additions & 4 deletions tests/data/TestVariableFont-CFF2.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -462,20 +462,20 @@
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="1">
<VarRegionAxis index="0">
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="2">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
Expand Down
8 changes: 4 additions & 4 deletions tests/data/TestVariableFont-TTF-post3.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -451,20 +451,20 @@
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="1">
<VarRegionAxis index="0">
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<StartCoord value="0.0"/>
<PeakCoord value="0.36365"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
<Region index="2">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<StartCoord value="0.36365"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
Expand Down
Loading

0 comments on commit d1c5ad4

Please sign in to comment.