Skip to content

Commit

Permalink
OutlineOTFCompiler: Guard against missing defaultWidthX or nominalWid…
Browse files Browse the repository at this point in the history
…thX (#358)

In case a UFO sets just one of the two.
  • Loading branch information
madig authored Dec 4, 2019
1 parent 83aacfe commit 12354b3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
12 changes: 8 additions & 4 deletions Lib/ufo2ft/outlineCompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,8 +948,8 @@ def getDefaultAndNominalWidths(self):
if self._defaultAndNominalWidths is None:
info = self.ufo.info
# populate the width values
if not any(
getattr(info, attr, None) is not None
if all(
getattr(info, attr, None) is None
for attr in ("postscriptDefaultWidthX", "postscriptNominalWidthX")
):
# no custom values set in fontinfo.plist; compute optimal ones
Expand All @@ -958,8 +958,12 @@ def getDefaultAndNominalWidths(self):
widths = [otRound(glyph.width) for glyph in self.allGlyphs.values()]
defaultWidthX, nominalWidthX = optimizeWidths(widths)
else:
defaultWidthX = otRound(info.postscriptDefaultWidthX)
nominalWidthX = otRound(info.postscriptNominalWidthX)
defaultWidthX = otRound(
getAttrWithFallback(info, "postscriptDefaultWidthX")
)
nominalWidthX = otRound(
getAttrWithFallback(info, "postscriptNominalWidthX")
)
self._defaultAndNominalWidths = (defaultWidthX, nominalWidthX)
return self._defaultAndNominalWidths

Expand Down
25 changes: 25 additions & 0 deletions tests/outlineCompiler_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,31 @@ def test_optimized_default_and_nominal_widths(self, FontClass):
# 250 - nominalWidthX
assert charStrings.getItemAndSelector("space")[0].program == [-53, "endchar"]

def test_optimized_default_but_no_nominal_widths(self, FontClass):
ufo = FontClass()
ufo.info.familyName = "Test"
ufo.info.styleName = "R"
ufo.info.ascender = 1
ufo.info.descender = 1
ufo.info.capHeight = 1
ufo.info.xHeight = 1
ufo.info.unitsPerEm = 1000
ufo.info.postscriptDefaultWidthX = 500
for glyphName, width in (
(".notdef", 500),
("space", 500),
("a", 500),
):
glyph = ufo.newGlyph(glyphName)
glyph.width = width

font = compileOTF(ufo)
cff = font["CFF "].cff
private = cff[list(cff.keys())[0]].Private

assert private.defaultWidthX == 500
assert private.nominalWidthX == 0


class GlyphOrderTest(object):
def test_compile_original_glyph_order(self, testufo):
Expand Down

1 comment on commit 12354b3

@adrientetar
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two should really be provided together, as I did here. The same goes for vertical metrics, you don't want to have some ascender metric set by the designer and the rest calculated by a fallback, because they could be totally different things (or at least warn about it), so I just return them all in one go.

Please sign in to comment.