-
Notifications
You must be signed in to change notification settings - Fork 1
/
ttf-to-textfont.py
executable file
·135 lines (104 loc) · 3.41 KB
/
ttf-to-textfont.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/python
import sys, getopt
import string
from PIL import ImageFont, ImageDraw
from itertools import chain
def find_max_height(font, glyphs):
max_height = 0
for g in glyphs:
bitmap = font.getmask(g, "1")
bbox = bitmap.getbbox()
if bbox != None:
x1, y1, x2, y2 = bbox
max_height = max(y2-y1, max_height)
return max_height
def find_max_width(font, glyphs):
max_width = 0
for g in glyphs:
bitmap = font.getmask(g, "1")
bbox = bitmap.getbbox()
if bbox != None:
x1, y1, x2, y2 = bbox
max_width = max(x2-x1, max_width)
return max_width
def print_character(font, glyph, max_height, alignments):
bitmap = font.getmask(glyph, "1")
bbox = bitmap.getbbox()
comment = "# " + glyph + " (ASCII: " + str(ord(glyph)) + ")"
if bbox == None:
print comment, "skipping empty glyph"
print
return
x1, y1, x2, y2 = bbox
pre = 0
post = 0
extra = max_height - (y2-y1)
if glyph in alignments["center"]:
comment += " (centered)"
post = extra / 2
pre = extra - post
elif glyph in alignments["top"]:
comment += " (align-top)"
post = extra
# Move one pixel down from the top if the glyph is really short
if post > (y2 - y1):
post -= 1
pre = 1
else:
comment += " (align-bot)"
pre = extra
#print comment
print "GLYPH: " + str(ord(glyph)) + " " + str(x2-x1) + " " + str(max_height) + " " + comment
for i in range(pre):
print "." * (x2-x1)
for y in range(y1, y2):
s = ""
for x in range(x1, x2):
if bitmap.getpixel((x,y)) > 0:
s += "X"
else:
s += "."
print s
for i in range(post):
print "." * (x2-x1)
def main(prog, argv):
vert_center = "~=%!#$()*+/<>@[]\{\}|"
vert_top = "^\"\'`"
font_points = 8
font_glyphs = string.printable
help = prog + '[-p <point-size>] [-g <glyphs-to-extract>] [-c <glyphs-to-center>] [-t <glyphs-to-align-top>] <fontfile>'
try:
opts, args = getopt.getopt(argv,"hg:p:c:t:")
except getopt.GetoptError:
print help
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print help
sys.exit()
elif opt == '-g':
font_glyphs = arg
elif opt == '-p':
font_points = int(arg)
elif opt == '-c':
vert_center = arg
elif opt == '-t':
vert_top = arg
if len(args) != 1:
print help
sys.exit(2)
font_file = args[0]
# Remove unprintable characters
exclude = set(chr(i) for i in chain(range(0, 31), range(128, 255)))
font_glyphs = ''.join(ch for ch in font_glyphs if ch not in exclude)
alignments = { "top": vert_top, "center": vert_center }
font = ImageFont.truetype(font_file, font_points)
max_height = find_max_height(font, font_glyphs)
max_width = find_max_height(font, font_glyphs)
print "# " + font_file + ", " + str(font_points) + " points, height " + str(max_height) + " px, widest " + str(max_width) + " px"
print "# Exporting: " + font_glyphs
print "FONT: " + str(max_width) + " " + str(max_height)
for glyph in font_glyphs:
print_character(font, glyph, max_height, alignments)
if __name__ == "__main__":
main(sys.argv[0], sys.argv[1:])