Newer
Older
#!/usr/bin/env python
'''
Updates icon font and header files for CopyQ repository.
First argument is path to upacked Font Awesome archive (https://fontawesome.com/).
'''
import json
import os
import sys
from shutil import copyfile
from fontTools.merge import Merger
FONTS = [
'fa-solid-900.ttf',
'fa-brands-400.ttf',
FONT_FILENAME = 'fontawesome.ttf'
SOLID_STYLE = 'solid'
BRANDS_STYLE = 'brands'
def read_icons(icons_json):
with open(icons_json, 'r') as icons_file:
icons_content = icons_file.read()
return json.loads(icons_content)
def write_header_file_preamble(header_file):
script = os.path.realpath(__file__)
script_name = os.path.basename(script)
comment = (
f'// This file is generated with "{script_name}"'
+ ' from FontAwesome\'s metadata.\n\n')
header_file.write(comment)
def write_icon_list_header_file(header_icon_list, icons):
with open(header_icon_list, 'w') as header_file:
items = []
for style in [SOLID_STYLE, BRANDS_STYLE]:
is_brand = 'true' if style == BRANDS_STYLE else 'false'
for name, icon in icons.items():
if style in icon['styles']:
code = icon['unicode']
search_terms = [icon['label'].lower()] + (icon['search']['terms'] or [])
search_terms_list = '|'.join(search_terms)
items.append('{0x%s, %s, "%s"}' % (code, is_brand, search_terms_list))
item_list_content = ',\n'.join(items)
content = dedent('''\
struct Icon {
bool isBrand;
const char *searchTerms;
};
constexpr Icon iconList[] = {
%s
};
''') % item_list_content
write_header_file_preamble(header_file)
header_file.write(content)
def write_icons_header_file(header_icons, icons):
with open(header_icons, 'w') as header_file:
write_header_file_preamble(header_file)
header_file.write('#ifndef ICONS_H\n')
header_file.write('#define ICONS_H\n')
header_file.write('\n')
header_file.write('enum IconId {\n')
for name, icon in icons.items():
label = name.title().replace('-', '')
code = icon['unicode']
header_file.write(f' Icon{label} = 0x{code},' + '\n')
header_file.write('};\n')
header_file.write('\n')
header_file.write('#endif // ICONS_H\n')
def rename_font_family(path):
"""
Adds suffix to font family it doesn't conflict with font installed on
system, which could be in incorrect version.
See: https://github.com/fonttools/fonttools/blob/master/Snippets/rename-fonts.py
font = TTFont(path)
name_table = font['name']
FAMILY_RELATED_IDS = dict(
LEGACY_FAMILY=1,
TRUETYPE_UNIQUE_ID=3,
FULL_NAME=4,
POSTSCRIPT_NAME=6,
PREFERRED_FAMILY=16,
WWS_FAMILY=21,
)
for rec in name_table.names:
if rec.nameID not in FAMILY_RELATED_IDS.values():
continue
name = rec.toUnicode()
if name.startswith('Font Awesome'):
rec.string = name + ' (CopyQ)'
elif name.startswith('FontAwesome'):
rec.string = name + '(CopyQ)'
def copy_fonts(font_awesome_src, target_font_dir):
font_dir = os.path.join(font_awesome_src, 'webfonts')
fonts = [
os.path.join(font_dir, src_name)
for src_name in FONTS
]
dest_path = os.path.join(target_font_dir, FONT_FILENAME)
print(f'Merging fonts: {fonts} -> {dest_path}')
merger = Merger()
with merger.merge(fonts) as font:
font.save(dest_path)
rename_font_family(dest_path)
def main():
font_awesome_src = sys.argv[1]
script = os.path.realpath(__file__)
utils_dir = os.path.dirname(script)
project_dir = os.path.dirname(utils_dir)
src_dir = os.path.join(project_dir, 'src')
header_icon_list = os.path.join(src_dir, 'gui', 'icon_list.h')
header_icons = os.path.join(src_dir, 'gui', 'icons.h')
target_font_dir = os.path.join(src_dir, 'images')
copy_fonts(font_awesome_src, target_font_dir)
icons_json = os.path.join(
font_awesome_src, 'metadata', 'icons.json')
icons = read_icons(icons_json)
write_icon_list_header_file(header_icon_list, icons)
print(f'Header file "{header_icon_list}" updated.')