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 )
0 commit comments