Skip to content

Commit 9840b8c

Browse files
committed
When updating repo dump out updated codepoint files
1 parent 4ea68aa commit 9840b8c

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

update/icons.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Utility to generate codepoint files for Google-style iconfonts."""
16+
17+
from fontTools import ttLib
18+
import functools
19+
from pathlib import Path
20+
21+
22+
_PUA_CODEPOINTS = [
23+
range(0xE000, 0xF8FF + 1),
24+
range(0xF0000, 0xFFFFD + 1),
25+
range(0x100000, 0x10FFFD + 1)
26+
]
27+
28+
29+
def _is_pua(codepoint):
30+
return any(r for r in _PUA_CODEPOINTS if codepoint in r)
31+
32+
33+
def _cmap(ttfont):
34+
35+
def _cmap_reducer(acc, u):
36+
acc.update(u)
37+
return acc
38+
39+
unicode_cmaps = (t.cmap for t in ttfont['cmap'].tables if t.isUnicode())
40+
return functools.reduce(_cmap_reducer, unicode_cmaps, {})
41+
42+
43+
def _ligatures(ttfont):
44+
liga_lookups = tuple(
45+
filter(lambda l: l.LookupType == 4,
46+
ttfont['GSUB'].table.LookupList.Lookup))
47+
for lookup in liga_lookups:
48+
for subtable in lookup.SubTable:
49+
yield subtable.ligatures
50+
51+
52+
def enumerate(font_file: Path):
53+
"""Yields (icon name, codepoint) tuples for icon font."""
54+
with ttLib.TTFont(font_file) as ttfont:
55+
cmap = _cmap(ttfont)
56+
rev_cmap = {v: k for k, v in cmap.items()}
57+
58+
for lig_root in _ligatures(ttfont):
59+
for first_glyph_name, ligatures in lig_root.items():
60+
for ligature in ligatures:
61+
glyph_names = (first_glyph_name,) + tuple(ligature.Component)
62+
icon_name = ''.join(chr(rev_cmap[n]) for n in glyph_names)
63+
codepoint = rev_cmap[ligature.LigGlyph]
64+
if not _is_pua(codepoint):
65+
continue
66+
yield (icon_name, codepoint)

update/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ black==19.10b0
55
certifi==2020.6.20
66
chardet==3.0.4
77
click==7.1.2
8+
fonttools==4.14.0
89
idna==2.10
910
pathspec==0.8.0
1011
regex==2020.7.14

update/update_repo.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
from absl import app
1818
from absl import flags
19+
import icons
1920
import json
2021
from pathlib import Path
2122
import re
@@ -179,6 +180,9 @@ def _fetch_fonts(css_files: Sequence[Path]):
179180
fetch = Fetch(url, css_file.parent / (css_file.stem + url[-4:]))
180181
_do_fetch(fetch)
181182
css_file.unlink()
183+
with open(fetch.dest_file.with_suffix(".codepoints"), "w") as f:
184+
for name, codepoint in sorted(icons.enumerate(fetch.dest_file)):
185+
f.write(f"{name} {codepoint:04x}\n")
182186

183187

184188
def _is_css(p: Path):

0 commit comments

Comments
 (0)