def test_setupTable_gasp(self): compiler = OutlineTTFCompiler(self.ufo) compiler.otf = TTFont() compiler.setupTable_gasp() self.assertTrue('gasp' in compiler.otf) self.assertEqual(compiler.otf['gasp'].gaspRange, {7: 10, 65535: 15})
def test_importTTX(self): compiler = OutlineTTFCompiler(self.ufo) otf = compiler.otf = TTFont() compiler.importTTX() self.assertIn("CUST", otf) self.assertEqual(otf["CUST"].data, b"\x00\x01\xbe\xef") self.assertEqual(otf.sfntVersion, "\x00\x01\x00\x00")
def test_importTTX(self, testufo): compiler = OutlineTTFCompiler(testufo) otf = compiler.otf = TTFont() compiler.importTTX() assert "CUST" in otf assert otf["CUST"].data == b"\x00\x01\xbe\xef" assert otf.sfntVersion == "\x00\x01\x00\x00"
def test_compile_strange_glyph_order(self, testufo): """Move space and .notdef to end of glyph ids ufo2ft always puts .notdef first. """ NEW_ORDER = ["b", "a", "c", "d", "space", ".notdef"] EXPECTED_ORDER = [ ".notdef", "b", "a", "c", "d", "space", "e", "f", "g", "h", "i", "j", "k", "l", ] testufo.lib["public.glyphOrder"] = NEW_ORDER compiler = OutlineTTFCompiler(testufo) compiler.compile() assert compiler.otf.getGlyphOrder() == EXPECTED_ORDER
def test_autoUseMyMetrics_None(self): ufo = getTestUFO('UseMyMetrics') compiler = OutlineTTFCompiler(ufo) # setting 'autoUseMyMetrics' attribute to None disables the feature compiler.autoUseMyMetrics = None ttf = compiler.compile() self.assertFalse(ttf['glyf']['Iacute'].components[1].flags & USE_MY_METRICS)
def test_compile_original_glyph_order(self): DEFAULT_ORDER = [ '.notdef', 'space', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' ] compiler = OutlineTTFCompiler(self.ufo) compiler.compile() self.assertEqual(compiler.otf.getGlyphOrder(), DEFAULT_ORDER)
def test_compile_tweaked_glyph_order(self): NEW_ORDER = [ '.notdef', 'space', 'b', 'a', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' ] self.ufo.lib['public.glyphOrder'] = NEW_ORDER compiler = OutlineTTFCompiler(self.ufo) compiler.compile() self.assertEqual(compiler.otf.getGlyphOrder(), NEW_ORDER)
def test_no_contour_glyphs(self, testufo): for glyph in testufo: glyph.clearContours() compiler = OutlineTTFCompiler(testufo) compiler.compile() assert compiler.otf["hhea"].advanceWidthMax == 600 assert compiler.otf["hhea"].minLeftSideBearing == 0 assert compiler.otf["hhea"].minRightSideBearing == 0 assert compiler.otf["hhea"].xMaxExtent == 0
def test_no_contour_glyphs(self): for glyph in self.ufo: glyph.clearContours() compiler = OutlineTTFCompiler(self.ufo) compiler.compile() self.assertEqual(compiler.otf['hhea'].advanceWidthMax, 600) self.assertEqual(compiler.otf['hhea'].minLeftSideBearing, 0) self.assertEqual(compiler.otf['hhea'].minRightSideBearing, 0) self.assertEqual(compiler.otf['hhea'].xMaxExtent, 0)
def test_compile_strange_glyph_order(self): """Move space and .notdef to end of glyph ids ufo2ft always puts .notdef first. """ NEW_ORDER = ['b', 'a', 'c', 'd', 'space', '.notdef'] EXPECTED_ORDER = ['.notdef', 'b', 'a', 'c', 'd', 'space'] self.ufo.lib['public.glyphOrder'] = NEW_ORDER compiler = OutlineTTFCompiler(self.ufo) compiler.compile() self.assertEqual(compiler.otf.getGlyphOrder(), EXPECTED_ORDER)
def test_autoUseMyMetrics(self, use_my_metrics_ufo): compiler = OutlineTTFCompiler(use_my_metrics_ufo) ttf = compiler.compile() # the first component in the 'Iacute' composite glyph ('acute') # does _not_ have the USE_MY_METRICS flag assert not (ttf["glyf"]["Iacute"].components[0].flags & USE_MY_METRICS) # the second component in the 'Iacute' composite glyph ('I') # has the USE_MY_METRICS flag set assert ttf["glyf"]["Iacute"].components[1].flags & USE_MY_METRICS # none of the 'I' components of the 'romanthree' glyph has # the USE_MY_METRICS flag set, because the composite glyph has a # different width for component in ttf["glyf"]["romanthree"].components: assert not (component.flags & USE_MY_METRICS)
def test_makeGlyphsBoundingBoxes(self, quadufo): compiler = OutlineTTFCompiler(quadufo) assert compiler.glyphBoundingBoxes[".notdef"] == (50, 0, 450, 750) # no outline data assert compiler.glyphBoundingBoxes["space"] is None # float coordinates are rounded, so is the bbox assert compiler.glyphBoundingBoxes["d"] == (90, 77, 211, 197)
def test_autoUseMyMetrics(self): ufo = getTestUFO('UseMyMetrics') compiler = OutlineTTFCompiler(ufo) ttf = compiler.compile() # the first component in the 'Iacute' composite glyph ('acute') # does _not_ have the USE_MY_METRICS flag self.assertFalse(ttf['glyf']['Iacute'].components[0].flags & USE_MY_METRICS) # the second component in the 'Iacute' composite glyph ('I') # has the USE_MY_METRICS flag set self.assertTrue(ttf['glyf']['Iacute'].components[1].flags & USE_MY_METRICS) # none of the 'I' components of the 'romanthree' glyph has # the USE_MY_METRICS flag set, because the composite glyph has a # different width for component in ttf['glyf']['romanthree'].components: self.assertFalse(component.flags & USE_MY_METRICS)
def test_makeGlyphsBoundingBoxes(self, testufo): # the call to 'makeGlyphsBoundingBoxes' happen in the __init__ method compiler = OutlineTTFCompiler(testufo) assert compiler.glyphBoundingBoxes[".notdef"] == (50, 0, 450, 750) # no outline data assert compiler.glyphBoundingBoxes["space"] is None # float coordinates are rounded, so is the bbox assert compiler.glyphBoundingBoxes["d"] == (90, 77, 211, 197)
def test_makeGlyphsBoundingBoxes(self): # the call to 'makeGlyphsBoundingBoxes' happen in the __init__ method compiler = OutlineTTFCompiler(self.ufo) self.assertEqual(compiler.glyphBoundingBoxes['.notdef'], (50, 0, 450, 750)) # no outline data self.assertEqual(compiler.glyphBoundingBoxes['space'], None) # float coordinates are rounded, so is the bbox self.assertEqual(compiler.glyphBoundingBoxes['d'], (90, 77, 211, 197))
def test_autoUseMyMetrics(self): # make sure we get the same USE_MY_METRICS flags with both values of # 'convertCubics': https://github.com/googlei18n/ufo2ft/issues/136 ufo = getTestUFO('UseMyMetrics') for convertCubics in (False, True): compiler = OutlineTTFCompiler(ufo, convertCubics=convertCubics) ttf = compiler.compile() # the first component in the 'Iacute' composite glyph ('acute') # does _not_ have the USE_MY_METRICS flag self.assertFalse(ttf['glyf']['Iacute'].components[0].flags & USE_MY_METRICS) # the second component in the 'Iacute' composite glyph ('I') # has the USE_MY_METRICS flag set self.assertTrue(ttf['glyf']['Iacute'].components[1].flags & USE_MY_METRICS) # none of the 'I' components of the 'romanthree' glyph has # the USE_MY_METRICS flag set, because the composite glyph has a # different width for component in ttf['glyf']['romanthree'].components: self.assertFalse(component.flags & USE_MY_METRICS)
def test_compile_original_glyph_order(self, testufo): DEFAULT_ORDER = [ ".notdef", "space", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", ] compiler = OutlineTTFCompiler(testufo) compiler.compile() assert compiler.otf.getGlyphOrder() == DEFAULT_ORDER
def test_compile_tweaked_glyph_order(self, testufo): NEW_ORDER = [ ".notdef", "space", "b", "a", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", ] testufo.lib["public.glyphOrder"] = NEW_ORDER compiler = OutlineTTFCompiler(testufo) compiler.compile() assert compiler.otf.getGlyphOrder() == NEW_ORDER
def test_missing_component(self, emptyufo): ufo = emptyufo a = ufo.newGlyph("a") pen = a.getPen() pen.moveTo((0, 0)) pen.lineTo((100, 0)) pen.lineTo((100, 100)) pen.lineTo((0, 100)) pen.closePath() # a mixed contour/component glyph, which is decomposed by the # TTGlyphPen; one of the components does not exist thus should # be dropped b = ufo.newGlyph("b") pen = b.getPen() pen.moveTo((0, 200)) pen.lineTo((100, 200)) pen.lineTo((50, 300)) pen.closePath() pen.addComponent("a", (1, 0, 0, 1, 0, 0)) pen.addComponent("c", (1, 0, 0, 1, 0, 0)) # missing d = ufo.newGlyph("d") pen = d.getPen() pen.addComponent("c", (1, 0, 0, 1, 0, 0)) # missing e = ufo.newGlyph("e") pen = e.getPen() pen.addComponent("a", (1, 0, 0, 1, 0, 0)) pen.addComponent("c", (1, 0, 0, 1, 0, 0)) # missing compiler = OutlineTTFCompiler(ufo) ttFont = compiler.compile() glyf = ttFont["glyf"] assert glyf["a"].numberOfContours == 1 assert glyf["b"].numberOfContours == 2 assert glyf["d"].numberOfContours == 0 assert glyf["e"].numberOfContours == -1 # composite glyph assert len(glyf["e"].components) == 1
def test_compile_empty_gasp(self, testufo): # ignore empty gasp testufo.info.openTypeGaspRangeRecords = [] compiler = OutlineTTFCompiler(testufo) compiler.compile() assert "gasp" not in compiler.otf
def test_compile_without_gasp(self, testufo): testufo.info.openTypeGaspRangeRecords = None compiler = OutlineTTFCompiler(testufo) compiler.compile() assert "gasp" not in compiler.otf
def test_compile_with_gasp(self, testufo): compiler = OutlineTTFCompiler(testufo) compiler.compile() assert "gasp" in compiler.otf assert compiler.otf["gasp"].gaspRange == {7: 10, 65535: 15}
def test_setupTable_gasp(self, testufo): compiler = OutlineTTFCompiler(testufo) compiler.otf = TTFont() compiler.setupTable_gasp() assert "gasp" in compiler.otf assert compiler.otf["gasp"].gaspRange == {7: 10, 65535: 15}
def test_compile_without_gasp(self): self.ufo.info.openTypeGaspRangeRecords = None compiler = OutlineTTFCompiler(self.ufo) compiler.compile() self.assertTrue('gasp' not in compiler.otf)
def test_os2_no_widths(self, testufo): for glyph in testufo: glyph.width = 0 compiler = OutlineTTFCompiler(testufo) compiler.compile() assert compiler.otf["OS/2"].xAvgCharWidth == 0
def test_compile_empty_gasp(self): # ignore empty gasp self.ufo.info.openTypeGaspRangeRecords = [] compiler = OutlineTTFCompiler(self.ufo) compiler.compile() self.assertTrue('gasp' not in compiler.otf)
def test_autoUseMyMetrics_None(self, use_my_metrics_ufo): compiler = OutlineTTFCompiler(use_my_metrics_ufo) # setting 'autoUseMyMetrics' attribute to None disables the feature compiler.autoUseMyMetrics = None ttf = compiler.compile() assert not (ttf["glyf"]["Iacute"].components[1].flags & USE_MY_METRICS)
def test_compile_with_gasp(self): compiler = OutlineTTFCompiler(self.ufo) compiler.compile() self.assertTrue('gasp' in compiler.otf) self.assertEqual(compiler.otf['gasp'].gaspRange, {7: 10, 65535: 15})