forked from mozman/ezdxf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdraw_glyph_table.py
107 lines (95 loc) · 3.08 KB
/
draw_glyph_table.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
# Copyright (c) 2023, Manfred Moitzi
# License: MIT License
# https://en.wikipedia.org/wiki/Unicode_font
import sys
import argparse
import ezdxf
from ezdxf import path
from ezdxf.math import Matrix44
from ezdxf.fonts import fonts
from ezdxf.layouts import Layout
import pathlib
CWD = pathlib.Path("~/Desktop/Outbox").expanduser()
if not CWD.exists():
CWD = pathlib.Path(".")
CAP_HEIGHT = 2
SQUARE_SIZE = 6
GLYPH_OFFSET = 2
def render_glyph_table(font: fonts.TrueTypeFont, layout: Layout):
text_attribs = {
"layer": "TEXT",
"style": "TEXT",
"height": CAP_HEIGHT,
}
glyph_attribs = {
"layer": "GLYPH",
}
red_dot_attribs = {
"layer": "DOTS",
}
undef_path = font.text_path(chr(0))
undef_hash = hash(tuple(undef_path.control_vertices()))
half_height = CAP_HEIGHT / 2
for page in range(256):
insert_y = page * SQUARE_SIZE + GLYPH_OFFSET
_page = page << 8
label = f"{_page:04x}"
print(f"rendering page: {label}")
layout.add_text(label, dxfattribs=text_attribs).set_placement((-10, insert_y))
for code in range(256):
insert_x = SQUARE_SIZE * code + GLYPH_OFFSET
code_point = (page << 8) + code
glyph = font.text_path(chr(code_point))
if undef_hash == hash(tuple(glyph.control_vertices())):
layout.add_point(
(insert_x + half_height, insert_y + half_height),
dxfattribs=red_dot_attribs,
)
continue
m = Matrix44.translate(insert_x, insert_y, 0)
glyph.transform_inplace(m)
path.render_hatches(layout, [glyph.to_path()], dxfattribs=glyph_attribs)
def render_font(font_name: str, sideload: bool):
doc = ezdxf.new()
doc.layers.add("TEXT")
doc.layers.add("GLYPH")
doc.layers.add("DOTS", color=1)
doc.styles.add("TEXT", font="Arial.ttf")
msp = doc.modelspace()
if sideload:
font = fonts.sideload_ttf(font_name, CAP_HEIGHT)
else:
font = fonts.make_font(font_name, CAP_HEIGHT)
if font.name != font_name:
print(f"font '{font_name}' not found.")
exit(1)
render_glyph_table(font, msp) # type: ignore
size = 260 * SQUARE_SIZE
doc.set_modelspace_vport(size, center=(size / 2, size / 2))
out_name = pathlib.Path(font_name).name.replace('.', '_')
file_path = CWD / f"glyph_table_{out_name}.dxf"
print(f"writing: {file_path}")
doc.saveas(file_path)
print("done")
def main():
parser = argparse.ArgumentParser(
__file__,
)
parser.add_argument(
"files",
metavar="FILE",
nargs="+",
help="font file name to render",
)
parser.add_argument(
"-s",
"--sideload",
action="store_true",
default=False,
help="bypass the font manager and load a font straight from disk, requires an absolute file path",
)
args = parser.parse_args(sys.argv[1:])
for font_name in args.files:
render_font(font_name, args.sideload)
if __name__ == "__main__":
main()