Skip to content

Commit dd0e5f7

Browse files
authored
Merge pull request #12943 from anntzer/font_table
Update the font_table example.
2 parents a7f129c + 2a8ef8a commit dd0e5f7

File tree

2 files changed

+120
-66
lines changed

2 files changed

+120
-66
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""
2+
==========
3+
Font table
4+
==========
5+
6+
Matplotlib's font support is provided by the FreeType library.
7+
8+
Here, we use `~.Axes.table` to draw a table that shows the glyphs by Unicode
9+
codepoint. For brevity, the table only contains the first 256 glyphs.
10+
11+
The example is a full working script. You can download it and use it to
12+
investigate a font by running ::
13+
14+
python font_table.py /path/to/font/file
15+
"""
16+
17+
import unicodedata
18+
19+
import matplotlib.font_manager as fm
20+
from matplotlib.ft2font import FT2Font
21+
import matplotlib.pyplot as plt
22+
23+
24+
def print_glyphs(path):
25+
"""
26+
Print the all glyphs in the given font file to stdout.
27+
28+
Parameters
29+
----------
30+
path : str or None
31+
The path to the font file. If None, use Matplotlib's default font.
32+
"""
33+
if path is None:
34+
path = fm.findfont(fm.FontProperties()) # The default font.
35+
36+
font = FT2Font(path)
37+
38+
charmap = font.get_charmap()
39+
max_indices_len = len(str(max(charmap.values())))
40+
41+
print("The font face contains the following glyphs:")
42+
for char_code, glyph_index in charmap.items():
43+
char = chr(char_code)
44+
name = unicodedata.name(
45+
char,
46+
f"{char_code:#x} ({font.get_glyph_name(glyph_index)})")
47+
print(f"{glyph_index:>{max_indices_len}} {char} {name}")
48+
49+
50+
def draw_font_table(path):
51+
"""
52+
Draw a font table of the first 255 chars of the given font.
53+
54+
Parameters
55+
----------
56+
path : str or None
57+
The path to the font file. If None, use Matplotlib's default font.
58+
"""
59+
if path is None:
60+
path = fm.findfont(fm.FontProperties()) # The default font.
61+
62+
font = FT2Font(path)
63+
# A charmap is a mapping of "character codes" (in the sense of a character
64+
# encoding, e.g. latin-1) to glyph indices (i.e. the internal storage table
65+
# of the font face).
66+
# In FreeType>=2.1, a Unicode charmap (i.e. mapping Unicode codepoints)
67+
# is selected by default. Moreover, recent versions of FreeType will
68+
# automatically synthesize such a charmap if the font does not include one
69+
# (this behavior depends on the font format; for example it is present
70+
# since FreeType 2.0 for Type 1 fonts but only since FreeType 2.8 for
71+
# TrueType (actually, SFNT) fonts).
72+
# The code below (specifically, the ``chr(char_code)`` call) assumes that
73+
# we have indeed selected a Unicode charmap.
74+
codes = font.get_charmap().items()
75+
76+
labelc = ["{:X}".format(i) for i in range(16)]
77+
labelr = ["{:02X}".format(16 * i) for i in range(16)]
78+
chars = [["" for c in range(16)] for r in range(16)]
79+
80+
for char_code, glyph_index in codes:
81+
if char_code >= 256:
82+
continue
83+
row, col = divmod(char_code, 16)
84+
chars[row][col] = chr(char_code)
85+
86+
fig, ax = plt.subplots(figsize=(8, 4))
87+
ax.set_title(path)
88+
ax.set_axis_off()
89+
90+
table = ax.table(
91+
cellText=chars,
92+
rowLabels=labelr,
93+
colLabels=labelc,
94+
rowColours=["palegreen"] * 16,
95+
colColours=["palegreen"] * 16,
96+
cellColours=[[".95" for c in range(16)] for r in range(16)],
97+
cellLoc='center',
98+
loc='upper left',
99+
)
100+
for key, cell in table.get_celld().items():
101+
row, col = key
102+
if row > 0 and col > -1: # Beware of table's idiosyncratic indexing...
103+
cell.set_text_props(fontproperties=fm.FontProperties(fname=path))
104+
105+
fig.tight_layout()
106+
plt.show()
107+
108+
109+
if __name__ == "__main__":
110+
from argparse import ArgumentParser
111+
112+
parser = ArgumentParser(description="Display a font table.")
113+
parser.add_argument("path", nargs="?", help="Path to the font file.")
114+
parser.add_argument("--print-all", action="store_true",
115+
help="Additionally, print all chars to stdout.")
116+
args = parser.parse_args()
117+
118+
if args.print_all:
119+
print_glyphs(args.path)
120+
draw_font_table(args.path)

examples/text_labels_and_annotations/font_table_ttf_sgskip.py

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)