def test_ignoreMarks(self): font = Font() for name in ("one", "four", "six"): font.newGlyph(name) font.kerning.update({ ('four', 'six'): -55.0, ('one', 'six'): -30.0, }) # default is ignoreMarks=True writer = KernFeatureWriter() kern = writer.write(font) assert kern == dedent(""" lookup kern_ltr { lookupflag IgnoreMarks; pos four six -55; pos one six -30; } kern_ltr; feature kern { lookup kern_ltr; } kern;""") writer = KernFeatureWriter(ignoreMarks=False) kern = writer.write(font) assert kern == dedent(""" lookup kern_ltr { pos four six -55; pos one six -30; } kern_ltr; feature kern { lookup kern_ltr; } kern;""")
def test_arabic_numerals(self): ufo = Font() for name, code in [("four-ar", 0x664), ("seven-ar", 0x667)]: glyph = ufo.newGlyph(name) glyph.unicode = code ufo.kerning.update({ ('four-ar', 'seven-ar'): -30, }) ufo.features.text = dedent(""" languagesystem DFLT dflt; languagesystem arab dflt; """) writer = KernFeatureWriter() kern = writer.write(ufo) assert kern == dedent(""" lookup kern_ltr { lookupflag IgnoreMarks; pos four-ar seven-ar -30; } kern_ltr; feature kern { lookup kern_ltr; } kern;""")
def test_mode(self, FontClass): ufo = FontClass() for name in ("one", "four", "six", "seven"): ufo.newGlyph(name) existing = dedent( """\ feature kern { pos one four' -50 six; } kern; """ ) ufo.features.text = existing ufo.kerning.update({("seven", "six"): 25.0}) writer = KernFeatureWriter() # default mode="skip" feaFile = parseLayoutFeatures(ufo) assert not writer.write(ufo, feaFile) assert str(feaFile) == existing # pass optional "append" mode writer = KernFeatureWriter(mode="append") feaFile = parseLayoutFeatures(ufo) assert writer.write(ufo, feaFile) expected = existing + dedent( """ lookup kern_ltr { lookupflag IgnoreMarks; pos seven six 25; } kern_ltr; feature kern { lookup kern_ltr; } kern; """ ) assert str(feaFile) == expected # pass "skip" mode explicitly writer = KernFeatureWriter(mode="skip") feaFile = parseLayoutFeatures(ufo) assert not writer.write(ufo, feaFile) assert str(feaFile) == existing
def test_cleanup_missing_glyphs(self, FontClass): groups = { "public.kern1.A": ["A", "Aacute", "Abreve", "Acircumflex"], "public.kern2.B": ["B", "D", "E", "F"], "public.kern1.C": ["foobar"], } kerning = { ("public.kern1.A", "public.kern2.B"): 10, ("public.kern1.A", "baz"): -25, ("baz", "public.kern2.B"): -20, ("public.kern1.C", "public.kern2.B"): 20, } ufo = FontClass() exclude = {"Abreve", "D", "foobar"} for glyphs in groups.values(): for glyph in glyphs: if glyph in exclude: continue ufo.newGlyph(glyph) ufo.groups.update(groups) ufo.kerning.update(kerning) writer = KernFeatureWriter() feaFile = parseLayoutFeatures(ufo) writer.write(ufo, feaFile) classDefs = getClassDefs(feaFile) assert len(classDefs) == 2 assert classDefs[0].name == "kern1.A" assert classDefs[1].name == "kern2.B" assert getGlyphs(classDefs[0]) == ["A", "Aacute", "Acircumflex"] assert getGlyphs(classDefs[1]) == ["B", "E", "F"] lookups = getLookups(feaFile) assert len(lookups) == 1 kern_ltr = lookups[0] assert kern_ltr.name == "kern_ltr" rules = getPairPosRules(kern_ltr) assert len(rules) == 1 assert str(rules[0]) == "pos @kern1.A @kern2.B 10;"
def test_ignoreMarks(self, FontClass): font = FontClass() for name in ("one", "four", "six"): font.newGlyph(name) font.kerning.update({("four", "six"): -55.0, ("one", "six"): -30.0}) # default is ignoreMarks=True writer = KernFeatureWriter() feaFile = ast.FeatureFile() assert writer.write(font, feaFile) assert str(feaFile) == dedent( """\ lookup kern_ltr { lookupflag IgnoreMarks; pos four six -55; pos one six -30; } kern_ltr; feature kern { lookup kern_ltr; } kern; """ ) writer = KernFeatureWriter(ignoreMarks=False) feaFile = ast.FeatureFile() assert writer.write(font, feaFile) assert str(feaFile) == dedent( """\ lookup kern_ltr { pos four six -55; pos one six -30; } kern_ltr; feature kern { lookup kern_ltr; } kern; """ )
def test_insert_comment_after(self, FontClass): ufo = FontClass() for name in ("one", "four", "six", "seven"): ufo.newGlyph(name) existing = dedent("""\ feature kern { pos one four' -50 six; # # Automatic Code # } kern; """) ufo.features.text = existing ufo.kerning.update({("seven", "six"): 25.0}) writer = KernFeatureWriter() feaFile = parseLayoutFeatures(ufo) assert writer.write(ufo, feaFile) expected = dedent("""\ feature kern { pos one four' -50 six; # # } kern; lookup kern_ltr { lookupflag IgnoreMarks; pos seven six 25; } kern_ltr; feature kern { lookup kern_ltr; } kern; """) assert str(feaFile) == expected # test append mode ignores insert marker generated = self.writeFeatures(ufo, mode="append") assert str(generated) == dedent(""" lookup kern_ltr { lookupflag IgnoreMarks; pos seven six 25; } kern_ltr; feature kern { lookup kern_ltr; } kern; """)
def test_insert_comment_middle(self, FontClass): ufo = FontClass() for name in ("one", "four", "six", "seven"): ufo.newGlyph(name) existing = dedent("""\ feature kern { pos one four' -50 six; # # Automatic Code # pos one six' -50 six; } kern; """) ufo.features.text = existing ufo.kerning.update({("seven", "six"): 25.0}) writer = KernFeatureWriter() feaFile = parseLayoutFeatures(ufo) with pytest.raises( InvalidFeaturesData, match="Insert marker has rules before and after, feature kern " "cannot be inserted.", ): writer.write(ufo, feaFile) # test append mode ignores insert marker generated = self.writeFeatures(ufo, mode="append") assert str(generated) == dedent(""" lookup kern_ltr { lookupflag IgnoreMarks; pos seven six 25; } kern_ltr; feature kern { lookup kern_ltr; } kern; """)
def test_quantize(self, FontClass): font = FontClass() for name in ("one", "four", "six"): font.newGlyph(name) font.kerning.update({("four", "six"): -57.0, ("one", "six"): -24.0}) writer = KernFeatureWriter(quantization=5) feaFile = ast.FeatureFile() assert writer.write(font, feaFile) assert str(feaFile) == dedent("""\ lookup kern_ltr { lookupflag IgnoreMarks; pos four six -55; pos one six -25; } kern_ltr; feature kern { lookup kern_ltr; } kern; """)
def test_insert_comment_before_extended(self, FontClass): ufo = FontClass() for name in ("one", "four", "six", "seven"): ufo.newGlyph(name) existing = dedent("""\ feature kern { # # Automatic Code End # pos one four' -50 six; } kern; """) ufo.features.text = existing ufo.kerning.update({("seven", "six"): 25.0}) writer = KernFeatureWriter() feaFile = parseLayoutFeatures(ufo) assert writer.write(ufo, feaFile) expected = dedent("""\ lookup kern_ltr { lookupflag IgnoreMarks; pos seven six 25; } kern_ltr; feature kern { lookup kern_ltr; } kern; feature kern { # # pos one four' -50 six; } kern; """) assert str(feaFile).strip() == expected.strip()