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_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_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_write_feature(self): feature = classes.GSFeature() feature.name = "sups" feature.code = " sub @standard by @sups;" feature.automatic = True feature.notes = "notes about sups" self.assertWrites(feature, dedent("""\ { automatic = 1; code = " sub @standard by @sups;"; name = sups; notes = "notes about sups"; } """))
def test_roundtrip_empty_feature(ufo_module): # https://github.com/googlefonts/glyphsLib/issues/562 font = to_glyphs([ufo_module.Font()]) feature = classes.GSFeature(name="dlig") feature.code = "" font.features.append(feature) (ufo, ) = to_ufos(font, ufo_module=ufo_module) assert ufo.features.text == dedent("""\ feature dlig { } dlig; """) font_r = to_glyphs([ufo]) assert len(font_r.features) == 1 feature_r = font_r.features[0] assert feature_r.name == "dlig" assert feature_r.code == ""
def test_roundtrip_automatic_feature(): font = to_glyphs([defcon.Font()]) feature = classes.GSFeature(name="ccmp") feature.code = "sub c by c.ss03;" feature.automatic = True font.features.append(feature) ufo, = to_ufos(font) assert ufo.features.text == dedent('''\ feature ccmp { # automatic 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 == "sub c by c.ss03;" assert feature_r.automatic is True
def test_roundtrip_automatic_feature(ufo_module): font = to_glyphs([ufo_module.Font()]) feature = classes.GSFeature(name="ccmp") feature.code = "sub c by c.ss03;" feature.automatic = True font.features.append(feature) (ufo, ) = to_ufos(font, ufo_module=ufo_module) assert ufo.features.text == dedent("""\ feature ccmp { # automatic 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 == "sub c by c.ss03;" assert feature_r.automatic is True
def test_write_font_attributes(self): """Test the writer on all GSFont attributes""" font = classes.GSFont() # List of properties from https://docu.glyphsapp.com/#gsfont # parent: not handled because it's internal and read-only # masters m1 = classes.GSFontMaster() m1.id = "M1" font.masters.insert(0, m1) m2 = classes.GSFontMaster() m2.id = "M2" font.masters.insert(1, m2) # instances i1 = classes.GSInstance() i1.name = "MuchBold" font.instances.append(i1) # glyphs g1 = classes.GSGlyph() g1.name = 'G1' font.glyphs.append(g1) # classes c1 = classes.GSClass() c1.name = "C1" font.classes.append(c1) # features f1 = classes.GSFeature() f1.name = "F1" font.features.append(f1) # featurePrefixes fp1 = classes.GSFeaturePrefix() fp1 = "FP1" font.featurePrefixes.append(fp1) # copyright font.copyright = "Copyright Bob" # designer font.designer = "Bob" # designerURL font.designerURL = "bob.me" # manufacturer font.manufacturer = "Manu" # manufacturerURL font.manufacturerURL = "manu.com" # versionMajor font.versionMajor = 2 # versionMinor font.versionMinor = 104 # date font.date = glyphs_datetime('2017-10-03 07:35:46 +0000') # familyName font.familyName = "Sans Rien" # upm font.upm = 2000 # note font.note = "Was bored, made this" # kerning font.kerning = OrderedDict([ ('M1', OrderedDict([ ('@MMK_L_G1', OrderedDict([ ('@MMK_R_G1', 0.1) ])) ])) ]) # userData font.userData = { 'a': 'test', 'b': [1, {'c': 2}], 'd': [1, "1"], } # grid -> gridLength font.grid = 35 # gridSubDivisions font.gridSubDivisions = 5 # keyboardIncrement font.keyboardIncrement = 1.2 # disablesNiceNames font.disablesNiceNames = True # customParameters font.customParameters['ascender'] = 300 # selection: not written # selectedLayers: not written # selectedFontMaster: not written # masterIndex: not written # currentText: not written # tabs: not written # currentTab: not written # filepath: not written # tool: not written # tools: not handled because it is a read-only list of GUI features # .appVersion (extra property that is not in the docs!) font.appVersion = "895" self.assertWrites(font, dedent("""\ { .appVersion = "895"; classes = ( { code = ""; name = C1; } ); copyright = "Copyright Bob"; customParameters = ( { name = note; value = "Was bored, made this"; }, { name = ascender; value = 300; } ); date = "2017-10-03 07:35:46 +0000"; designer = Bob; designerURL = bob.me; disablesNiceNames = 1; familyName = "Sans Rien"; featurePrefixes = ( FP1 ); features = ( { code = ""; name = F1; } ); fontMaster = ( { ascender = 800; capHeight = 700; id = M1; xHeight = 500; }, { ascender = 800; capHeight = 700; id = M2; xHeight = 500; } ); glyphs = ( { glyphname = G1; } ); gridLength = 35; gridSubDivision = 5; instances = ( { name = MuchBold; } ); kerning = { M1 = { "@MMK_L_G1" = { "@MMK_R_G1" = 0.1; }; }; }; keyboardIncrement = 1.2; manufacturer = Manu; manufacturerURL = manu.com; unitsPerEm = 2000; userData = { a = test; b = ( 1, { c = 2; } ); d = ( 1, "1" ); }; versionMajor = 2; versionMinor = 104; } """)) # Don't write the keyboardIncrement if it's 1 (default) font.keyboardIncrement = 1 written = test_helpers.write_to_lines(font) self.assertFalse(any("keyboardIncrement" in line for line in written))