Skip to content

Instantly share code, notes, and snippets.

@madig
Last active June 12, 2019 15:37
Show Gist options
  • Save madig/183d0440c9f7d05f04bd1280b9664bd1 to your computer and use it in GitHub Desktop.
Save madig/183d0440c9f7d05f04bd1280b9664bd1 to your computer and use it in GitHub Desktop.
#%%
import fontTools.designspaceLib
import fontTools.varLib
import fontTools.ttLib
import ufo2ft
import ufoLib2
def empty_ufo(style: str) -> ufoLib2.Font:
ufo = ufoLib2.Font()
ufo.info.unitsPerEm = 1000
ufo.info.ascender = 800
ufo.info.descender = -200
ufo.info.xHeight = 500
ufo.info.capHeight = 700
ufo.info.familyName = "Test"
ufo.info.styleName = style
ufo.info.postscriptUnderlineThickness = 50
ufo.info.postscriptUnderlinePosition = -150
return ufo
def extract_flat_kerning(
font: fontTools.ttLib.TTFont, pairpos_table: fontTools.ttLib.tables.otTables.PairPos
):
extracted_kerning = {}
for glyph_name_1 in pairpos_table.Coverage.glyphs:
class_def_1 = pairpos_table.ClassDef1.classDefs.get(glyph_name_1, 0)
for glyph_name_2 in font.getGlyphOrder():
class_def_2 = pairpos_table.ClassDef2.classDefs.get(glyph_name_2, 0)
kern_value = (
pairpos_table.Class1Record[class_def_1]
.Class2Record[class_def_2]
.Value1.XAdvance
)
extracted_kerning[(glyph_name_1, glyph_name_2)] = kern_value
return extracted_kerning
#%%
ufo_a = empty_ufo("Thin")
ufo_b = empty_ufo("Regular")
ufo_c = empty_ufo("Black")
for ufo in (ufo_a, ufo_b, ufo_c):
g = ufo.newGlyph("A")
g.width = 500
g.unicode = ord("A")
g = ufo.newGlyph("B")
g.width = 500
g.unicode = ord("B")
g = ufo.newGlyph("C")
g.width = 500
g.unicode = ord("C")
g = ufo.newGlyph("D")
g.width = 500
g.unicode = ord("D")
ufo.groups = {
"public.kern1.A": ["A"],
"public.kern1.B": ["B"],
"public.kern2.B": ["B"],
"public.kern2.C": ["C"],
"public.kern2.D": ["D"],
}
ufo_a.kerning[("public.kern1.A", "public.kern2.C")] = 10
ufo_a.kerning[("public.kern1.B", "public.kern2.C")] = 10
ufo_b.kerning[("public.kern1.A", "public.kern2.B")] = -20
ufo_b.kerning[("public.kern1.A", "public.kern2.D")] = -20
ufo_c.kerning[("public.kern1.A", "public.kern2.D")] = 40
ufo_c.kerning[("public.kern1.B", "public.kern2.D")] = 40
#%%
master_a = ufo2ft.compileTTF(ufo_a)
master_b = ufo2ft.compileTTF(ufo_b)
master_c = ufo2ft.compileTTF(ufo_c)
for i, m in enumerate((master_a, master_b, master_c)):
m.save(f"C:/Users/nikolaus.waxweiler/AppData/Local/Temp/asasas/{i}.ttf")
#%%
master_a_kerning = master_a["GPOS"].table.LookupList.Lookup[0].SubTable[0]
assert extract_flat_kerning(master_a, master_a_kerning) == {
("A", ".notdef"): 0,
("A", "A"): 0,
("A", "B"): 0,
("A", "C"): 10,
("A", "D"): 0,
("B", ".notdef"): 0,
("B", "A"): 0,
("B", "B"): 0,
("B", "C"): 10,
("B", "D"): 0,
}
master_b_kerning = master_b["GPOS"].table.LookupList.Lookup[0].SubTable[0]
assert extract_flat_kerning(master_b, master_b_kerning) == {
("A", ".notdef"): 0,
("A", "A"): 0,
("A", "B"): -20,
("A", "C"): 0,
("A", "D"): -20,
}
master_c_kerning = master_c["GPOS"].table.LookupList.Lookup[0].SubTable[0]
assert extract_flat_kerning(master_c, master_c_kerning) == {
("A", ".notdef"): 0,
("A", "A"): 0,
("A", "B"): 0,
("A", "C"): 0,
("A", "D"): 40,
("B", ".notdef"): 0,
("B", "A"): 0,
("B", "B"): 0,
("B", "C"): 0,
("B", "D"): 40,
}
#%%
designspace = fontTools.designspaceLib.DesignSpaceDocument()
axis_wght = fontTools.designspaceLib.AxisDescriptor()
axis_wght.minimum = 100
axis_wght.default = 400
axis_wght.maximum = 900
axis_wght.name = "Weight"
axis_wght.tag = "wght"
designspace.addAxis(axis_wght)
source_a = fontTools.designspaceLib.SourceDescriptor()
source_a.font = master_a
source_a.filename = "master_kerning_merging/0.ttf"
source_a.location = {"Weight": 100}
designspace.addSource(source_a)
source_b = fontTools.designspaceLib.SourceDescriptor()
source_b.font = master_b
source_b.filename = "master_kerning_merging/1.ttf"
source_b.location = {"Weight": 400}
designspace.addSource(source_b)
source_c = fontTools.designspaceLib.SourceDescriptor()
source_c.font = master_c
source_c.filename = "master_kerning_merging/2.ttf"
source_c.location = {"Weight": 900}
designspace.addSource(source_c)
designspace.write("C:/Users/nikolaus.waxweiler/AppData/Local/Temp/asasas/a.designspace")
#%%
varfont, _, _ = fontTools.varLib.build(designspace)
#%%
class_kerning_tables = [
t
for l in varfont["GPOS"].table.LookupList.Lookup
for t in l.SubTable
if t.Format == 2
]
#%%
assert len(class_kerning_tables) == 1
class_kerning_table = class_kerning_tables[0]
for class1_record in class_kerning_table.Class1Record:
class2_zero = class1_record.Class2Record[0]
assert vars(class2_zero.Value1).get("XAdvDevice", None) is None
assert extract_flat_kerning(varfont, class_kerning_table) == {
("A", ".notdef"): 0,
("A", "A"): 0,
("A", "B"): -20,
("A", "C"): 0,
("A", "D"): -20,
("B", ".notdef"): 0,
("B", "A"): 0,
("B", "B"): 0,
("B", "C"): 0,
("B", "D"): 0,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment