Last active
June 12, 2019 15:37
-
-
Save madig/183d0440c9f7d05f04bd1280b9664bd1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#%% | |
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