def test_masters_have_user_locations_string(ufo_module): """Test that stringified Axis Locations are converted. Some versions of Glyph store a string instead of an int. """ font = to_glyphs([ufo_module.Font(), ufo_module.Font()]) font.customParameters["Axes"] = [{"Tag": "opsz", "Name": "Optical"}] font.masters[0].weightValue = 0 font.masters[0].customParameters["Axis Location"] = [{ "Axis": "Optical", "Location": 13 }] font.masters[1].weightValue = 1000 font.masters[1].customParameters["Axis Location"] = [{ "Axis": "Optical", "Location": "100" }] doc = to_designspace(font, ufo_module=ufo_module) assert doc.axes[0].map == [(13, 0), (100, 1000)] font = to_glyphs(doc) assert font.masters[0].customParameters["Axis Location"] == [{ "Axis": "Optical", "Location": 13 }] assert font.masters[1].customParameters["Axis Location"] == [{ "Axis": "Optical", "Location": 100 }]
def test_only_background(ufo_module): ufo = ufo_module.Font() background = ufo.newLayer("public.background") background.newGlyph("a") # Check that it does not crash to_glyphs([ufo])
def test_roundtrip_disabled_feature(): font = to_glyphs([defcon.Font()]) feature = classes.GSFeature(name="ccmp") feature.code = dedent("""\ sub a by a.ss03; sub b by b.ss03; sub c by c.ss03; """) feature.disabled = True font.features.append(feature) ufo, = to_ufos(font) assert ufo.features.text == dedent('''\ feature ccmp { # disabled #sub a by a.ss03; #sub b by b.ss03; #sub c by c.ss03; } ccmp; ''') font_r = to_glyphs([ufo]) assert len(font_r.features) == 1 feature_r = font_r.features[0] assert feature_r.name == "ccmp" assert feature_r.code == feature.code assert feature_r.disabled is True font_rr = to_glyphs(to_ufos(font_r)) assert len(font_rr.features) == 1 feature_rr = font_rr.features[0] assert feature_rr.name == "ccmp" assert feature_rr.code == feature.code assert feature_rr.disabled is True
def test_designspace_generation_bracket_roundtrip_psnames(datadir, ufo_module): with open(str(datadir.join("PSNames.glyphs"))) as f: font = glyphsLib.load(f) designspace: DesignSpaceDocument = to_designspace(font, ufo_module=ufo_module) assert designspace.findDefault().font.lib["public.postscriptNames"] == { "a-cy": "uni0430", "a-cy.BRACKET.18": "uni0430.BRACKET.18", "a-cy.alt": "uni0430.alt", } font_rt = to_glyphs(designspace) designspace_rt = to_designspace(font_rt, ufo_module=ufo_module) assert designspace_rt.findDefault().font.lib["public.postscriptNames"] == { "a-cy": "uni0430", "a-cy.BRACKET.18": "uni0430.BRACKET.18", "a-cy.alt": "uni0430.alt", } font_rt2 = to_glyphs(designspace_rt) designspace_rt2 = to_designspace(font_rt2, ufo_module=ufo_module) assert designspace_rt2.findDefault().font.lib["public.postscriptNames"] == { "a-cy": "uni0430", "a-cy.BRACKET.18": "uni0430.BRACKET.18", "a-cy.alt": "uni0430.alt", }
def test_background_before_foreground(ufo_module): ufo = ufo_module.Font() ufo.newGlyph("a") background = ufo.newLayer("public.background") background.newGlyph("a") ufo.layers.layerOrder = ["public.background", "public.default"] # Check that it does not crash to_glyphs([ufo])
def test_masters_have_user_locations(): """Test the new axis definition with custom parameters. See https://github.com/googlei18n/glyphsLib/issues/280. For tests about the previous system with weight/width/custom, see `tests/builder/interpolation_test.py`. """ # Get a font with two masters font = to_glyphs([defcon.Font(), defcon.Font()]) font.customParameters['Axes'] = [{ 'Tag': 'opsz', 'Name': 'Optical', }] # There is only one axis, so the design location is stored in the weight font.masters[0].weightValue = 0 # The user location is stored as a custom parameter font.masters[0].customParameters['Axis Location'] = [{ 'Axis': 'Optical', 'Location': 13, }] font.masters[1].weightValue = 1000 font.masters[1].customParameters['Axis Location'] = [{ 'Axis': 'Optical', 'Location': 100, }] doc = to_designspace(font) assert len(doc.axes) == 1 assert doc.axes[0].map == [ (13, 0), (100, 1000), ] assert len(doc.sources) == 2 assert doc.sources[0].location == {'Optical': 0} assert doc.sources[1].location == {'Optical': 1000} font = to_glyphs(doc) assert font.customParameters['Axes'] == [{ 'Tag': 'opsz', 'Name': 'Optical', }] assert font.masters[0].weightValue == 0 assert font.masters[0].customParameters['Axis Location'] == [{ 'Axis': 'Optical', 'Location': 13, }] assert font.masters[1].weightValue == 1000 assert font.masters[1].customParameters['Axis Location'] == [{ 'Axis': 'Optical', 'Location': 100, }]
def test_axis_mapping(ufo_module): font = to_glyphs([ ufo_module.Font(), ufo_module.Font(), ufo_module.Font(), ufo_module.Font() ]) font.masters[0].weightValue = 0 font.masters[0].widthValue = 100 font.masters[1].weightValue = 1000 font.masters[1].widthValue = 100 font.masters[2].weightValue = 0 font.masters[2].widthValue = 75 font.masters[3].weightValue = 1000 font.masters[3].widthValue = 75 wght_mapping = [(100, 0), (400, 350), (900, 1000)] wdth_mapping = [(75, 75), (100, 100)] axis_mappings = { "wght": {str(float(k)): v for k, v in wght_mapping}, "wdth": {str(float(k)): v for k, v in wdth_mapping}, } font.customParameters["Axis Mappings"] = axis_mappings # When we convert to a designspace, the wdth mapping is removed because # it isn't needed. doc = to_designspace(font, ufo_module=ufo_module) assert doc.axes[0].name == "Weight" assert doc.axes[0].minimum == 100 assert doc.axes[0].default == 100 assert doc.axes[0].maximum == 900 assert doc.axes[0].map == wght_mapping assert doc.axes[1].name == "Width" assert doc.axes[1].minimum == 75 assert doc.axes[0].default == 100 assert doc.axes[1].maximum == 100 assert doc.axes[1].map != wdth_mapping assert doc.axes[1].map == [] # When we convert back to glyphs, the wdth mapping isn't present because # it was removed during the designspace conversion. font = to_glyphs(doc) axis_mappings["wdth"] = {} assert font.customParameters["Axis Mappings"] == axis_mappings
def test_designspace_generation_regular_different_family_names(tmpdir): ufo_Lt = defcon.Font() ufo_Lt.info.familyName = "CoolFoundry Examplary Serif Light" ufo_Lt.info.styleName = "Regular" ufo_Lt.info.openTypeOS2WeightClass = 300 ufo_Rg = defcon.Font() ufo_Rg.info.familyName = "CoolFoundry Examplary Serif" ufo_Rg.info.styleName = "Regular" ufo_Rg.info.openTypeOS2WeightClass = 400 # Different family names are not allowed # REVIEW: reasonable requirement? with pytest.raises(Exception): to_glyphs([ufo_Lt, ufo_Rg])
def test_dont_copy_advance_to_the_background_unless_it_was_there(tmpdir): ufo = defcon.Font() bg = ufo.newLayer('public.background') fg_a = ufo.newGlyph('a') fg_a.width = 100 bg_a = bg.newGlyph('a') fg_b = ufo.newGlyph('b') fg_b.width = 200 bg_b = bg.newGlyph('b') bg_b.width = 300 fg_c = ufo.newGlyph('c') fg_c.width = 400 bg_c = bg.newGlyph('c') bg_c.width = 400 font = to_glyphs([ufo]) path = os.path.join(str(tmpdir), 'test.glyphs') font.save(path) saved_font = classes.GSFont(path) for font in [font, saved_font]: ufo, = to_ufos(font) assert ufo['a'].width == 100 assert ufo.layers['public.background']['a'].width == 0 assert ufo['b'].width == 200 assert ufo.layers['public.background']['b'].width == 300 assert ufo['c'].width == 400 assert ufo.layers['public.background']['c'].width == 400
def test_designspace_source_locations(tmpdir): """Check that opening UFOs from their source descriptor works with both the filename and the path attributes. """ designspace_path = os.path.join(str(tmpdir), 'test.designspace') light_ufo_path = os.path.join(str(tmpdir), 'light.ufo') bold_ufo_path = os.path.join(str(tmpdir), 'bold.ufo') designspace = DesignSpaceDocument() light_source = designspace.newSourceDescriptor() light_source.filename = 'light.ufo' designspace.addSource(light_source) bold_source = designspace.newSourceDescriptor() bold_source.path = bold_ufo_path designspace.addSource(bold_source) designspace.write(designspace_path) light = defcon.Font() light.info.ascender = 30 light.save(light_ufo_path) bold = defcon.Font() bold.info.ascender = 40 bold.save(bold_ufo_path) designspace = DesignSpaceDocument() designspace.read(designspace_path) font = to_glyphs(designspace) assert len(font.masters) == 2 assert font.masters[0].ascender == 30 assert font.masters[1].ascender == 40
def test_custom_featureWriters_in_designpace_lib(tmpdir, ufo_module): """Test that we can roundtrip custom user-defined ufo2ft featureWriters settings that are stored in the designspace lib or GSFont.userData. """ font = classes.GSFont() font.masters.append(classes.GSFontMaster()) kern = classes.GSFeature(name="kern", code="pos a b 100;") font.features.append(kern) customFeatureWriters = list(DEFAULT_FEATURE_WRITERS) + [{ "class": "MyCustomWriter", "module": "myCustomWriter" }] font.userData[UFO2FT_FEATURE_WRITERS_KEY] = customFeatureWriters designspace = to_designspace(font, ufo_module=ufo_module) path = str(tmpdir / "test.designspace") designspace.write(path) for source in designspace.sources: source.font.save(str(tmpdir / source.filename)) designspace2 = DesignSpaceDocument.fromfile(path) assert UFO2FT_FEATURE_WRITERS_KEY in designspace2.lib assert designspace2.lib[UFO2FT_FEATURE_WRITERS_KEY] == customFeatureWriters font2 = to_glyphs(designspace2, ufo_module=ufo_module) assert len(font2.userData) == 1 assert font2.userData[UFO2FT_FEATURE_WRITERS_KEY] == customFeatureWriters
def test_default_featureWriters_in_designspace_lib(tmpdir, ufo_module): """Test that the glyphsLib custom featureWriters settings (with mode="append") are exported to the designspace lib whenever a GSFont contains a manual 'kern' feature. And that they are not imported back to GSFont.userData if they are the same as the default value. """ font = classes.GSFont() font.masters.append(classes.GSFontMaster()) kern = classes.GSFeature(name="kern", code="pos a b 100;") font.features.append(kern) designspace = to_designspace(font, ufo_module=ufo_module) path = str(tmpdir / "test.designspace") designspace.write(path) for source in designspace.sources: source.font.save(str(tmpdir / source.filename)) designspace2 = DesignSpaceDocument.fromfile(path) assert UFO2FT_FEATURE_WRITERS_KEY in designspace2.lib assert designspace2.lib[ UFO2FT_FEATURE_WRITERS_KEY] == DEFAULT_FEATURE_WRITERS font2 = to_glyphs(designspace2, ufo_module=ufo_module) assert not len(font2.userData) assert len([f for f in font2.features if f.name == "kern"]) == 1
def test_designspace_generation_bracket_no_export_glyph(datadir): with open(str(datadir.join("BracketTestFont2.glyphs"))) as f: font = glyphsLib.load(f) font.glyphs["E"].export = False designspace = to_designspace(font, write_skipexportglyphs=True) assert "E" in designspace.lib.get("public.skipExportGlyphs") for source in designspace.sources: assert "E.REV_BRACKET.570" not in source.font assert "E.BRACKET.630" not in source.font for rule in designspace.rules: assert "E" not in {g for g in itertools.chain(*rule.subs)} font_rt = to_glyphs(designspace) assert "E" in font_rt.glyphs assert {l.name for l in font_rt.glyphs["E"].layers} == { "Regular", "Regular [630]", "Bold", "Bold ]570]", }
def test_designspace_generation_bracket_composite_glyph(datadir): with open(str(datadir.join("BracketTestFont2.glyphs"))) as f: font = glyphsLib.load(f) g = font.glyphs["B"] for layer in g.layers: assert layer.components[0].name == "A" designspace = to_designspace(font) for source in designspace.sources: ufo = source.font assert "B.BRACKET.600" in ufo assert ufo["B"].components[0].baseGlyph == "A" assert ufo["B.BRACKET.600"].components[0].baseGlyph == "A.BRACKET.600" font_rt = to_glyphs(designspace) assert "B" in font_rt.glyphs g2 = font_rt.glyphs["B"] for layer in g2.layers: assert layer.components[0].name == "A" assert "B.BRACKET.600" not in font_rt.glyphs
def roundtrip(ufo, tmpdir): font = to_glyphs([ufo], minimize_ufo_diffs=True) filename = os.path.join(str(tmpdir), 'font.glyphs') font.save(filename) font = classes.GSFont(filename) ufo, = to_ufos(font) return font, ufo
def test_dont_copy_advance_to_the_background_unless_it_was_there( tmpdir, ufo_module): ufo = ufo_module.Font() bg = ufo.newLayer("public.background") fg_a = ufo.newGlyph("a") fg_a.width = 100 bg.newGlyph("a") fg_b = ufo.newGlyph("b") fg_b.width = 200 bg_b = bg.newGlyph("b") bg_b.width = 300 fg_c = ufo.newGlyph("c") fg_c.width = 400 bg_c = bg.newGlyph("c") bg_c.width = 400 font = to_glyphs([ufo]) path = os.path.join(str(tmpdir), "test.glyphs") font.save(path) saved_font = classes.GSFont(path) for font in [font, saved_font]: (ufo, ) = to_ufos(font) assert ufo["a"].width == 100 assert ufo.layers["public.background"]["a"].width == 0 assert ufo["b"].width == 200 assert ufo.layers["public.background"]["b"].width == 300 assert ufo["c"].width == 400 assert ufo.layers["public.background"]["c"].width == 400
def roundtrip(ufo, tmpdir, ufo_module): font = to_glyphs([ufo], minimize_ufo_diffs=True) filename = os.path.join(str(tmpdir), "font.glyphs") font.save(filename) font = classes.GSFont(filename) (ufo, ) = to_ufos(font, ufo_module=ufo_module) return font, ufo
def test_groups_remain_at_top(tmpdir, ufo_module): ufo = ufo_module.Font() ufo.newGlyph("zero") ufo.newGlyph("zero.alt") fea_example = dedent("""\ @FIG_DFLT = [zero]; @FIG_ALT = [zero.alt]; lookup pnum_text { sub @FIG_DFLT by @FIG_ALT; } pnum_text; feature pnum { lookup pnum_text; } pnum; """) ufo.features.text = fea_example font = to_glyphs([ufo], minimize_ufo_diffs=True) filename = os.path.join(str(tmpdir), "font.glyphs") font.save(filename) font = classes.GSFont(filename) (rtufo, ) = to_ufos(font, ufo_module=ufo_module) fea_rt = rtufo.features.text assert fea_rt.index("@FIG_DFLT") < fea_rt.index("lookup") < fea_rt.index( "feature")
def test_mapping_is_same_regardless_of_axes_custom_parameter(ufo_module): # https://github.com/googlefonts/glyphsLib/issues/409 # https://github.com/googlefonts/glyphsLib/issues/411 # First, try without the custom param font = to_glyphs([ufo_module.Font(), ufo_module.Font(), ufo_module.Font()]) font.masters[0].name = "ExtraLight" font.masters[0].weightValue = 200 font.masters[1].name = "Regular" font.masters[1].weightValue = 400 font.masters[2].name = "Bold" font.masters[2].weightValue = 700 doc = to_designspace(font, ufo_module=ufo_module) assert doc.axes[0].minimum == 200 assert doc.axes[0].maximum == 700 assert doc.axes[0].map == [] # Now with the custom parameter. Should produce the same results font.customParameters["Axes"] = [{"Name": "Weight", "Tag": "wght"}] doc = to_designspace(font, ufo_module=ufo_module) assert doc.axes[0].minimum == 200 assert doc.axes[0].maximum == 700 assert doc.axes[0].map == []
def test_master_user_location_goes_into_os2_classes(ufo_module): font = to_glyphs([ufo_module.Font(), ufo_module.Font()]) font.customParameters["Axes"] = [ {"Tag": "wght", "Name": "Weight"}, {"Tag": "wdth", "Name": "Width"}, ] font.masters[0].weightValue = 0 font.masters[0].widthValue = 1000 # This master will be Light Expanded # as per https://docs.microsoft.com/en-gb/typography/opentype/spec/os2#uswidthclass font.masters[0].customParameters["Axis Location"] = [ {"Axis": "Weight", "Location": 300}, {"Axis": "Width", "Location": 125}, ] font.masters[1].weightValue = 1000 font.masters[1].widthValue = 0 # This master is Black Ultra-condensed but not quite font.masters[1].customParameters["Axis Location"] = [ {"Axis": "Weight", "Location": 920}, # instead of 900 {"Axis": "Width", "Location": 55}, # instead of 50 ] light, black = to_ufos(font) assert light.info.openTypeOS2WeightClass == 300 assert light.info.openTypeOS2WidthClass == 7 assert black.info.openTypeOS2WeightClass == 920 assert black.info.openTypeOS2WidthClass == 1
def test_only_background(): ufo = defcon.Font() background = ufo.newLayer('public.background') a_bg = background.newGlyph('a') # Check that it does not crash font = to_glyphs([ufo])
def test_info_name_records(tmpdir, ufo_module): ufo = ufo_module.Font() name_records = [ { "nameID": 19, "platformID": 1, "encodingID": 0, "languageID": 1, "string": "Les cornichons sont nos amis", }, { "nameID": 1, "platformID": 3, "encodingID": 1, "languageID": 0x0410, "string": "Illustrativo Sans", }, ] ufo.info.openTypeNameRecords = name_records font = to_glyphs([ufo], minimize_ufo_diffs=True) filename = os.path.join(str(tmpdir), "font.glyphs") font.save(filename) font = classes.GSFont(filename) (ufo, ) = to_ufos(font, ufo_module=ufo_module) print(ufo.info.openTypeNameRecords) assert [dict(r) for r in ufo.info.openTypeNameRecords] == name_records
def test_warn_diff_between_designspace_and_ufos(caplog): ufo = defcon.Font() ufo.info.familyName = 'UFO Family Name' ufo.info.styleName = 'UFO Style Name' # ufo.info.styleMapFamilyName = 'UFO Stylemap Family Name' # ufo.info.styleMapStyleName = 'bold' doc = DesignSpaceDocument() source = doc.newSourceDescriptor() source.font = ufo source.familyName = 'DS Family Name' source.styleName = 'DS Style Name' doc.addSource(source) font = to_glyphs(doc, minimize_ufo_diffs=True) assert any(record.levelname == 'WARNING' for record in caplog.records) assert 'The familyName is different between the UFO and the designspace source' in caplog.text assert 'The styleName is different between the UFO and the designspace source' in caplog.text doc = to_designspace(font) source = doc.sources[0] # The UFO info will prevail assert ufo.info.familyName == 'UFO Family Name' assert ufo.info.styleName == 'UFO Style Name' assert source.font.info.familyName == 'UFO Family Name' assert source.font.info.styleName == 'UFO Style Name'
def test_axis_with_no_mapping_does_not_error_in_roundtrip(ufo_module): """Tests that a custom axis without a mapping and without sources on its extremes does not generate an error during roundtrip. Also tests that during a to_glyphs, to_designspace roundtrip the min and max axis information is not lost. """ doc = designspaceLib.DesignSpaceDocument() # Add a "Regular" source regular = doc.newSourceDescriptor() regular.font = ufo_module.Font() regular.location = {"Style": 0} doc.addSource(regular) axis = doc.newAxisDescriptor() axis.tag = "styl" axis.name = "Style" doc.addAxis(axis) # This axis spans a range of 0 to 1 but only has a source at {"Style": 0} # and no explicit mapping. The point of this test is to see if the min and # max are still the same after round tripping. doc.axes[0].minimum = 0 doc.axes[0].maximum = 1 doc.axes[0].default = 0 doc.axes[0].map = [] doc2 = deepcopy(doc) font = to_glyphs(doc2) doc_rt = to_designspace(font) assert doc_rt.axes[0].serialize() == doc.axes[0].serialize()
def test_designspace_generation_reverse_bracket_roundtrip(datadir): with open(str(datadir.join("BracketTestFont2.glyphs"))) as f: font = glyphsLib.load(f) g = font.glyphs["D"] assert {"Regular ]600]", "Bold ]600]"}.intersection(l.name for l in g.layers) designspace = to_designspace(font) assert designspace.rules[1].name == "BRACKET.400.600" assert designspace.rules[1].conditionSets == [[ dict(name="Weight", minimum=400, maximum=600) ]] assert designspace.rules[1].subs == [("D", "D.REV_BRACKET.600")] for source in designspace.sources: ufo = source.font assert "D.REV_BRACKET.600" in ufo font_rt = to_glyphs(designspace) assert "D" in font_rt.glyphs g2 = font_rt.glyphs["D"] assert {"Regular ]600]", "Bold ]600]"}.intersection(l.name for l in g2.layers) assert "D.REV_BRACKET.600" not in font_rt.glyphs
def test_warn_diff_between_designspace_and_ufos(caplog, ufo_module): ufo = ufo_module.Font() ufo.info.familyName = "UFO Family Name" ufo.info.styleName = "UFO Style Name" # ufo.info.styleMapFamilyName = 'UFO Stylemap Family Name' # ufo.info.styleMapStyleName = 'bold' doc = DesignSpaceDocument() source = doc.newSourceDescriptor() source.font = ufo source.familyName = "DS Family Name" source.styleName = "DS Style Name" doc.addSource(source) font = to_glyphs(doc, minimize_ufo_diffs=True) assert any(record.levelname == "WARNING" for record in caplog.records) assert ( "The familyName is different between the UFO and the designspace source" in caplog.text) assert ( "The styleName is different between the UFO and the designspace source" in caplog.text) doc = to_designspace(font, ufo_module=ufo_module) source = doc.sources[0] # The UFO info will prevail assert ufo.info.familyName == "UFO Family Name" assert ufo.info.styleName == "UFO Style Name" assert source.font.info.familyName == "UFO Family Name" assert source.font.info.styleName == "UFO Style Name"
def test_masters_have_user_locations(ufo_module): """Test the new axis definition with custom parameters. See https://github.com/googlefonts/glyphsLib/issues/280. For tests about the previous system with weight/width/custom, see `tests/builder/interpolation_test.py`. """ # Get a font with two masters font = to_glyphs([ufo_module.Font(), ufo_module.Font()]) font.customParameters["Axes"] = [{"Tag": "opsz", "Name": "Optical"}] # There is only one axis, so the design location is stored in the weight font.masters[0].weightValue = 0 # The user location is stored as a custom parameter font.masters[0].customParameters["Axis Location"] = [{ "Axis": "Optical", "Location": 13 }] font.masters[1].weightValue = 1000 font.masters[1].customParameters["Axis Location"] = [{ "Axis": "Optical", "Location": 100 }] doc = to_designspace(font, ufo_module=ufo_module) assert len(doc.axes) == 1 assert doc.axes[0].map == [(13, 0), (100, 1000)] assert len(doc.sources) == 2 assert doc.sources[0].location == {"Optical": 0} assert doc.sources[1].location == {"Optical": 1000} font = to_glyphs(doc) assert font.customParameters["Axes"] == [{ "Tag": "opsz", "Name": "Optical" }] assert font.masters[0].weightValue == 0 assert font.masters[0].customParameters["Axis Location"] == [{ "Axis": "Optical", "Location": 13 }] assert font.masters[1].weightValue == 1000 assert font.masters[1].customParameters["Axis Location"] == [{ "Axis": "Optical", "Location": 100 }]
def test_weird_kerning_roundtrip(ufo_module): groups = { "public.kern1.i": [ "i", "dotlessi", "iacute", "icircumflex", "idieresis", "igrave", "imacron", "iogonek", "itilde", "f_i", "f_f_i", "fi", "ffi", ], "public.kern2.i": [ "i", "dotlessi", "iacute", "icircumflex", "idieresis", "igrave", "ij", "imacron", "iogonek", "itilde", "dotlessij", "ijacute", ], } kerning = { ("icircumflex", "public.kern2.i"): 20, ("idieresis", "idieresis"): 125, ("idieresis", "public.kern2.i"): 35, ("itilde", "public.kern2.i"): 10, ("public.kern1.i", "icircumflex"): 15, ("public.kern1.i", "idieresis"): 40, ("public.kern1.i", "itilde"): 10, } glyphs = sorted({g for glyphs in groups.values() for g in glyphs}) ufo = ufo_module.Font() for glyph in glyphs: ufo.newGlyph(glyph) for k, v in groups.items(): ufo.groups[k] = v for k, v in kerning.items(): ufo.kerning[k] = v font = to_glyphs([ufo]) (ufo, ) = to_ufos(font) # The kerning and groups should round-trip untouched for name, glyphs in groups.items(): assert set(glyphs) == set(ufo.groups[name]) assert ufo.kerning == kerning
def test_designspace_generation_bracket_roundtrip(datadir): with open(str(datadir.join("BracketTestFont.glyphs"))) as f: font = glyphsLib.load(f) designspace = to_designspace(font) assert designspace.rules[0].name == "BRACKET.300.600" assert designspace.rules[0].conditionSets == [[ dict(name="Weight", minimum=300, maximum=600) ]] assert designspace.rules[0].subs == [("x", "x.BRACKET.300")] assert designspace.rules[1].name == "BRACKET.300.1000" assert designspace.rules[1].conditionSets == [[ dict(name="Weight", minimum=300, maximum=1000) ]] assert designspace.rules[1].subs == [("a", "a.BRACKET.300")] assert designspace.rules[2].name == "BRACKET.600.1000" assert designspace.rules[2].conditionSets == [[ dict(name="Weight", minimum=600, maximum=1000) ]] assert designspace.rules[2].subs == [("x", "x.BRACKET.600")] for source in designspace.sources: assert "[300]" not in source.font.layers assert "Something [300]" not in source.font.layers assert "[600]" not in source.font.layers assert "Other [600]" not in source.font.layers g1 = source.font["x.BRACKET.300"] assert not g1.unicodes g2 = source.font["x.BRACKET.600"] assert not g2.unicodes font_rt = to_glyphs(designspace) assert "x" in font_rt.glyphs g1 = font_rt.glyphs["x"] assert len(g1.layers) == 12 and {l.name for l in g1.layers} == { "[300]", "[600]", "Bold", "Condensed Bold", "Condensed Light", "Light", "Other [600]", "Something [300]", } g2 = font_rt.glyphs["a"] assert len(g2.layers) == 8 and {l.name for l in g2.layers} == { "[300]", "Bold", "Condensed Bold", "Condensed Light", "Light", } assert "a.BRACKET.300" not in font_rt.glyphs assert "x.BRACKET.300" not in font_rt.glyphs assert "x.BRACKET.600" not in font_rt.glyphs
def test_custom_stylemap_style_name(ufo_module): ufo = ufo_module.Font() ufo.info.styleMapStyleName = "bold" # Not "regular" font = to_glyphs([ufo], minimize_ufo_diffs=True) (ufo, ) = to_ufos(font) assert ufo.info.styleMapStyleName == "bold"