diff --git a/Lib/ufo2ft/constants.py b/Lib/ufo2ft/constants.py
index 242800a..eec1a9d 100644
--- a/Lib/ufo2ft/constants.py
+++ b/Lib/ufo2ft/constants.py
@@ -38,6 +38,7 @@ COLR_CLIP_BOXES_KEY = UFO2FT_PREFIX + "colrClipBoxes"
 OBJECT_LIBS_KEY = "public.objectLibs"
 OPENTYPE_CATEGORIES_KEY = "public.openTypeCategories"
 OPENTYPE_META_KEY = "public.openTypeMeta"
+OPENTYPE_POST_UNDERLINE_POSITION_KEY = "public.openTypePostUnderlinePosition"
 TRUETYPE_INSTRUCTIONS_KEY = "public.truetype.instructions"
 TRUETYPE_METRICS_KEY = "public.truetype.useMyMetrics"
 TRUETYPE_OVERLAP_KEY = "public.truetype.overlap"
diff --git a/Lib/ufo2ft/outlineCompiler.py b/Lib/ufo2ft/outlineCompiler.py
index 72b8328..14b7bfe 100644
--- a/Lib/ufo2ft/outlineCompiler.py
+++ b/Lib/ufo2ft/outlineCompiler.py
@@ -31,6 +31,7 @@ from ufo2ft.constants import (
     COLOR_PALETTES_KEY,
     COLR_CLIP_BOXES_KEY,
     OPENTYPE_META_KEY,
+    OPENTYPE_POST_UNDERLINE_POSITION_KEY,
     UNICODE_VARIATION_SEQUENCES_KEY,
 )
 from ufo2ft.errors import InvalidFontData
@@ -928,9 +929,12 @@ class BaseOutlineCompiler:
         italicAngle = float(getAttrWithFallback(font.info, "italicAngle"))
         post.italicAngle = italicAngle
         # underline
