-
Notifications
You must be signed in to change notification settings - Fork 0
/
fontutils.py
82 lines (65 loc) · 2.22 KB
/
fontutils.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
import json
import os
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from fontTools.ttLib import TTFont
def get_all_words():
f = open('all_words.txt', 'r', encoding='utf-8')
lines = f.readlines()
f.close()
lines = [l.strip() for l in lines]
return ' '+''.join(lines)
word_set = set(get_all_words())
def get_all_font_chars():
"""
:return: font_chars_dict: dict{font_path:[visible chars]
"""
font_dir = os.path.join(os.path.dirname(__file__), 'fonts')
font_path_list = [os.path.join(font_dir, font_name)
for font_name in os.listdir(font_dir)]
font_list = [ImageFont.truetype(font_path, size=10) for font_path in font_path_list]
font_chars_dict = dict()
for font, font_path in zip(font_list, font_path_list):
font_chars = get_font_chars(font_path)
font_chars = [c.strip() for c in font_chars if len(c) == 1 and
word_set.__contains__(c) and
is_char_visible(font, c)] # 可见字符
font_chars = list(set(font_chars)) # 去重
font_chars.sort()
font_chars_dict[font_path] = font_chars
return font_chars_dict
def to_unicode(glyph):
return json.loads(f'"{glyph}"')
def get_font_chars(font_path):
font = TTFont(font_path, fontNumber=0)
glyph_names = font.getGlyphNames()
char_list = []
for idx, glyph in enumerate(glyph_names):
if glyph[0] == '.': # 跳过'.notdef', '.null'
continue
if glyph == 'union':
continue
if glyph[:3] == 'uni':
glyph = glyph.replace('uni', '\\u')
if glyph[:2] == 'uF':
glyph = glyph.replace('uF', '\\u')
if glyph == '\\uversal':
continue
char = to_unicode(glyph)
char_list.append(char)
return char_list
def is_char_visible(font, char):
"""
是否可见字符
:param font:
:param char:
:return:
"""
gray = Image.fromarray(np.zeros((20, 20), dtype=np.uint8))
draw = ImageDraw.Draw(gray)
draw.text((0, 0), char, 100, font=font)
visible = np.max(np.array(gray)) > 0
return visible
FONT_CHARS_DICT = get_all_font_chars()
if __name__ == '__main__':
print(FONT_CHARS_DICT)