diff --git a/Lib/ufo2ft/__init__.py b/Lib/ufo2ft/__init__.py
index 6825465a7..fb17a5db8 100644
--- a/Lib/ufo2ft/__init__.py
+++ b/Lib/ufo2ft/__init__.py
@@ -1,5 +1,6 @@
import logging
from enum import IntEnum
+from typing import Any, Optional
from fontTools import varLib
@@ -53,6 +54,7 @@ def compileOTF(
cffVersion=1,
subroutinizer=None,
notdefGlyph=None,
+ postProcessorClass: Optional[Any] = PostProcessor,
_tables=None,
):
"""Create FontTools CFF font from a UFO.
@@ -153,13 +155,14 @@ def compileOTF(
debugFeatureFile=debugFeatureFile,
)
- postProcessor = PostProcessor(otf, ufo, glyphSet=glyphSet)
- otf = postProcessor.process(
- useProductionNames,
- optimizeCFF=optimizeCFF >= CFFOptimization.SUBROUTINIZE,
- subroutinizer=subroutinizer,
- cffVersion=cffVersion,
- )
+ if postProcessorClass is not None:
+ postProcessor = postProcessorClass(otf, ufo, glyphSet=glyphSet)
+ otf = postProcessor.process(
+ useProductionNames,
+ optimizeCFF=optimizeCFF >= CFFOptimization.SUBROUTINIZE,
+ subroutinizer=subroutinizer,
+ cffVersion=cffVersion,
+ )
return otf
@@ -185,6 +188,7 @@ def compileTTF(
skipExportGlyphs=None,
debugFeatureFile=None,
notdefGlyph=None,
+ postProcessorClass: Optional[Any] = PostProcessor,
):
"""Create FontTools TrueType font from a UFO.
@@ -244,8 +248,9 @@ def compileTTF(
debugFeatureFile=debugFeatureFile,
)
- postProcessor = PostProcessor(otf, ufo, glyphSet=glyphSet)
- otf = postProcessor.process(useProductionNames)
+ if postProcessorClass is not None:
+ postProcessor = postProcessorClass(otf, ufo, glyphSet=glyphSet)
+ otf = postProcessor.process(useProductionNames)
return otf
@@ -267,6 +272,7 @@ def compileInterpolatableTTFs(
skipExportGlyphs=None,
debugFeatureFile=None,
notdefGlyph=None,
+ postProcessorClass: Optional[Any] = PostProcessor,
):
"""Create FontTools TrueType fonts from a list of UFOs with interpolatable
outlines. Cubic curves are converted compatibly to quadratic curves using
@@ -343,8 +349,9 @@ def compileInterpolatableTTFs(
debugFeatureFile=debugFeatureFile,
)
- postProcessor = PostProcessor(ttf, ufo, glyphSet=glyphSet)
- ttf = postProcessor.process(useProductionNames)
+ if postProcessorClass is not None:
+ postProcessor = postProcessorClass(ttf, ufo, glyphSet=glyphSet)
+ ttf = postProcessor.process(useProductionNames)
if layerName is not None:
# for sparse masters (i.e. containing only a subset of the glyphs), we
@@ -375,6 +382,7 @@ def compileInterpolatableTTFsFromDS(
inplace=False,
debugFeatureFile=None,
notdefGlyph=None,
+ postProcessorClass: Optional[Any] = PostProcessor,
):
"""Create FontTools TrueType fonts from the DesignSpaceDocument UFO sources
with interpolatable outlines. Cubic curves are converted compatibly to
@@ -433,6 +441,7 @@ def compileInterpolatableTTFsFromDS(
skipExportGlyphs=skipExportGlyphs,
debugFeatureFile=debugFeatureFile,
notdefGlyph=notdefGlyph,
+ postProcessorClass=postProcessorClass,
)
if inplace:
@@ -458,6 +467,7 @@ def compileInterpolatableOTFsFromDS(
inplace=False,
debugFeatureFile=None,
notdefGlyph=None,
+ postProcessorClass: Optional[Any] = PostProcessor,
):
"""Create FontTools CFF fonts from the DesignSpaceDocument UFO sources
with interpolatable outlines.
@@ -519,6 +529,7 @@ def compileInterpolatableOTFsFromDS(
debugFeatureFile=debugFeatureFile,
notdefGlyph=notdefGlyph,
_tables=SPARSE_OTF_MASTER_TABLES if source.layerName else None,
+ postProcessorClass=postProcessorClass,
)
)
@@ -596,6 +607,7 @@ def compileVariableTTF(
inplace=False,
debugFeatureFile=None,
notdefGlyph=None,
+ postProcessorClass: Optional[Any] = PostProcessor,
):
"""Create FontTools TrueType variable font from the DesignSpaceDocument UFO sources
with interpolatable outlines, using fontTools.varLib.build.
@@ -627,6 +639,8 @@ def compileVariableTTF(
inplace=inplace,
debugFeatureFile=debugFeatureFile,
notdefGlyph=notdefGlyph,
+ # No need to post-process intermediate fonts.
+ postProcessorClass=None,
)
logger.info("Building variable TTF font")
@@ -635,8 +649,9 @@ def compileVariableTTF(
ttfDesignSpace, exclude=excludeVariationTables, optimize=optimizeGvar
)[0]
- postProcessor = PostProcessor(varfont, baseUfo)
- varfont = postProcessor.process(useProductionNames)
+ if postProcessorClass is not None:
+ postProcessor = postProcessorClass(varfont, baseUfo)
+ varfont = postProcessor.process(useProductionNames)
return varfont
@@ -656,6 +671,7 @@ def compileVariableCFF2(
debugFeatureFile=None,
optimizeCFF=CFFOptimization.SPECIALIZE,
notdefGlyph=None,
+ postProcessorClass: Optional[Any] = PostProcessor,
):
"""Create FontTools CFF2 variable font from the DesignSpaceDocument UFO sources
with interpolatable outlines, using fontTools.varLib.build.
@@ -690,6 +706,8 @@ def compileVariableCFF2(
inplace=inplace,
debugFeatureFile=debugFeatureFile,
notdefGlyph=notdefGlyph,
+ # No need to post-process intermediate fonts.
+ postProcessorClass=None,
)
logger.info("Building variable CFF2 font")
@@ -704,10 +722,11 @@ def compileVariableCFF2(
optimize=optimizeCFF >= CFFOptimization.SPECIALIZE,
)[0]
- postProcessor = PostProcessor(varfont, baseUfo)
- varfont = postProcessor.process(
- useProductionNames,
- optimizeCFF=optimizeCFF >= CFFOptimization.SUBROUTINIZE,
- )
+ if postProcessorClass is not None:
+ postProcessor = postProcessorClass(varfont, baseUfo)
+ varfont = postProcessor.process(
+ useProductionNames,
+ optimizeCFF=optimizeCFF >= CFFOptimization.SUBROUTINIZE,
+ )
return varfont
diff --git a/Lib/ufo2ft/outlineCompiler.py b/Lib/ufo2ft/outlineCompiler.py
index c0054ff92..b1877503e 100644
--- a/Lib/ufo2ft/outlineCompiler.py
+++ b/Lib/ufo2ft/outlineCompiler.py
@@ -537,7 +537,7 @@ def setupTable_OS2(self):
# subscript, superscript, strikeout values, taken from AFDKO:
# FDK/Tools/Programs/makeotf/makeotf_lib/source/hotconv/hot.c
unitsPerEm = getAttrWithFallback(font.info, "unitsPerEm")
- italicAngle = getAttrWithFallback(font.info, "italicAngle")
+ italicAngle = float(getAttrWithFallback(font.info, "italicAngle"))
xHeight = getAttrWithFallback(font.info, "xHeight")
def adjustOffset(offset, angle):
@@ -889,7 +889,7 @@ def setupTable_post(self):
font = self.ufo
post.formatType = 3.0
# italic angle
- italicAngle = getAttrWithFallback(font.info, "italicAngle")
+ italicAngle = float(getAttrWithFallback(font.info, "italicAngle"))
post.italicAngle = italicAngle
# underline
underlinePosition = getAttrWithFallback(
@@ -900,7 +900,9 @@ def setupTable_post(self):
font.info, "postscriptUnderlineThickness"
)
post.underlineThickness = otRound(underlineThickness)
- post.isFixedPitch = getAttrWithFallback(font.info, "postscriptIsFixedPitch")
+ post.isFixedPitch = int(
+ getAttrWithFallback(font.info, "postscriptIsFixedPitch")
+ )
# misc
post.minMemType42 = 0
post.maxMemType42 = 0
@@ -1140,6 +1142,9 @@ def setupTable_CFF(self):
self.otf["CFF "] = cff = newTable("CFF ")
cff = cff.cff
+ # NOTE: Set up a back-reference to be used by some CFFFontSet methods
+ # down the line (as of fontTools 4.21.1).
+ cff.otFont = self.otf
# set up the basics
cff.major = 1
cff.minor = 0
@@ -1215,8 +1220,8 @@ def setupTable_CFF(self):
)
topDict.Weight = getAttrWithFallback(info, "postscriptWeightName")
# populate various numbers
- topDict.isFixedPitch = getAttrWithFallback(info, "postscriptIsFixedPitch")
- topDict.ItalicAngle = getAttrWithFallback(info, "italicAngle")
+ topDict.isFixedPitch = int(getAttrWithFallback(info, "postscriptIsFixedPitch"))
+ topDict.ItalicAngle = float(getAttrWithFallback(info, "italicAngle"))
underlinePosition = getAttrWithFallback(info, "postscriptUnderlinePosition")
topDict.UnderlinePosition = otRound(underlinePosition)
underlineThickness = getAttrWithFallback(info, "postscriptUnderlineThickness")
diff --git a/Lib/ufo2ft/postProcessor.py b/Lib/ufo2ft/postProcessor.py
index 02d2d323c..2f8c1a797 100644
--- a/Lib/ufo2ft/postProcessor.py
+++ b/Lib/ufo2ft/postProcessor.py
@@ -40,10 +40,15 @@ class SubroutinizerBackend(enum.Enum):
def __init__(self, otf, ufo, glyphSet=None):
self.ufo = ufo
self.glyphSet = glyphSet if glyphSet is not None else ufo
- stream = BytesIO()
- otf.save(stream)
- stream.seek(0)
- self.otf = TTFont(stream)
+
+ # FIXME: Stop reloading all incoming fonts here. It ensures that 1) we
+ # get the final binary layout, which canonicalizes data for us and 2)
+ # can easily rename glyphs later. The former point should be fixed, as
+ # reloading is expensive and it is within reason for the compiler to
+ # spit out something that can be used without reloading.
+ # https://github.com/googlefonts/ufo2ft/issues/485
+ self.otf = _reloadFont(otf)
+
self._postscriptNames = ufo.lib.get("public.postscriptNames")
def process(
@@ -379,3 +384,11 @@ def _stripCharStringWidth(program):
if stack:
result.extend(stack)
return result
+
+
+def _reloadFont(font: TTFont) -> TTFont:
+ """Recompile a font to arrive at the final internal layout."""
+ stream = BytesIO()
+ font.save(stream)
+ stream.seek(0)
+ return TTFont(stream)
diff --git a/requirements.txt b/requirements.txt
index 0b4859587..cb3f750bd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-fonttools[lxml,ufo]==4.21.1
+fonttools[lxml,ufo]==4.22.0
defcon==0.8.1
cu2qu==1.6.7
compreffor==0.5.1
diff --git a/setup.py b/setup.py
index 551fe4cab..4d34f5959 100644
--- a/setup.py
+++ b/setup.py
@@ -29,7 +29,7 @@
setup_requires=pytest_runner + wheel + ["setuptools_scm"],
tests_require=["pytest>=2.8"],
install_requires=[
- "fonttools[ufo]>=4.21.1",
+ "fonttools[ufo]>=4.22.0",
"cu2qu>=1.6.7",
"cffsubr>=0.2.8",
"booleanOperations>=0.9.0",
diff --git a/tests/data/Bug108.ttx b/tests/data/Bug108.ttx
index 90d792fba..48adca775 100644
--- a/tests/data/Bug108.ttx
+++ b/tests/data/Bug108.ttx
@@ -34,7 +34,7 @@
-
+
diff --git a/tests/data/MTIFeatures.ttx b/tests/data/MTIFeatures.ttx
index 1f146e42c..c0f57e6c8 100644
--- a/tests/data/MTIFeatures.ttx
+++ b/tests/data/MTIFeatures.ttx
@@ -33,7 +33,7 @@
-
+
diff --git a/tests/data/TestFont-CFF-compreffor.ttx b/tests/data/TestFont-CFF-compreffor.ttx
index a5462adb9..9877c3e17 100644
--- a/tests/data/TestFont-CFF-compreffor.ttx
+++ b/tests/data/TestFont-CFF-compreffor.ttx
@@ -420,7 +420,7 @@
-
+
diff --git a/tests/data/TestFont-CFF.ttx b/tests/data/TestFont-CFF.ttx
index 167e7a658..0a916f689 100644
--- a/tests/data/TestFont-CFF.ttx
+++ b/tests/data/TestFont-CFF.ttx
@@ -436,7 +436,7 @@
-
+
diff --git a/tests/data/TestFont-CFF2-cffsubr.ttx b/tests/data/TestFont-CFF2-cffsubr.ttx
index 3e4bc7af6..687b56390 100644
--- a/tests/data/TestFont-CFF2-cffsubr.ttx
+++ b/tests/data/TestFont-CFF2-cffsubr.ttx
@@ -291,6 +291,8 @@
+
+
@@ -440,7 +442,7 @@
-
+
diff --git a/tests/data/TestFont-CFF2-compreffor.ttx b/tests/data/TestFont-CFF2-compreffor.ttx
index 0e099dc3a..f8b7b60b9 100644
--- a/tests/data/TestFont-CFF2-compreffor.ttx
+++ b/tests/data/TestFont-CFF2-compreffor.ttx
@@ -294,6 +294,8 @@
+
+
@@ -433,7 +435,7 @@
-
+
diff --git a/tests/data/TestFont-CFF2-post3.ttx b/tests/data/TestFont-CFF2-post3.ttx
index 0f8e767d2..5975f6a4f 100644
--- a/tests/data/TestFont-CFF2-post3.ttx
+++ b/tests/data/TestFont-CFF2-post3.ttx
@@ -266,6 +266,8 @@
+
+
@@ -415,7 +417,7 @@
-
+
diff --git a/tests/data/TestFont-NoOptimize-CFF.ttx b/tests/data/TestFont-NoOptimize-CFF.ttx
index 780064bba..144327bb5 100644
--- a/tests/data/TestFont-NoOptimize-CFF.ttx
+++ b/tests/data/TestFont-NoOptimize-CFF.ttx
@@ -439,7 +439,7 @@
-
+
diff --git a/tests/data/TestFont-NoOptimize-CFF2.ttx b/tests/data/TestFont-NoOptimize-CFF2.ttx
index 8540b8ec3..76b856f73 100644
--- a/tests/data/TestFont-NoOptimize-CFF2.ttx
+++ b/tests/data/TestFont-NoOptimize-CFF2.ttx
@@ -294,6 +294,8 @@
+
+
@@ -449,7 +451,7 @@
-
+
diff --git a/tests/data/TestFont-NoOverlaps-CFF-pathops.ttx b/tests/data/TestFont-NoOverlaps-CFF-pathops.ttx
index 35d0b2219..8801b2f7d 100644
--- a/tests/data/TestFont-NoOverlaps-CFF-pathops.ttx
+++ b/tests/data/TestFont-NoOverlaps-CFF-pathops.ttx
@@ -431,7 +431,7 @@
-
+
diff --git a/tests/data/TestFont-NoOverlaps-CFF.ttx b/tests/data/TestFont-NoOverlaps-CFF.ttx
index 3c3015eca..5ebd04720 100644
--- a/tests/data/TestFont-NoOverlaps-CFF.ttx
+++ b/tests/data/TestFont-NoOverlaps-CFF.ttx
@@ -428,7 +428,7 @@
-
+
diff --git a/tests/data/TestFont-NoOverlaps-TTF-pathops.ttx b/tests/data/TestFont-NoOverlaps-TTF-pathops.ttx
index 9dbe2b8f9..7e912b231 100644
--- a/tests/data/TestFont-NoOverlaps-TTF-pathops.ttx
+++ b/tests/data/TestFont-NoOverlaps-TTF-pathops.ttx
@@ -515,7 +515,7 @@
-
+
diff --git a/tests/data/TestFont-NoOverlaps-TTF.ttx b/tests/data/TestFont-NoOverlaps-TTF.ttx
index f66fd0a15..9632608bf 100644
--- a/tests/data/TestFont-NoOverlaps-TTF.ttx
+++ b/tests/data/TestFont-NoOverlaps-TTF.ttx
@@ -515,7 +515,7 @@
-
+
diff --git a/tests/data/TestFont-Specialized-CFF.ttx b/tests/data/TestFont-Specialized-CFF.ttx
index 114adffdd..ab7c8219d 100644
--- a/tests/data/TestFont-Specialized-CFF.ttx
+++ b/tests/data/TestFont-Specialized-CFF.ttx
@@ -417,7 +417,7 @@
-
+
diff --git a/tests/data/TestFont-Specialized-CFF2.ttx b/tests/data/TestFont-Specialized-CFF2.ttx
index abfc01de2..344702e87 100644
--- a/tests/data/TestFont-Specialized-CFF2.ttx
+++ b/tests/data/TestFont-Specialized-CFF2.ttx
@@ -294,6 +294,8 @@
+
+
@@ -427,7 +429,7 @@
-
+
diff --git a/tests/data/TestFont-TTF-post3.ttx b/tests/data/TestFont-TTF-post3.ttx
index 32e4f87f9..fbf4798a4 100644
--- a/tests/data/TestFont-TTF-post3.ttx
+++ b/tests/data/TestFont-TTF-post3.ttx
@@ -488,7 +488,7 @@
-
+
diff --git a/tests/data/TestFont.ttx b/tests/data/TestFont.ttx
index fb820cfd2..76dd3b8d6 100644
--- a/tests/data/TestFont.ttx
+++ b/tests/data/TestFont.ttx
@@ -513,7 +513,7 @@
-
+
diff --git a/tests/data/TestVariableFont-CFF2-cffsubr.ttx b/tests/data/TestVariableFont-CFF2-cffsubr.ttx
index d5ec5590f..b55692286 100644
--- a/tests/data/TestVariableFont-CFF2-cffsubr.ttx
+++ b/tests/data/TestVariableFont-CFF2-cffsubr.ttx
@@ -201,6 +201,8 @@
+
+
@@ -315,7 +317,7 @@
-
+
@@ -377,10 +379,10 @@
-
+
-
+
@@ -450,7 +452,7 @@
-
+
diff --git a/tests/data/TestVariableFont-CFF2-post3.ttx b/tests/data/TestVariableFont-CFF2-post3.ttx
index 5800e8694..f80c8a030 100644
--- a/tests/data/TestVariableFont-CFF2-post3.ttx
+++ b/tests/data/TestVariableFont-CFF2-post3.ttx
@@ -187,6 +187,8 @@
+
+
@@ -292,7 +294,7 @@
-
+
@@ -354,10 +356,10 @@
-
+
-
+
@@ -427,7 +429,7 @@
-
+
diff --git a/tests/data/TestVariableFont-CFF2-useProductionNames.ttx b/tests/data/TestVariableFont-CFF2-useProductionNames.ttx
index 3015fd004..e3d3b540f 100644
--- a/tests/data/TestVariableFont-CFF2-useProductionNames.ttx
+++ b/tests/data/TestVariableFont-CFF2-useProductionNames.ttx
@@ -204,6 +204,8 @@
+
+
@@ -309,7 +311,7 @@
-
+
@@ -371,10 +373,10 @@
-
+
-
+
@@ -444,7 +446,7 @@
-
+
diff --git a/tests/data/TestVariableFont-CFF2.ttx b/tests/data/TestVariableFont-CFF2.ttx
index 310c85a28..d82ba84f9 100644
--- a/tests/data/TestVariableFont-CFF2.ttx
+++ b/tests/data/TestVariableFont-CFF2.ttx
@@ -201,6 +201,8 @@
+
+
@@ -306,7 +308,7 @@
-
+
@@ -368,10 +370,10 @@
-
+
-
+
@@ -441,7 +443,7 @@
-
+
diff --git a/tests/data/TestVariableFont-TTF-post3.ttx b/tests/data/TestVariableFont-TTF-post3.ttx
index 86bb0e4bf..4f83e6bd1 100644
--- a/tests/data/TestVariableFont-TTF-post3.ttx
+++ b/tests/data/TestVariableFont-TTF-post3.ttx
@@ -297,7 +297,7 @@
-
+
@@ -359,10 +359,10 @@
-
+
-
+
@@ -432,7 +432,7 @@
-
+
diff --git a/tests/data/TestVariableFont-TTF-useProductionNames.ttx b/tests/data/TestVariableFont-TTF-useProductionNames.ttx
index c9e83dfe0..5adc73e7b 100644
--- a/tests/data/TestVariableFont-TTF-useProductionNames.ttx
+++ b/tests/data/TestVariableFont-TTF-useProductionNames.ttx
@@ -314,7 +314,7 @@
-
+
@@ -376,10 +376,10 @@
-
+
-
+
@@ -449,7 +449,7 @@
-
+
diff --git a/tests/data/TestVariableFont-TTF.ttx b/tests/data/TestVariableFont-TTF.ttx
index 80382c045..e6fab0507 100644
--- a/tests/data/TestVariableFont-TTF.ttx
+++ b/tests/data/TestVariableFont-TTF.ttx
@@ -311,7 +311,7 @@
-
+
@@ -373,10 +373,10 @@
-
+
-
+
@@ -446,7 +446,7 @@
-
+