-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfbdiff.py
91 lines (78 loc) · 3.3 KB
/
fbdiff.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import argparse
import textwrap
from fontTools.ttLib import TTFont
def sorted_tags(ttf):
"""Return the table tags of ttf in the order of the file."""
tables = ttf.reader.tables
return sorted(tables.keys(), key=lambda tag: tables[tag].offset)
def main():
parser = argparse.ArgumentParser(description="Compare the binary tables of two OpenType fonts.")
parser.add_argument('-o', '--table-order', action="store_true",
help="show the table tags in sfnt order side-by-side")
parser.add_argument('font_A', metavar="FONT_A", type=argparse.FileType("rb"),
help="an OpenType font file")
parser.add_argument('font_B', metavar="FONT_B", type=argparse.FileType("rb"),
help="an OpenType font file")
args = parser.parse_args()
font_A = TTFont(args.font_A)
font_B = TTFont(args.font_B)
tags_A = set(font_A.reader.keys())
tags_B = set(font_B.reader.keys())
if args.table_order:
sorted_tags_A = sorted_tags(font_A)
sorted_tags_B = sorted_tags(font_B)
sorted_tags_A.extend(" " for i in range(len(tags_B) - len(tags_A)))
sorted_tags_B.extend(" " for i in range(len(tags_A) - len(tags_B)))
assert len(sorted_tags_A) == len(sorted_tags_B)
print("font A font B table order")
print("------ ------")
for tag_A, tag_B in zip(sorted_tags_A, sorted_tags_B):
print(f" {tag_A} {tag_B}")
print()
if tags_A != tags_B:
only_in_A = tags_A - tags_B
only_in_B = tags_B - tags_A
if only_in_A:
print("Tables only in font A:")
print(textwrap.fill(", ".join(sorted(only_in_A)),
initial_indent=" ", subsequent_indent=" "))
print()
if only_in_B:
print("Tables only in font B:")
print(textwrap.fill(", ".join(sorted(only_in_B)),
initial_indent=" ", subsequent_indent=" "))
print()
common_tags = sorted(tags_A & tags_B)
max_length = 1
for tag in common_tags:
max_length = max(max_length, font_A.reader.tables[tag].length)
max_length = max(max_length, font_B.reader.tables[tag].length)
max_digits = len(str(max_length))
length_format = "{length:%dd}" % max_digits
filler = " " * (max_digits - 1)
did_print_header = False
same_tables = []
for tag in common_tags:
data_A = font_A.reader[tag]
data_B = font_B.reader[tag]
if data_A != data_B:
if not did_print_header:
print(f"Different tables:")
print(f" {filler}A {filler}B")
did_print_header = True
length_A = length_format.format(length=len(data_A))
length_B = length_format.format(length=len(data_B))
print(f" {tag} {length_A} {length_B} bytes")
else:
same_tables.append(tag)
if same_tables:
if did_print_header:
print()
if set(same_tables) == tags_A == tags_B:
print("Fonts are identical.")
else:
print("Identical tables:")
print(textwrap.fill(", ".join(same_tables),
initial_indent=" ", subsequent_indent=" "))
if __name__ == "__main__":
main()