Skip to content

Commit a8e7db7

Browse files
committed
get AGD glyph names from the FDK’s own AGD.txt
1 parent fdd68b4 commit a8e7db7

File tree

1 file changed

+81
-15
lines changed

1 file changed

+81
-15
lines changed

goadbWriter.py

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
'''
44
GOADB writer -- write a GlyphOrderAndAliasDB file using a UFO as an input.
5-
Relies on the agl glyph names which come in fontTools’ agl module.
65
76
More reading on the GOADB format:
87
https://github.com/adobe-type-tools/afdko/issues/1662
@@ -13,8 +12,8 @@
1312

1413
import argparse
1514
import re
15+
from afdko import agd, fdkutils
1616
from pathlib import Path
17-
from fontTools import agl
1817
from defcon import Font, Glyph
1918

2019

@@ -56,6 +55,68 @@ def get_args(args=None):
5655
return parser.parse_args(args)
5756

5857

58+
def _load_agd_data():
59+
'''
60+
read and load the AGD.txt file
61+
'''
62+
agd_txt = Path(fdkutils.get_resources_dir()) / 'AGD.txt'
63+
64+
with open(agd_txt, "r") as agd_blob:
65+
agd_data = agd_blob.read()
66+
67+
# This object is called “dictionary”, but it doesn’t have dict methods.
68+
# However, it contains two dicts -- .glyphs and .unicode.
69+
return agd.dictionary(agd_data)
70+
71+
72+
def _make_agd_dict():
73+
'''
74+
AGD glyph name mapped to final name (often equivalent to the AGD name),
75+
and codepoint.
76+
77+
Mappings to private us codepoints (and mappings to esoteric final names)
78+
are deliberately omitted.
79+
'''
80+
agd_data = _load_agd_data()
81+
rx_uni_name = r'(?:u|uni)?([0-9A-F]{4,5}).*' # ?: is non-capturing
82+
agd_name_dict = {}
83+
84+
private_use = (
85+
set(range(0xe000, 0xf8ff + 1)) |
86+
set(range(0xf0000, 0xffffd + 1)) |
87+
set(range(0x100000, 0x10fffd + 1)))
88+
89+
for gname, agdglyph in agd_data.glyphs.items():
90+
if agdglyph.uni and not agdglyph.fin:
91+
gname_final = gname
92+
# The friendly name is equivalent to the final name.
93+
# makeotf will know which code point to assign
94+
# based on the name alone
95+
codepoint = int(agdglyph.uni, 16)
96+
# The AGD contains a number of private_use code points.
97+
# Those are outdated, we do not need to consider them.
98+
if codepoint not in private_use:
99+
agd_name_dict[gname] = gname_final, codepoint
100+
101+
elif agdglyph.uni and agdglyph.fin:
102+
gname_final = agdglyph.fin
103+
# makeotf knows that a specific name is associated with a certain
104+
# code point, but comparefamily complains about a “working name”
105+
# being assigned. This includes florin, for example.
106+
uni_match = re.match(rx_uni_name, agdglyph.fin)
107+
if uni_match:
108+
codepoint = int(uni_match.group(1), 16)
109+
if codepoint not in private_use:
110+
agd_name_dict[gname] = gname_final, codepoint
111+
112+
return agd_name_dict
113+
114+
115+
# inspired by
116+
# https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/agl.py#L5107
117+
AGD_DICT = _make_agd_dict()
118+
119+
59120
def get_glyph_order(f, include_template_glyphs=False):
60121
'''
61122
Figure out the glyph order.
@@ -114,7 +175,8 @@ def get_glyph_order(f, include_template_glyphs=False):
114175
# then by the order of related names of encoded glyphs.
115176
gnames_alternates = sorted(
116177
[g.name for g in glyphs_alternates],
117-
key=lambda gn: (gn.split('.')[1], gnames_encoded.index(gn.split('.')[0])))
178+
key=lambda gn:
179+
(gn.split('.')[1], gnames_encoded.index(gn.split('.')[0])))
118180

119181
# glyphs not related to encoded glyphs are sorted alphabetically
120182
glyphs_rest = [
@@ -126,10 +188,6 @@ def get_glyph_order(f, include_template_glyphs=False):
126188
return order
127189

128190

129-
def is_agl_name(input_name):
130-
return input_name in agl.AGL2UV.keys()
131-
132-
133191
def get_uni_name(cp):
134192
'''
135193
convert codepoint to uniXXXX (or uXXXXX) glyph name
@@ -175,7 +233,7 @@ def make_unique_final_name(gname):
175233

176234
def sanitize_final_name(gname):
177235
'''
178-
The following characters are allowed in friendly but not in final names:
236+
The following characters are allowed in friendly- but not final names:
179237
U+002A * asterisk
180238
U+002B + plus sign
181239
U+002D - hyphen-minus
@@ -253,27 +311,30 @@ def __init__(self, gn_friendly, g=None, gn_final=None, cp_override=None):
253311
# outside, and use this object for data storage only.
254312

255313
def assign_final_and_cp_override(self):
314+
is_agd_name = self.gn_friendly in AGD_DICT.keys()
256315
rx_uni_name = r'(?:u|uni)?([0-9A-F]{4,5}).*' # ?: is non-capturing
257316
uni_name_match = re.match(rx_uni_name, self.gn_friendly)
258317

259-
# glyph name is in AGL
260-
if is_agl_name(self.gn_friendly):
318+
# glyph name is in AGD
319+
if is_agd_name:
320+
agd_final, agd_cp = AGD_DICT.get(self.gn_friendly)
261321
if self.glyph.unicodes == []:
262322
# no codepoint assigned to glyph, codepoint will be assigned
263-
# through the glyph name only
264-
self.gn_final = self.gn_friendly
323+
# through the glyph name only (or, in some cases, the AGD
324+
# dict has a different final name)
325+
self.gn_final = agd_final
265326
elif len(self.glyph.unicodes) > 1:
266-
# glyph name is in AGL, but multiple code points attached;
327+
# glyph name is in AGD, but multiple code points attached;
267328
# override is needed
268329
self.gn_final = self.gn_friendly
269330
self.cp_override = get_uni_override(self.glyph.unicodes)
270331
else:
271332
# just one codepoint
272-
expected_codepoint = agl.AGL2UV.get(self.gn_friendly)
333+
expected_codepoint = agd_cp
273334
actual_codepoint = self.glyph.unicode
274335
if expected_codepoint == actual_codepoint:
275336
# codepoint is the expected one.
276-
self.gn_final = self.gn_friendly
337+
self.gn_final = agd_final
277338
else:
278339
# codepoint is different from what we expect
279340
self.gn_final = get_uni_name(self.glyph.unicode)
@@ -333,7 +394,12 @@ def fill_gn_dict(gb, glyph_name_dict):
333394

334395

335396
def get_glyph(f, gname):
397+
'''
398+
make sure a glyph object is present -- no matter if it exists in the UFO
399+
or not.
400+
'''
336401
try:
402+
# glyph exists in the UFO
337403
glyph = f[gname]
338404
except KeyError:
339405
# template glyph

0 commit comments

Comments
 (0)