-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
ttf.py
executable file
·101 lines (82 loc) · 3.63 KB
/
ttf.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
#!/usr/bin/env python
"""A TrueType Font example using the FreeType library.
You will need to get this external library from PyPI:
pip install freetype-py
"""
# To the extent possible under law, the libtcod maintainers have waived all
# copyright and related or neighboring rights to this example script.
# https://creativecommons.org/publicdomain/zero/1.0/
from typing import Tuple
import freetype # type: ignore # pip install freetype-py
import numpy as np
from numpy.typing import NDArray
import tcod.console
import tcod.context
import tcod.event
import tcod.tileset
FONT = "VeraMono.ttf"
def load_ttf(path: str, size: Tuple[int, int]) -> tcod.tileset.Tileset:
"""Load a TTF file and return a tcod Tileset.
`path` is the file path to the font, this can be any font supported by the
FreeType library.
`size` is the (width, height) of the Tileset in pixels.
Feel free to use this function in your own code.
"""
ttf = freetype.Face(path)
ttf.set_pixel_sizes(*size)
tileset = tcod.tileset.Tileset(*size)
for codepoint, glyph_index in ttf.get_chars():
# Add every glyph to the Tileset.
ttf.load_glyph(glyph_index)
bitmap = ttf.glyph.bitmap
assert bitmap.pixel_mode == freetype.FT_PIXEL_MODE_GRAY
bitmap_array: NDArray[np.uint8] = np.asarray(bitmap.buffer).reshape((bitmap.width, bitmap.rows), order="F")
if bitmap_array.size == 0:
continue # Skip blank glyphs.
output_image: NDArray[np.uint8] = np.zeros(size, dtype=np.uint8, order="F")
out_slice = output_image
# Adjust the position to center this glyph on the tile.
left = (size[0] - bitmap.width) // 2
top = size[1] - ttf.glyph.bitmap_top + ttf.size.descender // 64
# `max` is used because I was too lazy to properly slice the array.
out_slice = out_slice[max(0, left) :, max(0, top) :]
out_slice[: bitmap_array.shape[0], : bitmap_array.shape[1]] = bitmap_array[
: out_slice.shape[0], : out_slice.shape[1]
]
tileset.set_tile(codepoint, output_image.transpose())
return tileset
def main() -> None:
"""True-type font example script."""
console = tcod.console.Console(16, 12, order="F")
with tcod.context.new(
columns=console.width,
rows=console.height,
tileset=load_ttf(FONT, (24, 24)),
) as context:
while True:
console.clear()
# Draw checkerboard.
console.tiles_rgb["bg"][::2, ::2] = 0x20
console.tiles_rgb["bg"][1::2, 1::2] = 0x20
# Print ASCII characters.
console.tiles_rgb["ch"][:16, :6] = np.arange(0x20, 0x80).reshape(0x10, -1, order="F")
console.print(0, 7, "Example text.")
context.present(console, integer_scaling=True)
for event in tcod.event.wait():
if isinstance(event, tcod.event.Quit):
raise SystemExit()
if isinstance(event, tcod.event.WindowResized) and event.type == "WindowSizeChanged":
# Resize the Tileset to match the new screen size.
context.change_tileset(
load_ttf(
path=FONT,
size=(
event.width // console.width,
event.height // console.height,
),
)
)
if __name__ == "__main__":
tcod_version = tuple(int(n) for n in tcod.__version__.split(".") if n.isdigit())
assert tcod_version[:2] >= (12, 1), "Must be using tcod 12.1 or later."
main()