-        underlinePosition = getAttrWithFallback(
-            font.info, "postscriptUnderlinePosition"
-        )
+        if OPENTYPE_POST_UNDERLINE_POSITION_KEY in font.lib:
+            underlinePosition = font.lib[OPENTYPE_POST_UNDERLINE_POSITION_KEY]
+        else:
+            underlinePosition = getAttrWithFallback(
+                font.info, "postscriptUnderlinePosition"
+            )
         post.underlinePosition = otRound(underlinePosition)
         underlineThickness = getAttrWithFallback(
             font.info, "postscriptUnderlineThickness"
@@ -1326,7 +1330,16 @@ class OutlineOTFCompiler(BaseOutlineCompiler):
         # populate various numbers
         topDict.isFixedPitch = int(getAttrWithFallback(info, "postscriptIsFixedPitch"))
         topDict.ItalicAngle = float(getAttrWithFallback(info, "italicAngle"))
-        underlinePosition = getAttrWithFallback(info, "postscriptUnderlinePosition")
+        if (
+            OPENTYPE_POST_UNDERLINE_POSITION_KEY in self.ufo.lib
+            and info.postscriptUnderlinePosition is None
+        ):
+            underlinePosition = (
+                self.ufo.lib[OPENTYPE_POST_UNDERLINE_POSITION_KEY]
+                - getAttrWithFallback(info, "postscriptUnderlineThickness") / 2
+            )
+        else:
+            underlinePosition = getAttrWithFallback(info, "postscriptUnderlinePosition")
         topDict.UnderlinePosition = otRound(underlinePosition)
         underlineThickness = getAttrWithFallback(info, "postscriptUnderlineThickness")
         topDict.UnderlineThickness = otRound(underlineThickness)

diff --git a/tests/fontInfoData_test.py b/tests/fontInfoData_test.py
index 5e8bdd2..d594e77 100644
--- a/tests/fontInfoData_test.py
+++ b/tests/fontInfoData_test.py
@@ -185,6 +185,12 @@ class GetAttrWithFallbackTest:
         assert getAttrWithFallback(info, "xHeight") == 1024
         assert getAttrWithFallback(info, "descender") == -410
 
+    def test_underline_position(self, info):
+        assert getAttrWithFallback(info, "postscriptUnderlinePosition") == -75
+
+        info.postscriptUnderlinePosition = -485
+        assert getAttrWithFallback(info, "postscriptUnderlinePosition") == -485
+
 
 class PostscriptBlueScaleFallbackTest:
     def test_without_blue_zones(self, info):
diff --git a/tests/outlineCompiler_test.py b/tests/outlineCompiler_test.py
index 2bbf025..86a02f8 100644
--- a/tests/outlineCompiler_test.py
+++ b/tests/outlineCompiler_test.py
@@ -17,6 +17,7 @@ from ufo2ft import (
 )
 from ufo2ft.constants import (
     GLYPHS_DONT_USE_PRODUCTION_NAMES,
+    OPENTYPE_POST_UNDERLINE_POSITION_KEY,
     SPARSE_OTF_MASTER_TABLES,
     SPARSE_TTF_MASTER_TABLES,
     USE_PRODUCTION_NAMES,
@@ -262,6 +263,19 @@ class OutlineTTFCompilerTest:
         actual = compiler.otf["name"].getName(1, 3, 1, 1033).string
         assert actual == "Custom Name for Windows"
 
+    def test_post_underline_without_public_key(self, testufo):
+        compiler = OutlineTTFCompiler(testufo)
+        compiler.compile()
+        actual = compiler.otf["post"].underlinePosition
+        assert actual == -200
+
+    def test_post_underline_with_public_key(self, testufo):
+        testufo.lib[OPENTYPE_POST_UNDERLINE_POSITION_KEY] = -485
+        compiler = OutlineTTFCompiler(testufo)
+        compiler.compile()
+        actual = compiler.otf["post"].underlinePosition
+        assert actual == -485
+
 
 class OutlineOTFCompilerTest:
     def test_setupTable_CFF_all_blues_defined(self, testufo):
@@ -596,6 +610,81 @@ class OutlineOTFCompilerTest:
         assert private.defaultWidthX == 500
         assert private.nominalWidthX == 0
 
+    def test_underline_without_public_key(self, testufo):
+        # Test with no lib key
+        compiler = OutlineOTFCompiler(testufo)
+        compiler.compile()
+
+        post = compiler.otf["post"].underlinePosition
+
+        cff = compiler.otf["CFF "].cff
+        cff_underline = cff[list(cff.keys())[0]].UnderlinePosition
+
+        assert post == -200
+        assert cff_underline == -200
+
+    def test_underline_with_public_key(self, testufo):
+        # Test with a lib key and postscriptUnderlinePosition
+        testufo.lib[OPENTYPE_POST_UNDERLINE_POSITION_KEY] = -485
+        testufo.info.postscriptUnderlinePosition = -42
+        compiler = OutlineOTFCompiler(testufo)
+        compiler.compile()
+
+        post = compiler.otf["post"].underlinePosition
+
+        cff = compiler.otf["CFF "].cff
+        cff_underline = cff[list(cff.keys())[0]].UnderlinePosition
+
+        assert post == -485
+        assert cff_underline == -42
+
+    def test_underline_with_public_key_and_no_psPosition(self, testufo):
+        # Test with a lib key and no postscriptUnderlinePosition
+        testufo.lib[OPENTYPE_POST_UNDERLINE_POSITION_KEY] = -485
+        testufo.info.postscriptUnderlinePosition = None
+        testufo.info.postscriptUnderlineThickness = 100
+        compiler = OutlineOTFCompiler(testufo)
+        compiler.compile()
+
+        post = compiler.otf["post"].underlinePosition
+
+        cff = compiler.otf["CFF "].cff
+        cff_underline = cff[list(cff.keys())[0]].UnderlinePosition
+
+        assert post == -485
+        assert cff_underline == -535
+
+    def test_underline_with_no_public_key_and_no_psPosition(self, testufo):
+        compiler = OutlineOTFCompiler(testufo)
+        compiler.compile()
+
+        post = compiler.otf["post"].underlinePosition
+
+        cff = compiler.otf["CFF "].cff
+        cff_underline = cff[list(cff.keys())[0]].UnderlinePosition
+
+        # Note: This is actually incorrect according to the post/cff
+        # spec, but it is how UFO3 has things defined, and is expected
+        # current behavior.
+        assert post == -200
+        assert cff_underline == -200
+
+    def test_underline_ps_rounding(self, testufo):
+        # Test rounding
+        testufo.lib[OPENTYPE_POST_UNDERLINE_POSITION_KEY] = -485
+        testufo.info.postscriptUnderlinePosition = None
+        testufo.info.postscriptUnderlineThickness = 43
+        compiler = OutlineOTFCompiler(testufo)
+        compiler.compile()
+
+        post = compiler.otf["post"].underlinePosition
+
+        cff = compiler.otf["CFF "].cff
+        cff_underline = cff[list(cff.keys())[0]].UnderlinePosition
+
+        assert post == -485
+        assert cff_underline == -506
+
 
 class GlyphOrderTest:
     def test_compile_original_glyph_order(self, testufo):

post table underlinePosition
The `postscriptUnderlinePosition` wasn't well specified in the UFO: it conflated the value for `CFF/Type1` and `post/CFF2`, where those values are actually different: `post/CFF2` value is the top of the underline, `CFF/Type1` is the middle of the underline.

The UFO spec got clarified to be clear that `postscriptUnerlinePosition` is `CFF/Type1' (https://github.com/unified-font-object/ufo-spec/issues/217).

The behavior for calculation from above is what the AFDKO has been doing, just need to update ufo2ft to follow suit.

I will PR a change (and tests) soon.
tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[defcon-infoDict0-expected0] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[defcon-infoDict1-expected1] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[defcon-infoDict2-expected2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[defcon-infoDict3-expected3] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[defcon-infoDict4-expected4] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[defcon-infoDict5-expected5] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_redundant_metadata[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_unecessary_metadata[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_vertical_metrics[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_caret_slope[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_head_created[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_empty_info[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_empty_info_2048[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_underline_position[defcon] tests/fontInfoData_test.py::PostscriptBlueScaleFallbackTest::test_without_blue_zones[defcon] tests/fontInfoData_test.py::PostscriptBlueScaleFallbackTest::test_with_blue_zones[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_with_gasp[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_without_gasp[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_empty_gasp[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_makeGlyphsBoundingBoxes[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_getMaxComponentDepths[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics_False[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics_None[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_importTTX[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_no_contour_glyphs[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_os2_no_widths[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_missing_component[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_contour_starts_with_offcurve_point[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_meta[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_name[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_post_underline_without_public_key[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_post_underline_with_public_key[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_all_blues_defined[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_blues_defined[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_some_blues_defined[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_all[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_none[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_some[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_optimize[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_optimize[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes_floats[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_importTTX[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_no_contour_glyphs[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_and_nominal_widths[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_but_no_nominal_widths[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_without_public_key[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_with_public_key[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_with_public_key_and_no_psPosition[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_with_no_public_key_and_no_psPosition[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_ps_rounding[defcon] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_original_glyph_order[defcon] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_tweaked_glyph_order[defcon] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_strange_glyph_order[defcon] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[defcon-useProductionNames] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[defcon-Don't tests/outlineCompiler_test.py::NamesTest::test_compile_with_production_names[defcon] tests/outlineCompiler_test.py::NamesTest::test_postprocess_production_names_no_notdef[defcon] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[defcon-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[defcon-True] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[defcon-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[defcon-True] tests/outlineCompiler_test.py::NamesTest::test_warn_name_exceeds_max_length[defcon] tests/outlineCompiler_test.py::NamesTest::test_duplicate_glyph_names[defcon] tests/outlineCompiler_test.py::NamesTest::test_too_long_production_name[defcon] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal[defcon] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_raw[defcon] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_otf[defcon] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_interpolatable_ttf[defcon] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-1-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-1-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-1-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-1-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-32-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-32-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-32-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-32-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-100-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-100-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-100-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-True-100-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-False-None-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-False-None-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-False-None-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[defcon-False-None-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_strip_color_codepoints[defcon-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_strip_color_codepoints[defcon-compileOTF] tests/outlineCompiler_test.py::CmapTest::test_cmap_BMP[defcon] tests/outlineCompiler_test.py::CmapTest::test_cmap_nonBMP_with_UVS[defcon] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes0-expected0] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes1-expected1] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes2-expected2] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes3-expected3] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes4-expected4] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes5-expected5] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes6-expected6] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes7-expected7] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes8-expected8] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes9-expected9] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes10-expected10] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes11-expected11] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes12-expected12] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes13-expected13] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes14-expected14] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes15-expected15] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes16-expected16] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes17-expected17] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes18-expected18] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes19-expected19] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes20-expected20] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes21-expected21] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes22-expected22] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes23-expected23] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes24-expected24] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes25-expected25] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes26-expected26] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes27-expected27] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes28-expected28] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes29-expected29] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes30-expected30] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes31-expected31] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes32-expected32] tests/outlineCompiler_test.py::test_custom_layer_compilation[defcon] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable[defcon] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[defcon-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[defcon-inplace] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[defcon-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[defcon-inplace] tests/outlineCompiler_test.py::test_compilation_from_ds_missing_source_font[defcon] tests/outlineCompiler_test.py::test_compile_empty_ufo[defcon] tests/outlineCompiler_test.py::test_pass_on_conversion_error[defcon] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[ufoLib2-infoDict0-expected0] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[ufoLib2-infoDict1-expected1] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[ufoLib2-infoDict2-expected2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[ufoLib2-infoDict3-expected3] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[ufoLib2-infoDict4-expected4] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_family_and_style_names[ufoLib2-infoDict5-expected5] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_redundant_metadata[ufoLib2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_unecessary_metadata[ufoLib2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_vertical_metrics[ufoLib2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_caret_slope[ufoLib2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_head_created[ufoLib2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_empty_info[ufoLib2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_empty_info_2048[ufoLib2] tests/fontInfoData_test.py::GetAttrWithFallbackTest::test_underline_position[ufoLib2] tests/fontInfoData_test.py::PostscriptBlueScaleFallbackTest::test_without_blue_zones[ufoLib2] tests/fontInfoData_test.py::PostscriptBlueScaleFallbackTest::test_with_blue_zones[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_with_gasp[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_without_gasp[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_empty_gasp[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_makeGlyphsBoundingBoxes[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_getMaxComponentDepths[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics_False[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics_None[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_importTTX[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_no_contour_glyphs[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_os2_no_widths[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_missing_component[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_contour_starts_with_offcurve_point[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_meta[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_name[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_post_underline_without_public_key[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_post_underline_with_public_key[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_all_blues_defined[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_blues_defined[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_some_blues_defined[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_all[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_none[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_some[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_optimize[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_optimize[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes_floats[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_importTTX[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_no_contour_glyphs[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_and_nominal_widths[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_but_no_nominal_widths[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_without_public_key[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_with_public_key[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_with_public_key_and_no_psPosition[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_with_no_public_key_and_no_psPosition[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_underline_ps_rounding[ufoLib2] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_original_glyph_order[ufoLib2] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_tweaked_glyph_order[ufoLib2] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_strange_glyph_order[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[ufoLib2-useProductionNames] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[ufoLib2-Don't tests/outlineCompiler_test.py::NamesTest::test_compile_with_production_names[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_postprocess_production_names_no_notdef[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[ufoLib2-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[ufoLib2-True] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[ufoLib2-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[ufoLib2-True] tests/outlineCompiler_test.py::NamesTest::test_warn_name_exceeds_max_length[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_duplicate_glyph_names[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_too_long_production_name[ufoLib2] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal[ufoLib2] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_raw[ufoLib2] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_otf[ufoLib2] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_interpolatable_ttf[ufoLib2] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-1-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-1-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-1-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-1-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-32-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-32-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-32-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-32-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-100-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-100-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-100-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-True-100-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-False-None-True-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-False-None-True-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-False-None-False-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_colrv1_computeClipBoxes[ufoLib2-False-None-False-compileOTF] tests/outlineCompiler_test.py::ColrCpalTest::test_strip_color_codepoints[ufoLib2-compileTTF] tests/outlineCompiler_test.py::ColrCpalTest::test_strip_color_codepoints[ufoLib2-compileOTF] tests/outlineCompiler_test.py::CmapTest::test_cmap_BMP[ufoLib2] tests/outlineCompiler_test.py::CmapTest::test_cmap_nonBMP_with_UVS[ufoLib2] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes0-expected0] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes1-expected1] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes2-expected2] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes3-expected3] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes4-expected4] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes5-expected5] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes6-expected6] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes7-expected7] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes8-expected8] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes9-expected9] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes10-expected10] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes11-expected11] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes12-expected12] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes13-expected13] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes14-expected14] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes15-expected15] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes16-expected16] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes17-expected17] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes18-expected18] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes19-expected19] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes20-expected20] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes21-expected21] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes22-expected22] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes23-expected23] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes24-expected24] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes25-expected25] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes26-expected26] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes27-expected27] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes28-expected28] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes29-expected29] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes30-expected30] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes31-expected31] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes32-expected32] tests/outlineCompiler_test.py::test_custom_layer_compilation[ufoLib2] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable[ufoLib2] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[ufoLib2-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[ufoLib2-inplace] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[ufoLib2-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[ufoLib2-inplace] tests/outlineCompiler_test.py::test_compilation_from_ds_missing_source_font[ufoLib2] tests/outlineCompiler_test.py::test_compile_empty_ufo[ufoLib2] tests/outlineCompiler_test.py::test_pass_on_conversion_error[ufoLib2] tests/fontInfoData_test.py::NormalizeStringForPostscriptTest::test_no_change tests/fontInfoData_test.py::DateStringToTimeValueTest::test_roundtrip_random_timestamp