mirror of
https://github.com/daylinmorgan/monolisa-nerdfont-patch.git
synced 2024-11-09 16:43:14 -06:00
Compare commits
2 commits
c06928af07
...
86020c4474
Author | SHA1 | Date | |
---|---|---|---|
86020c4474 | |||
51a57bbbfa |
3 changed files with 108 additions and 55 deletions
|
@ -1,6 +1,6 @@
|
|||
# MonoLisa NF
|
||||
|
||||
*Most* Batteries inlcuded repo to patch MonoLisa with Nerd Fonts glyphs
|
||||
*Most* Batteries included repo to patch MonoLisa with Nerd Fonts glyphs
|
||||
|
||||
tested w/ MonoLisa v1.808
|
||||
|
||||
|
|
159
bin/font-patcher
159
bin/font-patcher
|
@ -1,23 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# coding=utf8
|
||||
# Nerd Fonts Version: 2.2.1
|
||||
# Nerd Fonts Version: 2.2.2
|
||||
# Script version is further down
|
||||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
# 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"
|
||||
projectNameAbbreviation = "NF"
|
||||
projectNameSingular = projectName[:-1]
|
||||
|
||||
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 os
|
||||
import argparse
|
||||
|
@ -30,12 +26,13 @@ try:
|
|||
except ImportError:
|
||||
sys.exit(projectName + ": configparser module is probably not installed. Try `pip install configparser` or equivalent")
|
||||
try:
|
||||
import psMat
|
||||
import fontforge
|
||||
except ImportError:
|
||||
sys.exit(
|
||||
projectName + (
|
||||
": 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.onlybitmaps = 0
|
||||
self.extension = ""
|
||||
self.essential = set()
|
||||
self.setup_arguments()
|
||||
self.config = configparser.ConfigParser(empty_lines_in_values=False, allow_no_value=True)
|
||||
if not os.path.isfile(self.args.font):
|
||||
|
@ -181,6 +179,7 @@ class font_patcher:
|
|||
except Exception:
|
||||
sys.exit(projectName + ": Can not open font, try to open with fontforge interactively to get more information")
|
||||
self.setup_version()
|
||||
self.get_essential_references()
|
||||
self.setup_name_backup()
|
||||
self.remove_ligatures()
|
||||
make_sure_path_exists(self.args.outputdir)
|
||||
|
@ -219,6 +218,10 @@ class font_patcher:
|
|||
PreviousSymbolFilename = ""
|
||||
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:
|
||||
if patch['Enabled']:
|
||||
if PreviousSymbolFilename != patch['Filename']:
|
||||
|
@ -226,7 +229,13 @@ class font_patcher:
|
|||
if symfont:
|
||||
symfont.close()
|
||||
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
|
||||
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('--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('--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
|
||||
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.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('--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('--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/)')
|
||||
|
@ -351,7 +361,7 @@ class font_patcher:
|
|||
if self.args.complete:
|
||||
self.args.fontawesome = True
|
||||
self.args.fontawesomeextension = True
|
||||
self.args.fontlinux = True
|
||||
self.args.fontlogos = True
|
||||
self.args.octicons = True
|
||||
self.args.codicons = True
|
||||
self.args.powersymbols = True
|
||||
|
@ -380,6 +390,10 @@ class font_patcher:
|
|||
if self.args.alsowindows:
|
||||
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
|
||||
# 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.
|
||||
|
@ -389,7 +403,7 @@ class font_patcher:
|
|||
# self.args.complete = all([
|
||||
# self.args.fontawesome is True,
|
||||
# self.args.fontawesomeextension is True,
|
||||
# self.args.fontlinux is True,
|
||||
# self.args.fontlogos is True,
|
||||
# self.args.octicons is True,
|
||||
# self.args.powersymbols is True,
|
||||
# self.args.pomicons is True,
|
||||
|
@ -436,9 +450,9 @@ class font_patcher:
|
|||
if self.args.pomicons:
|
||||
additionalFontNameSuffix += " P"
|
||||
verboseAdditionalFontNameSuffix += " Plus Pomicons"
|
||||
if self.args.fontlinux:
|
||||
if self.args.fontlogos:
|
||||
additionalFontNameSuffix += " L"
|
||||
verboseAdditionalFontNameSuffix += " Plus Font Logos (Font Linux)"
|
||||
verboseAdditionalFontNameSuffix += " Plus Font Logos"
|
||||
if self.args.material:
|
||||
additionalFontNameSuffix += " MDI"
|
||||
verboseAdditionalFontNameSuffix += " Plus Material Design Icons"
|
||||
|
@ -522,6 +536,8 @@ class font_patcher:
|
|||
maxFamilyLength = 31
|
||||
maxFontLength = maxFamilyLength - len('-' + subFamily)
|
||||
familyname += " " + projectNameAbbreviation
|
||||
if self.args.single:
|
||||
familyname += "M"
|
||||
fullname += " Windows Compatible"
|
||||
|
||||
# now make sure less than 32 characters name length
|
||||
|
@ -673,7 +689,7 @@ class font_patcher:
|
|||
# Supported params: overlap | careful
|
||||
# Powerline dividers
|
||||
SYM_ATTR_POWERLINE = {
|
||||
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': ''},
|
||||
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}},
|
||||
|
||||
# Arrow tips
|
||||
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}},
|
||||
|
||||
# Small squares
|
||||
0xe0c4: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0c5: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0c4: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
0xe0c5: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
|
||||
# Bigger squares
|
||||
0xe0c6: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0c7: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0c6: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
0xe0c7: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
|
||||
# Waveform
|
||||
0xe0c8: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.01}},
|
||||
|
||||
# Hexagons
|
||||
0xe0cc: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0cd: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0cc: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
0xe0cd: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
|
||||
# Legos
|
||||
0xe0ce: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0cf: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': ''},
|
||||
0xe0ce: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
0xe0cf: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {}},
|
||||
0xe0d1: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
|
||||
|
||||
# Top and bottom trapezoid
|
||||
|
@ -732,22 +748,22 @@ class font_patcher:
|
|||
|
||||
SYM_ATTR_DEFAULT = {
|
||||
# 'pa' == preserve aspect ratio
|
||||
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': ''}
|
||||
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}}
|
||||
}
|
||||
|
||||
SYM_ATTR_FONTA = {
|
||||
# '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
|
||||
0xf0dc: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': ''},
|
||||
0xf0dd: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': ''},
|
||||
0xf0de: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': ''}
|
||||
0xf0dc: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': {}},
|
||||
0xf0dd: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': {}},
|
||||
0xf0de: {'align': 'c', 'valign': '', 'stretch': 'pa', 'params': {}}
|
||||
}
|
||||
|
||||
CUSTOM_ATTR = {
|
||||
# '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
|
||||
|
@ -789,7 +805,7 @@ class font_patcher:
|
|||
# Define the character ranges
|
||||
# Symbol font ranges
|
||||
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': 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},
|
||||
|
@ -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.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.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': 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
|
||||
|
@ -835,6 +851,17 @@ class font_patcher:
|
|||
self.sourceFont.hhea_linegap = 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):
|
||||
# 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
|
||||
scale_ratio_x = self.font_dim['width'] / sym_dim['width']
|
||||
|
||||
# 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']
|
||||
scale_ratio_y = self.font_dim['height'] / sym_dim['height']
|
||||
if scale_ratio_x > scale_ratio_y:
|
||||
scale_ratio = scale_ratio_y
|
||||
else:
|
||||
|
@ -927,6 +951,8 @@ class font_patcher:
|
|||
if self.args.quiet is False:
|
||||
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):
|
||||
index = max(1, index)
|
||||
|
||||
|
@ -936,8 +962,17 @@ class font_patcher:
|
|||
sym_attr = attributes['default']
|
||||
|
||||
if exactEncoding:
|
||||
# use the exact same hex values for the source font as for the symbol font
|
||||
currentSourceFontGlyph = sym_glyph.encoding
|
||||
# Use the exact same hex values for the source font as for the symbol font.
|
||||
# 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:
|
||||
# use source font defined hex values based on passed in start and end
|
||||
currentSourceFontGlyph = sourceFontList[sourceFontCounter]
|
||||
|
@ -952,10 +987,11 @@ class font_patcher:
|
|||
sys.stdout.flush()
|
||||
|
||||
# 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 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
|
||||
continue
|
||||
else:
|
||||
|
@ -1012,13 +1048,10 @@ class font_patcher:
|
|||
# Currently stretching vertically for both monospace and double-width
|
||||
scale_ratio_y = self.font_dim['height'] / sym_dim['height']
|
||||
|
||||
if 'overlap' in sym_attr['params']:
|
||||
overlap = sym_attr['params']['overlap']
|
||||
else:
|
||||
overlap = 0
|
||||
overlap = sym_attr['params'].get('overlap')
|
||||
|
||||
if scale_ratio_x != 1 or scale_ratio_y != 1:
|
||||
if overlap != 0:
|
||||
if overlap:
|
||||
scale_ratio_x *= 1 + overlap
|
||||
scale_ratio_y *= 1 + overlap
|
||||
self.sourceFont[currentSourceFontGlyph].transform(psMat.scale(scale_ratio_x, scale_ratio_y))
|
||||
|
@ -1044,7 +1077,7 @@ class font_patcher:
|
|||
# Right align
|
||||
x_align_distance += self.font_dim['width'] - sym_dim['width']
|
||||
|
||||
if overlap != 0:
|
||||
if overlap:
|
||||
overlap_width = self.font_dim['width'] * overlap
|
||||
if sym_attr['align'] == 'l':
|
||||
x_align_distance -= overlap_width
|
||||
|
@ -1054,20 +1087,26 @@ class font_patcher:
|
|||
align_matrix = psMat.translate(x_align_distance, y_align_distance)
|
||||
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,
|
||||
# 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,
|
||||
# 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])
|
||||
|
||||
# Ensure after horizontal adjustments and centering that the glyph
|
||||
# does not overlap the bearings (edges)
|
||||
# Re-remove negative bearings for target font with variable advance width
|
||||
if self.args.nonmono:
|
||||
self.remove_glyph_neg_bearings(self.sourceFont[currentSourceFontGlyph])
|
||||
|
||||
# Check if the inserted glyph is scaled correctly for monospace
|
||||
if self.args.single:
|
||||
(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(
|
||||
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().
|
||||
"""
|
||||
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']
|
||||
except:
|
||||
pass
|
||||
|
||||
def prepareScaleGlyph(self, scaleGlyph, symbolFont):
|
||||
def prepareScaleGlyph(self, scaleGlyph, symbolFont, destGlyph):
|
||||
""" Prepare raw ScaleGlyph data for use """
|
||||
# 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
|
||||
|
@ -1153,13 +1196,14 @@ class font_patcher:
|
|||
else:
|
||||
scaleGlyph['scales'] = []
|
||||
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))
|
||||
|
||||
def get_glyph_scale(self, unicode_value, scaleGlyph, symbolFont):
|
||||
""" 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:
|
||||
self.prepareScaleGlyph(scaleGlyph, symbolFont)
|
||||
self.prepareScaleGlyph(scaleGlyph, symbolFont, self.sourceFont[unicode_value])
|
||||
for glyph_list, scale in zip(scaleGlyph['GlyphsToScale'], scaleGlyph['scales']):
|
||||
if unicode_value in glyph_list:
|
||||
return scale
|
||||
|
@ -1181,13 +1225,22 @@ def make_sure_path_exists(path):
|
|||
if exception.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
def get_multiglyph_boundingBox(glyphs):
|
||||
""" Returns dict of the dimensions of multiple glyphs combined """
|
||||
def get_multiglyph_boundingBox(glyphs, destGlyph = None):
|
||||
""" 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 ]
|
||||
for glyph in glyphs:
|
||||
if glyph is None:
|
||||
# Glyph has been in defining range but is not in the actual font
|
||||
continue
|
||||
if destGlyph:
|
||||
glyph.font.selection.select(glyph)
|
||||
glyph.font.copy()
|
||||
destGlyph.font.selection.select(destGlyph)
|
||||
destGlyph.font.paste()
|
||||
glyph = destGlyph
|
||||
gbb = glyph.boundingBox()
|
||||
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]
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue