mirror of
https://github.com/daylinmorgan/monolisa-nerdfont-patch.git
synced 2024-12-22 06:50:44 -06:00
update NF batteries
This commit is contained in:
parent
51a57bbbfa
commit
86020c4474
2 changed files with 107 additions and 54 deletions
161
bin/font-patcher
161
bin/font-patcher
|
@ -1,23 +1,19 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# coding=utf8
|
# coding=utf8
|
||||||
# Nerd Fonts Version: 2.2.1
|
# Nerd Fonts Version: 2.2.2
|
||||||
# Script version is further down
|
# Script version is further down
|
||||||
|
|
||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
# Change the script version when you edit this script:
|
# Change the script version when you edit this script:
|
||||||
script_version = "3.0.3"
|
script_version = "3.0.6"
|
||||||
|
|
||||||
version = "2.2.1"
|
version = "2.2.2"
|
||||||
projectName = "Nerd Fonts"
|
projectName = "Nerd Fonts"
|
||||||
projectNameAbbreviation = "NF"
|
projectNameAbbreviation = "NF"
|
||||||
projectNameSingular = projectName[:-1]
|
projectNameSingular = projectName[:-1]
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
try:
|
|
||||||
import psMat
|
|
||||||
except ImportError:
|
|
||||||
sys.exit(projectName + ": FontForge module is probably not installed. [See: http://designwithfontforge.com/en-US/Installing_Fontforge.html]")
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
|
@ -30,12 +26,13 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit(projectName + ": configparser module is probably not installed. Try `pip install configparser` or equivalent")
|
sys.exit(projectName + ": configparser module is probably not installed. Try `pip install configparser` or equivalent")
|
||||||
try:
|
try:
|
||||||
|
import psMat
|
||||||
import fontforge
|
import fontforge
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit(
|
sys.exit(
|
||||||
projectName + (
|
projectName + (
|
||||||
": FontForge module could not be loaded. Try installing fontforge python bindings "
|
": FontForge module could not be loaded. Try installing fontforge python bindings "
|
||||||
"[e.g. on Linux Debian or Ubuntu: `sudo apt install fontforge python-fontforge`]"
|
"[e.g. on Linux Debian or Ubuntu: `sudo apt install fontforge python3-fontforge`]"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -167,6 +164,7 @@ class font_patcher:
|
||||||
self.font_dim = None # class 'dict'
|
self.font_dim = None # class 'dict'
|
||||||
self.onlybitmaps = 0
|
self.onlybitmaps = 0
|
||||||
self.extension = ""
|
self.extension = ""
|
||||||
|
self.essential = set()
|
||||||
self.setup_arguments()
|
self.setup_arguments()
|
||||||
self.config = configparser.ConfigParser(empty_lines_in_values=False, allow_no_value=True)
|
self.config = configparser.ConfigParser(empty_lines_in_values=False, allow_no_value=True)
|
||||||
if not os.path.isfile(self.args.font):
|
if not os.path.isfile(self.args.font):
|
||||||
|
@ -181,6 +179,7 @@ class font_patcher:
|
||||||
except Exception:
|
except Exception:
|
||||||
sys.exit(projectName + ": Can not open font, try to open with fontforge interactively to get more information")
|
sys.exit(projectName + ": Can not open font, try to open with fontforge interactively to get more information")
|
||||||
self.setup_version()
|
self.setup_version()
|
||||||
|
self.get_essential_references()
|
||||||
self.setup_name_backup()
|
self.setup_name_backup()
|
||||||
self.remove_ligatures()
|
self.remove_ligatures()
|
||||||
make_sure_path_exists(self.args.outputdir)
|
make_sure_path_exists(self.args.outputdir)
|
||||||
|
@ -219,6 +218,10 @@ class font_patcher:
|
||||||
PreviousSymbolFilename = ""
|
PreviousSymbolFilename = ""
|
||||||
symfont = None
|
symfont = None
|
||||||
|
|
||||||
|
if not os.path.isdir(self.args.glyphdir):
|
||||||
|
sys.exit("{}: Can not find symbol glyph directory {} "
|
||||||
|
"(probably you need to download the src/glyphs/ directory?)".format(projectName, self.args.glyphdir))
|
||||||
|
|
||||||
for patch in self.patch_set:
|
for patch in self.patch_set:
|
||||||
if patch['Enabled']:
|
if patch['Enabled']:
|
||||||
if PreviousSymbolFilename != patch['Filename']:
|
if PreviousSymbolFilename != patch['Filename']:
|
||||||
|
@ -226,7 +229,13 @@ class font_patcher:
|
||||||
if symfont:
|
if symfont:
|
||||||
symfont.close()
|
symfont.close()
|
||||||
symfont = None
|
symfont = None
|
||||||
symfont = fontforge.open(self.args.glyphdir + patch['Filename'])
|
if not os.path.isfile(self.args.glyphdir + patch['Filename']):
|
||||||
|
sys.exit("{}: Can not find symbol source for '{}'\n{:>{}} (i.e. {})".format(
|
||||||
|
projectName, patch['Name'], '', len(projectName), self.args.glyphdir + patch['Filename']))
|
||||||
|
if not os.access(self.args.glyphdir + patch['Filename'], os.R_OK):
|
||||||
|
sys.exit("{}: Can not open symbol source for '{}'\n{:>{}} (i.e. {})".format(
|
||||||
|
projectName, patch['Name'], '', len(projectName), self.args.glyphdir + patch['Filename']))
|
||||||
|
symfont = fontforge.open(os.path.join(self.args.glyphdir, patch['Filename']))
|
||||||
|
|
||||||
# Match the symbol font size to the source font size
|
# Match the symbol font size to the source font size
|
||||||
symfont.em = self.sourceFont.em
|
symfont.em = self.sourceFont.em
|
||||||
|
@ -320,6 +329,7 @@ class font_patcher:
|
||||||
parser.add_argument('-out', '--outputdir', dest='outputdir', default=".", type=str, nargs='?', help='The directory to output the patched font file to')
|
parser.add_argument('-out', '--outputdir', dest='outputdir', default=".", type=str, nargs='?', help='The directory to output the patched font file to')
|
||||||
parser.add_argument('--glyphdir', dest='glyphdir', default=__dir__ + "/src/glyphs/", type=str, nargs='?', help='Path to glyphs to be used for patching')
|
parser.add_argument('--glyphdir', dest='glyphdir', default=__dir__ + "/src/glyphs/", type=str, nargs='?', help='Path to glyphs to be used for patching')
|
||||||
parser.add_argument('--makegroups', dest='makegroups', default=False, action='store_true', help='Use alternative method to name patched fonts (experimental)')
|
parser.add_argument('--makegroups', dest='makegroups', default=False, action='store_true', help='Use alternative method to name patched fonts (experimental)')
|
||||||
|
parser.add_argument('--variable-width-glyphs', dest='nonmono', default=False, action='store_true', help='Do not adjust advance width (no "overhang")')
|
||||||
|
|
||||||
# progress bar arguments - https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse
|
# progress bar arguments - https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse
|
||||||
progressbars_group_parser = parser.add_mutually_exclusive_group(required=False)
|
progressbars_group_parser = parser.add_mutually_exclusive_group(required=False)
|
||||||
|
@ -332,7 +342,7 @@ class font_patcher:
|
||||||
sym_font_group = parser.add_argument_group('Symbol Fonts')
|
sym_font_group = parser.add_argument_group('Symbol Fonts')
|
||||||
sym_font_group.add_argument('--fontawesome', dest='fontawesome', default=False, action='store_true', help='Add Font Awesome Glyphs (http://fontawesome.io/)')
|
sym_font_group.add_argument('--fontawesome', dest='fontawesome', default=False, action='store_true', help='Add Font Awesome Glyphs (http://fontawesome.io/)')
|
||||||
sym_font_group.add_argument('--fontawesomeextension', dest='fontawesomeextension', default=False, action='store_true', help='Add Font Awesome Extension Glyphs (https://andrelzgava.github.io/font-awesome-extension/)')
|
sym_font_group.add_argument('--fontawesomeextension', dest='fontawesomeextension', default=False, action='store_true', help='Add Font Awesome Extension Glyphs (https://andrelzgava.github.io/font-awesome-extension/)')
|
||||||
sym_font_group.add_argument('--fontlinux', '--fontlogos', dest='fontlinux', default=False, action='store_true', help='Add Font Linux and other open source Glyphs (https://github.com/Lukas-W/font-logos)')
|
sym_font_group.add_argument('--fontlogos', '--fontlinux', dest='fontlogos', default=False, action='store_true', help='Add Font Logos Glyphs (https://github.com/Lukas-W/font-logos)')
|
||||||
sym_font_group.add_argument('--octicons', dest='octicons', default=False, action='store_true', help='Add Octicons Glyphs (https://octicons.github.com)')
|
sym_font_group.add_argument('--octicons', dest='octicons', default=False, action='store_true', help='Add Octicons Glyphs (https://octicons.github.com)')
|
||||||
sym_font_group.add_argument('--codicons', dest='codicons', default=False, action='store_true', help='Add Codicons Glyphs (https://github.com/microsoft/vscode-codicons)')
|
sym_font_group.add_argument('--codicons', dest='codicons', default=False, action='store_true', help='Add Codicons Glyphs (https://github.com/microsoft/vscode-codicons)')
|
||||||
sym_font_group.add_argument('--powersymbols', dest='powersymbols', default=False, action='store_true', help='Add IEC Power Symbols (https://unicodepowersymbol.com/)')
|
sym_font_group.add_argument('--powersymbols', dest='powersymbols', default=False, action='store_true', help='Add IEC Power Symbols (https://unicodepowersymbol.com/)')
|
||||||
|
@ -351,7 +361,7 @@ class font_patcher:
|
||||||
if self.args.complete:
|
if self.args.complete:
|
||||||
self.args.fontawesome = True
|
self.args.fontawesome = True
|
||||||
self.args.fontawesomeextension = True
|
self.args.fontawesomeextension = True
|
||||||
self.args.fontlinux = True
|
self.args.fontlogos = True
|
||||||
self.args.octicons = True
|
self.args.octicons = True
|
||||||
self.args.codicons = True
|
self.args.codicons = True
|
||||||
self.args.powersymbols = True
|
self.args.powersymbols = True
|
||||||
|
@ -380,6 +390,10 @@ class font_patcher:
|
||||||
if self.args.alsowindows:
|
if self.args.alsowindows:
|
||||||
self.args.windows = False
|
self.args.windows = False
|
||||||
|
|
||||||
|
if self.args.nonmono and self.args.single:
|
||||||
|
print("Warniung: Specified contradicting --variable-width-glyphs and --use-single-width-glyph. Ignoring --variable-width-glyphs.")
|
||||||
|
self.args.nonmono = False
|
||||||
|
|
||||||
# this one also works but it needs to be updated every time a font is added
|
# this one also works but it needs to be updated every time a font is added
|
||||||
# it was a conditional in self.setup_font_names() before, but it was missing
|
# it was a conditional in self.setup_font_names() before, but it was missing
|
||||||
# a symbol font, so it would name the font complete without being so sometimes.
|
# a symbol font, so it would name the font complete without being so sometimes.
|
||||||
|
@ -389,7 +403,7 @@ class font_patcher:
|
||||||
# self.args.complete = all([
|
# self.args.complete = all([
|
||||||
# self.args.fontawesome is True,
|
# self.args.fontawesome is True,
|
||||||
# self.args.fontawesomeextension is True,
|
# self.args.fontawesomeextension is True,
|
||||||
# self.args.fontlinux is True,
|
# self.args.fontlogos is True,
|
||||||
# self.args.octicons is True,
|
# self.args.octicons is True,
|
||||||
# self.args.powersymbols is True,
|
# self.args.powersymbols is True,
|
||||||
# self.args.pomicons is True,
|
# self.args.pomicons is True,
|
||||||
|
@ -436,9 +450,9 @@ class font_patcher:
|
||||||
if self.args.pomicons:
|
if self.args.pomicons:
|
||||||
additionalFontNameSuffix += " P"
|
additionalFontNameSuffix += " P"
|
||||||
verboseAdditionalFontNameSuffix += " Plus Pomicons"
|
verboseAdditionalFontNameSuffix += " Plus Pomicons"
|
||||||
if self.args.fontlinux:
|
if self.args.fontlogos:
|
||||||
additionalFontNameSuffix += " L"
|
additionalFontNameSuffix += " L"
|
||||||
verboseAdditionalFontNameSuffix += " Plus Font Logos (Font Linux)"
|
verboseAdditionalFontNameSuffix += " Plus Font Logos"
|
||||||
if self.args.material:
|
if self.args.material:
|
||||||
additionalFontNameSuffix += " MDI"
|
additionalFontNameSuffix += " MDI"
|
||||||
verboseAdditionalFontNameSuffix += " Plus Material Design Icons"
|
verboseAdditionalFontNameSuffix += " Plus Material Design Icons"
|
||||||
|
@ -522,6 +536,8 @@ class font_patcher:
|
||||||
maxFamilyLength = 31
|
maxFamilyLength = 31
|
||||||
maxFontLength = maxFamilyLength - len('-' + subFamily)
|
maxFontLength = maxFamilyLength - len('-' + subFamily)
|
||||||
familyname += " " + projectNameAbbreviation
|
familyname += " " + projectNameAbbreviation
|
||||||
|
if self.args.single:
|
||||||
|
familyname += "M"
|
||||||
fullname += " Windows Compatible"
|
fullname += " Windows Compatible"
|
||||||
|
|
||||||
# now make sure less than 32 characters name length
|
# now make sure less than 32 characters name length
|
||||||
|
@ -673,7 +689,7 @@ class font_patcher:
|
||||||
# Supported params: overlap | careful
|
# Supported params: overlap | careful
|
||||||
# Powerline dividers
|
# Powerline dividers
|
||||||
SYM_ATTR_POWERLINE = {
|
SYM_ATTR_POWERLINE = {
|
||||||
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': ''},
|
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}},
|
||||||
|
|
||||||
# Arrow tips
|
# Arrow tips
|
||||||
0xe0b0: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
|
0xe0b0: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
|
||||||
|
@ -706,23 +722,23 @@ class font_patcher:
|
||||||
0xe0c3: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.01}},
|
0xe0c3: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.01}},
|
||||||
|
|
||||||
# Small squares
|
# Small squares
|
||||||
0xe0c4: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0c4: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
0xe0c5: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0c5: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
|
|
||||||
# Bigger squares
|
# Bigger squares
|
||||||
0xe0c6: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0c6: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
0xe0c7: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0c7: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
|
|
||||||
# Waveform
|
# Waveform
|
||||||
0xe0c8: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.01}},
|
0xe0c8: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.01}},
|
||||||
|
|
||||||
# Hexagons
|
# Hexagons
|
||||||
0xe0cc: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0cc: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
0xe0cd: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0cd: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
|
|
||||||
# Legos
|
# Legos
|
||||||
0xe0ce: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0ce: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
0xe0cf: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
0xe0cf: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||||
0xe0d1: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
|
0xe0d1: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
|
||||||
|
|
||||||
# Top and bottom trapezoid
|
# Top and bottom trapezoid
|
||||||
|
@ -732,22 +748,22 @@ class font_patcher:
|
||||||
|
|
||||||
SYM_ATTR_DEFAULT = {
|
SYM_ATTR_DEFAULT = {
|
||||||
# 'pa' == preserve aspect ratio
|
# 'pa' == preserve aspect ratio
|
||||||
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': ''}
|
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}}
|
||||||
}
|
}
|
||||||
|
|
||||||
SYM_ATTR_FONTA = {
|
SYM_ATTR_FONTA = {
|
||||||
# 'pa' == preserve aspect ratio
|
# 'pa' == preserve aspect ratio
|
||||||
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': ''},
|
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}},
|
||||||
|
|
||||||
# Don't center these arrows vertically
|
# Don't center these arrows vertically
|
||||||
0xf0dc: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': ''},
|
0xf0dc: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': {}},
|
||||||
0xf0dd: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': ''},
|
0xf0dd: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': {}},
|
||||||
0xf0de: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': ''}
|
0xf0de: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': {}}
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_ATTR = {
|
CUSTOM_ATTR = {
|
||||||
# 'pa' == preserve aspect ratio
|
# 'pa' == preserve aspect ratio
|
||||||
'default': {'align': 'c', 'valign': '', 'stretch': '', 'params': ''}
|
'default': {'align': 'c', 'valign': '', 'stretch': '', 'params': {}}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Most glyphs we want to maximize during the scale. However, there are some
|
# Most glyphs we want to maximize during the scale. However, there are some
|
||||||
|
@ -789,7 +805,7 @@ class font_patcher:
|
||||||
# Define the character ranges
|
# Define the character ranges
|
||||||
# Symbol font ranges
|
# Symbol font ranges
|
||||||
self.patch_set = [
|
self.patch_set = [
|
||||||
{'Enabled': True, 'Name': "Seti-UI + Custom", 'Filename': "original-source.otf", 'Exact': False, 'SymStart': 0xE4FA, 'SymEnd': 0xE531, 'SrcStart': 0xE5FA, 'SrcEnd': 0xE631, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
{'Enabled': True, 'Name': "Seti-UI + Custom", 'Filename': "original-source.otf", 'Exact': False, 'SymStart': 0xE4FA, 'SymEnd': 0xE534, 'SrcStart': 0xE5FA, 'SrcEnd': 0xE634, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
||||||
{'Enabled': True, 'Name': "Devicons", 'Filename': "devicons.ttf", 'Exact': False, 'SymStart': 0xE600, 'SymEnd': 0xE6C5, 'SrcStart': 0xE700, 'SrcEnd': 0xE7C5, 'ScaleGlyph': DEVI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT},
|
{'Enabled': True, 'Name': "Devicons", 'Filename': "devicons.ttf", 'Exact': False, 'SymStart': 0xE600, 'SymEnd': 0xE6C5, 'SrcStart': 0xE700, 'SrcEnd': 0xE7C5, 'ScaleGlyph': DEVI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT},
|
||||||
{'Enabled': self.args.powerline, 'Name': "Powerline Symbols", 'Filename': "powerline-symbols/PowerlineSymbols.otf", 'Exact': True, 'SymStart': 0xE0A0, 'SymEnd': 0xE0A2, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_POWERLINE},
|
{'Enabled': self.args.powerline, 'Name': "Powerline Symbols", 'Filename': "powerline-symbols/PowerlineSymbols.otf", 'Exact': True, 'SymStart': 0xE0A0, 'SymEnd': 0xE0A2, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_POWERLINE},
|
||||||
{'Enabled': self.args.powerline, 'Name': "Powerline Symbols", 'Filename': "powerline-symbols/PowerlineSymbols.otf", 'Exact': True, 'SymStart': 0xE0B0, 'SymEnd': 0xE0B3, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_POWERLINE},
|
{'Enabled': self.args.powerline, 'Name': "Powerline Symbols", 'Filename': "powerline-symbols/PowerlineSymbols.otf", 'Exact': True, 'SymStart': 0xE0B0, 'SymEnd': 0xE0B3, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_POWERLINE},
|
||||||
|
@ -804,7 +820,7 @@ class font_patcher:
|
||||||
{'Enabled': self.args.powersymbols, 'Name': "Power Symbols", 'Filename': "Unicode_IEC_symbol_font.otf", 'Exact': True, 'SymStart': 0x2B58, 'SymEnd': 0x2B58, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT}, # Heavy Circle (aka Power Off)
|
{'Enabled': self.args.powersymbols, 'Name': "Power Symbols", 'Filename': "Unicode_IEC_symbol_font.otf", 'Exact': True, 'SymStart': 0x2B58, 'SymEnd': 0x2B58, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT}, # Heavy Circle (aka Power Off)
|
||||||
{'Enabled': self.args.material, 'Name': "Material", 'Filename': "materialdesignicons-webfont.ttf", 'Exact': False, 'SymStart': 0xF001, 'SymEnd': 0xF847, 'SrcStart': 0xF500, 'SrcEnd': 0xFD46, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
{'Enabled': self.args.material, 'Name': "Material", 'Filename': "materialdesignicons-webfont.ttf", 'Exact': False, 'SymStart': 0xF001, 'SymEnd': 0xF847, 'SrcStart': 0xF500, 'SrcEnd': 0xFD46, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
||||||
{'Enabled': self.args.weather, 'Name': "Weather Icons", 'Filename': "weather-icons/weathericons-regular-webfont.ttf", 'Exact': False, 'SymStart': 0xF000, 'SymEnd': 0xF0EB, 'SrcStart': 0xE300, 'SrcEnd': 0xE3EB, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
{'Enabled': self.args.weather, 'Name': "Weather Icons", 'Filename': "weather-icons/weathericons-regular-webfont.ttf", 'Exact': False, 'SymStart': 0xF000, 'SymEnd': 0xF0EB, 'SrcStart': 0xE300, 'SrcEnd': 0xE3EB, 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
||||||
{'Enabled': self.args.fontlinux, 'Name': "Font Logos (Font Linux)", 'Filename': "font-logos.ttf", 'Exact': True, 'SymStart': 0xF300, 'SymEnd': 0xF32F, 'SrcStart': None, 'SrcEnd': None , 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
{'Enabled': self.args.fontlogos, 'Name': "Font Logos", 'Filename': "font-logos.ttf", 'Exact': True, 'SymStart': 0xF300, 'SymEnd': 0xF32F, 'SrcStart': None, 'SrcEnd': None , 'ScaleGlyph': None, 'Attributes': SYM_ATTR_DEFAULT},
|
||||||
{'Enabled': self.args.octicons, 'Name': "Octicons", 'Filename': "octicons.ttf", 'Exact': self.octiconsExactEncodingPosition, 'SymStart': 0xF000, 'SymEnd': 0xF105, 'SrcStart': 0xF400, 'SrcEnd': 0xF505, 'ScaleGlyph': OCTI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT}, # Magnifying glass
|
{'Enabled': self.args.octicons, 'Name': "Octicons", 'Filename': "octicons.ttf", 'Exact': self.octiconsExactEncodingPosition, 'SymStart': 0xF000, 'SymEnd': 0xF105, 'SrcStart': 0xF400, 'SrcEnd': 0xF505, 'ScaleGlyph': OCTI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT}, # Magnifying glass
|
||||||
{'Enabled': self.args.octicons, 'Name': "Octicons", 'Filename': "octicons.ttf", 'Exact': self.octiconsExactEncodingPosition, 'SymStart': 0x2665, 'SymEnd': 0x2665, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': OCTI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT}, # Heart
|
{'Enabled': self.args.octicons, 'Name': "Octicons", 'Filename': "octicons.ttf", 'Exact': self.octiconsExactEncodingPosition, 'SymStart': 0x2665, 'SymEnd': 0x2665, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': OCTI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT}, # Heart
|
||||||
{'Enabled': self.args.octicons, 'Name': "Octicons", 'Filename': "octicons.ttf", 'Exact': self.octiconsExactEncodingPosition, 'SymStart': 0X26A1, 'SymEnd': 0X26A1, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': OCTI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT}, # Zap
|
{'Enabled': self.args.octicons, 'Name': "Octicons", 'Filename': "octicons.ttf", 'Exact': self.octiconsExactEncodingPosition, 'SymStart': 0X26A1, 'SymEnd': 0X26A1, 'SrcStart': None, 'SrcEnd': None, 'ScaleGlyph': OCTI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT}, # Zap
|
||||||
|
@ -835,6 +851,17 @@ class font_patcher:
|
||||||
self.sourceFont.hhea_linegap = 0
|
self.sourceFont.hhea_linegap = 0
|
||||||
self.sourceFont.os2_typolinegap = 0
|
self.sourceFont.os2_typolinegap = 0
|
||||||
|
|
||||||
|
def get_essential_references(self):
|
||||||
|
"""Find glyphs that are needed for the basic glyphs"""
|
||||||
|
# Sometimes basic glyphs are constructed from multiple other glyphs.
|
||||||
|
# Find out which other glyphs are also needed to keep the basic
|
||||||
|
# glyphs intact.
|
||||||
|
# 0x00-0x17f is the Latin Extended-A range
|
||||||
|
for glyph in range(0x21, 0x17f):
|
||||||
|
if not glyph in self.sourceFont:
|
||||||
|
continue
|
||||||
|
for r in self.sourceFont[glyph].references:
|
||||||
|
self.essential.add(self.sourceFont[r[0]].unicode)
|
||||||
|
|
||||||
def get_sourcefont_dimensions(self):
|
def get_sourcefont_dimensions(self):
|
||||||
# Initial font dimensions
|
# Initial font dimensions
|
||||||
|
@ -886,10 +913,7 @@ class font_patcher:
|
||||||
|
|
||||||
# We want to preserve x/y aspect ratio, so find biggest scale factor that allows symbol to fit
|
# We want to preserve x/y aspect ratio, so find biggest scale factor that allows symbol to fit
|
||||||
scale_ratio_x = self.font_dim['width'] / sym_dim['width']
|
scale_ratio_x = self.font_dim['width'] / sym_dim['width']
|
||||||
|
scale_ratio_y = self.font_dim['height'] / sym_dim['height']
|
||||||
# font_dim['height'] represents total line height, keep our symbols sized based upon font's em
|
|
||||||
# NOTE: is this comment correct? font_dim['height'] isn't used here
|
|
||||||
scale_ratio_y = self.sourceFont.em / sym_dim['height']
|
|
||||||
if scale_ratio_x > scale_ratio_y:
|
if scale_ratio_x > scale_ratio_y:
|
||||||
scale_ratio = scale_ratio_y
|
scale_ratio = scale_ratio_y
|
||||||
else:
|
else:
|
||||||
|
@ -927,6 +951,8 @@ class font_patcher:
|
||||||
if self.args.quiet is False:
|
if self.args.quiet is False:
|
||||||
sys.stdout.write("Adding " + str(max(1, glyphSetLength)) + " Glyphs from " + setName + " Set \n")
|
sys.stdout.write("Adding " + str(max(1, glyphSetLength)) + " Glyphs from " + setName + " Set \n")
|
||||||
|
|
||||||
|
currentSourceFontGlyph = -1 # initialize for the exactEncoding case
|
||||||
|
|
||||||
for index, sym_glyph in enumerate(symbolFontSelection):
|
for index, sym_glyph in enumerate(symbolFontSelection):
|
||||||
index = max(1, index)
|
index = max(1, index)
|
||||||
|
|
||||||
|
@ -936,8 +962,17 @@ class font_patcher:
|
||||||
sym_attr = attributes['default']
|
sym_attr = attributes['default']
|
||||||
|
|
||||||
if exactEncoding:
|
if exactEncoding:
|
||||||
# use the exact same hex values for the source font as for the symbol font
|
# Use the exact same hex values for the source font as for the symbol font.
|
||||||
currentSourceFontGlyph = sym_glyph.encoding
|
# Problem is we do not know the codepoint of the sym_glyph and because it
|
||||||
|
# came from a selection.byGlyphs there might be skipped over glyphs.
|
||||||
|
# The iteration is still in the order of the selection by codepoint,
|
||||||
|
# so we take the next allowed codepoint of the current glyph
|
||||||
|
possible_codes = [ ]
|
||||||
|
if sym_glyph.unicode > currentSourceFontGlyph:
|
||||||
|
possible_codes += [ sym_glyph.unicode ]
|
||||||
|
if sym_glyph.altuni:
|
||||||
|
possible_codes += [ v for v, s, r in sym_glyph.altuni if v > currentSourceFontGlyph ]
|
||||||
|
currentSourceFontGlyph = min(possible_codes)
|
||||||
else:
|
else:
|
||||||
# use source font defined hex values based on passed in start and end
|
# use source font defined hex values based on passed in start and end
|
||||||
currentSourceFontGlyph = sourceFontList[sourceFontCounter]
|
currentSourceFontGlyph = sourceFontList[sourceFontCounter]
|
||||||
|
@ -952,10 +987,11 @@ class font_patcher:
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
# check if a glyph already exists in this location
|
# check if a glyph already exists in this location
|
||||||
if careful or 'careful' in sym_attr['params']:
|
if careful or 'careful' in sym_attr['params'] or currentSourceFontGlyph in self.essential:
|
||||||
if currentSourceFontGlyph in self.sourceFont:
|
if currentSourceFontGlyph in self.sourceFont:
|
||||||
if self.args.quiet is False:
|
if self.args.quiet is False:
|
||||||
print(" Found existing Glyph at {:X}. Skipping...".format(currentSourceFontGlyph))
|
careful_type = 'essential' if currentSourceFontGlyph in self.essential else 'existing'
|
||||||
|
print(" Found {} Glyph at {:X}. Skipping...".format(careful_type, currentSourceFontGlyph))
|
||||||
# We don't want to touch anything so move to next Glyph
|
# We don't want to touch anything so move to next Glyph
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
@ -1012,13 +1048,10 @@ class font_patcher:
|
||||||
# Currently stretching vertically for both monospace and double-width
|
# Currently stretching vertically for both monospace and double-width
|
||||||
scale_ratio_y = self.font_dim['height'] / sym_dim['height']
|
scale_ratio_y = self.font_dim['height'] / sym_dim['height']
|
||||||
|
|
||||||
if 'overlap' in sym_attr['params']:
|
overlap = sym_attr['params'].get('overlap')
|
||||||
overlap = sym_attr['params']['overlap']
|
|
||||||
else:
|
|
||||||
overlap = 0
|
|
||||||
|
|
||||||
if scale_ratio_x != 1 or scale_ratio_y != 1:
|
if scale_ratio_x != 1 or scale_ratio_y != 1:
|
||||||
if overlap != 0:
|
if overlap:
|
||||||
scale_ratio_x *= 1 + overlap
|
scale_ratio_x *= 1 + overlap
|
||||||
scale_ratio_y *= 1 + overlap
|
scale_ratio_y *= 1 + overlap
|
||||||
self.sourceFont[currentSourceFontGlyph].transform(psMat.scale(scale_ratio_x, scale_ratio_y))
|
self.sourceFont[currentSourceFontGlyph].transform(psMat.scale(scale_ratio_x, scale_ratio_y))
|
||||||
|
@ -1044,7 +1077,7 @@ class font_patcher:
|
||||||
# Right align
|
# Right align
|
||||||
x_align_distance += self.font_dim['width'] - sym_dim['width']
|
x_align_distance += self.font_dim['width'] - sym_dim['width']
|
||||||
|
|
||||||
if overlap != 0:
|
if overlap:
|
||||||
overlap_width = self.font_dim['width'] * overlap
|
overlap_width = self.font_dim['width'] * overlap
|
||||||
if sym_attr['align'] == 'l':
|
if sym_attr['align'] == 'l':
|
||||||
x_align_distance -= overlap_width
|
x_align_distance -= overlap_width
|
||||||
|
@ -1054,20 +1087,26 @@ class font_patcher:
|
||||||
align_matrix = psMat.translate(x_align_distance, y_align_distance)
|
align_matrix = psMat.translate(x_align_distance, y_align_distance)
|
||||||
self.sourceFont[currentSourceFontGlyph].transform(align_matrix)
|
self.sourceFont[currentSourceFontGlyph].transform(align_matrix)
|
||||||
|
|
||||||
|
# Ensure after horizontal adjustments and centering that the glyph
|
||||||
|
# does not overlap the bearings (edges)
|
||||||
|
if not overlap:
|
||||||
|
self.remove_glyph_neg_bearings(self.sourceFont[currentSourceFontGlyph])
|
||||||
|
|
||||||
# Needed for setting 'advance width' on each glyph so they do not overlap,
|
# Needed for setting 'advance width' on each glyph so they do not overlap,
|
||||||
# also ensures the font is considered monospaced on Windows by setting the
|
# also ensures the font is considered monospaced on Windows by setting the
|
||||||
# same width for all character glyphs. This needs to be done for all glyphs,
|
# same width for all character glyphs. This needs to be done for all glyphs,
|
||||||
# even the ones that are empty and didn't go through the scaling operations.
|
# even the ones that are empty and didn't go through the scaling operations.
|
||||||
|
# It should come after setting the glyph bearings
|
||||||
self.set_glyph_width_mono(self.sourceFont[currentSourceFontGlyph])
|
self.set_glyph_width_mono(self.sourceFont[currentSourceFontGlyph])
|
||||||
|
|
||||||
# Ensure after horizontal adjustments and centering that the glyph
|
# Re-remove negative bearings for target font with variable advance width
|
||||||
# does not overlap the bearings (edges)
|
if self.args.nonmono:
|
||||||
self.remove_glyph_neg_bearings(self.sourceFont[currentSourceFontGlyph])
|
self.remove_glyph_neg_bearings(self.sourceFont[currentSourceFontGlyph])
|
||||||
|
|
||||||
# Check if the inserted glyph is scaled correctly for monospace
|
# Check if the inserted glyph is scaled correctly for monospace
|
||||||
if self.args.single:
|
if self.args.single:
|
||||||
(xmin, _, xmax, _) = self.sourceFont[currentSourceFontGlyph].boundingBox()
|
(xmin, _, xmax, _) = self.sourceFont[currentSourceFontGlyph].boundingBox()
|
||||||
if int(xmax - xmin) > self.font_dim['width'] * (1 + overlap):
|
if int(xmax - xmin) > self.font_dim['width'] * (1 + (overlap or 0)):
|
||||||
print("\n Warning: Scaled glyph U+{:X} wider than one monospace width ({} / {} (overlap {}))".format(
|
print("\n Warning: Scaled glyph U+{:X} wider than one monospace width ({} / {} (overlap {}))".format(
|
||||||
currentSourceFontGlyph, int(xmax - xmin), self.font_dim['width'], overlap))
|
currentSourceFontGlyph, int(xmax - xmin), self.font_dim['width'], overlap))
|
||||||
|
|
||||||
|
@ -1114,11 +1153,15 @@ class font_patcher:
|
||||||
self.font_dim.width is set with self.get_sourcefont_dimensions().
|
self.font_dim.width is set with self.get_sourcefont_dimensions().
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# Fontforge handles the width change like this:
|
||||||
|
# - Keep existing left_side_bearing
|
||||||
|
# - Set width
|
||||||
|
# - Calculate and set new right_side_bearing
|
||||||
glyph.width = self.font_dim['width']
|
glyph.width = self.font_dim['width']
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def prepareScaleGlyph(self, scaleGlyph, symbolFont):
|
def prepareScaleGlyph(self, scaleGlyph, symbolFont, destGlyph):
|
||||||
""" Prepare raw ScaleGlyph data for use """
|
""" Prepare raw ScaleGlyph data for use """
|
||||||
# The GlyphData is a dict with these (possible) entries:
|
# The GlyphData is a dict with these (possible) entries:
|
||||||
# 'GlyphsToScale': List of ((lists of glyph codes) or (ranges of glyph codes)) that shall be scaled
|
# 'GlyphsToScale': List of ((lists of glyph codes) or (ranges of glyph codes)) that shall be scaled
|
||||||
|
@ -1153,13 +1196,14 @@ class font_patcher:
|
||||||
else:
|
else:
|
||||||
scaleGlyph['scales'] = []
|
scaleGlyph['scales'] = []
|
||||||
for group in scaleGlyph['GlyphsToScale']:
|
for group in scaleGlyph['GlyphsToScale']:
|
||||||
sym_dim = get_multiglyph_boundingBox([ symbolFont[g] if g in symbolFont else None for g in group ])
|
sym_dim = get_multiglyph_boundingBox([ symbolFont[g] if g in symbolFont else None for g in group ], destGlyph)
|
||||||
scaleGlyph['scales'].append(self.get_scale_factor(sym_dim))
|
scaleGlyph['scales'].append(self.get_scale_factor(sym_dim))
|
||||||
|
|
||||||
def get_glyph_scale(self, unicode_value, scaleGlyph, symbolFont):
|
def get_glyph_scale(self, unicode_value, scaleGlyph, symbolFont):
|
||||||
""" Determines whether or not to use scaled glyphs for glyphs in passed glyph_list """
|
""" Determines whether or not to use scaled glyphs for glyphs in passed glyph_list """
|
||||||
|
# Potentially destorys the contents of self.sourceFont[unicode_value]
|
||||||
if not 'scales' in scaleGlyph:
|
if not 'scales' in scaleGlyph:
|
||||||
self.prepareScaleGlyph(scaleGlyph, symbolFont)
|
self.prepareScaleGlyph(scaleGlyph, symbolFont, self.sourceFont[unicode_value])
|
||||||
for glyph_list, scale in zip(scaleGlyph['GlyphsToScale'], scaleGlyph['scales']):
|
for glyph_list, scale in zip(scaleGlyph['GlyphsToScale'], scaleGlyph['scales']):
|
||||||
if unicode_value in glyph_list:
|
if unicode_value in glyph_list:
|
||||||
return scale
|
return scale
|
||||||
|
@ -1181,13 +1225,22 @@ def make_sure_path_exists(path):
|
||||||
if exception.errno != errno.EEXIST:
|
if exception.errno != errno.EEXIST:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def get_multiglyph_boundingBox(glyphs):
|
def get_multiglyph_boundingBox(glyphs, destGlyph = None):
|
||||||
""" Returns dict of the dimensions of multiple glyphs combined """
|
""" Returns dict of the dimensions of multiple glyphs combined(, as if they are copied into destGlyph) """
|
||||||
|
# If destGlyph is given the glyph(s) are first copied over into that
|
||||||
|
# glyph and measured in that font (to avoid rounding errors)
|
||||||
|
# Leaves the destGlyph in unknown state!
|
||||||
bbox = [ None, None, None, None ]
|
bbox = [ None, None, None, None ]
|
||||||
for glyph in glyphs:
|
for glyph in glyphs:
|
||||||
if glyph is None:
|
if glyph is None:
|
||||||
# Glyph has been in defining range but is not in the actual font
|
# Glyph has been in defining range but is not in the actual font
|
||||||
continue
|
continue
|
||||||
|
if destGlyph:
|
||||||
|
glyph.font.selection.select(glyph)
|
||||||
|
glyph.font.copy()
|
||||||
|
destGlyph.font.selection.select(destGlyph)
|
||||||
|
destGlyph.font.paste()
|
||||||
|
glyph = destGlyph
|
||||||
gbb = glyph.boundingBox()
|
gbb = glyph.boundingBox()
|
||||||
bbox[0] = gbb[0] if bbox[0] is None or bbox[0] > gbb[0] else bbox[0]
|
bbox[0] = gbb[0] if bbox[0] is None or bbox[0] > gbb[0] else bbox[0]
|
||||||
bbox[1] = gbb[1] if bbox[1] is None or bbox[1] > gbb[1] else bbox[1]
|
bbox[1] = gbb[1] if bbox[1] is None or bbox[1] > gbb[1] else bbox[1]
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue