mirror of
https://github.com/ryanoasis/nerd-fonts.git
synced 2025-01-25 03:32:02 +02:00
Various improvements for mono-space generation
This commit is contained in:
parent
72ca7b7c1f
commit
fec7b20a4a
182
font-patcher
182
font-patcher
@ -43,10 +43,10 @@ parser.add_argument('--pomicons', dest='pomicons', action='store_true', help='Ad
|
||||
parser.add_argument('--powerline', dest='powerline', action='store_true', help='Add Powerline Glyphs', default=False)
|
||||
parser.add_argument('--powerlineextra', dest='powerlineextra', action='store_true', help='Add Powerline Glyphs (https://github.com/ryanoasis/powerline-extra-symbols)', default=False)
|
||||
parser.add_argument('--careful', dest='careful', action='store_true', help='Do not overwrite existing glyphs if detected', default=False)
|
||||
parser.add_argument('-ext', '--extension', type=str, nargs='?', dest='extension', help='Change type of font file to create (e.g. ttf, otf)', default="")
|
||||
parser.add_argument('-out', '--outputdir', type=str, nargs='?', dest='outputdir', help='The directory to output the patched font file to', default=".")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
changelog = open("changelog.md", "r")
|
||||
minimumVersion = 20141231
|
||||
actualVersion = int(fontforge.version())
|
||||
@ -180,6 +180,7 @@ sourceFont.version += ";" + projectName + " " + version
|
||||
# glyph font
|
||||
|
||||
sourceFont_em_original = sourceFont.em
|
||||
print("SourceFont.em: ", sourceFont.em)
|
||||
|
||||
# Open fonts and force the em size to be equal
|
||||
|
||||
@ -190,7 +191,8 @@ symbolsDevicons = fontforge.open("glyph-source-fonts/devicons.ttf")
|
||||
|
||||
symbols.em = sourceFont.em
|
||||
symbolsDevicons.em = sourceFont.em
|
||||
# powerlineExtraSymbols.em = sourceFont.em
|
||||
powerlineSymbols.em = sourceFont.em
|
||||
powerlineExtraSymbols.em = sourceFont.em
|
||||
|
||||
if args.fontawesome:
|
||||
fontawesome = fontforge.open("glyph-source-fonts/FontAwesome.otf")
|
||||
@ -285,15 +287,77 @@ SYM_ATTR = {
|
||||
0x2b81: { 'align': 'l', 'stretch': 'xy', 'overlap': True },
|
||||
0x2b82: { 'align': 'r', 'stretch': 'xy', 'overlap': True },
|
||||
0x2b83: { 'align': 'r', 'stretch': 'xy', 'overlap': True },
|
||||
|
||||
# Powerline dividers
|
||||
|
||||
# Arrow tips
|
||||
0xe0b0: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0b1: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0b2: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0b3: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Rounded arcs
|
||||
0xe0b4: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0b5: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0b6: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0b7: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Bottom Triangles
|
||||
0xe0b8: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0b9: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0ba: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0bb: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Top Triangles
|
||||
0xe0bc: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0bd: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0be: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0bf: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Flames
|
||||
0xe0c0: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0c1: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0c2: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0c3: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Small squares
|
||||
0xe0c4: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0c5: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Bigger squares
|
||||
0xe0c6: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0c7: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Waveform
|
||||
0xe0c8: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Hexagons
|
||||
0xe0cc: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0cd: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Legos
|
||||
0xe0ce: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0cf: { 'align': 'c', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0d1: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
|
||||
# Top and bottom trapezoid
|
||||
0xe0d2: { 'align': 'l', 'stretch': 'xy', 'overlap': False },
|
||||
0xe0d4: { 'align': 'r', 'stretch': 'xy', 'overlap': False },
|
||||
}
|
||||
|
||||
SYM_ATTR_DEFAULT = {
|
||||
# 'pa' == preserve aspect ratio
|
||||
'align': 'c', 'stretch': 'pa', 'overlap': False
|
||||
}
|
||||
|
||||
|
||||
# Initial font dimensions
|
||||
font_dim = {
|
||||
# Use winXXXXXX for ymin and ymax as this is typically what is used for line size
|
||||
'xmin' : 0,
|
||||
'ymin' : -sourceFont.descent,
|
||||
'ymin' : -sourceFont.os2_windescent,
|
||||
'xmax' : 0,
|
||||
'ymax' : sourceFont.ascent,
|
||||
'ymax' : sourceFont.os2_winascent,
|
||||
'width' : 0,
|
||||
'height': 0,
|
||||
}
|
||||
@ -311,8 +375,12 @@ for glyph in range(0x00, 0x17f) + range(0x2500, 0x2600):
|
||||
if font_dim['width'] == 0:
|
||||
font_dim['width'] = sourceFont[glyph].width
|
||||
|
||||
if ymin < font_dim['ymin']: font_dim['ymin'] = ymin
|
||||
if ymax > font_dim['ymax']: font_dim['ymax'] = ymax
|
||||
if font_dim['width'] < sourceFont[glyph].width:
|
||||
font_dim['width'] = sourceFont[glyph].width
|
||||
|
||||
# Ignore the y-values, os2_winXXXXX values set above are more accurate
|
||||
# if ymin < font_dim['ymin']: font_dim['ymin'] = ymin
|
||||
# if ymax > font_dim['ymax']: font_dim['ymax'] = ymax
|
||||
if xmax > font_dim['xmax']: font_dim['xmax'] = xmax
|
||||
|
||||
# Calculate font height
|
||||
@ -354,7 +422,11 @@ def copy_glyphs(sourceFont, sourceFontStart, sourceFontEnd, symbolFont, symbolFo
|
||||
|
||||
for sym_glyph in symbolFont.selection.byGlyphs:
|
||||
|
||||
#sym_attr = SYM_ATTR[sym_glyph.unicode]
|
||||
try:
|
||||
sym_attr = SYM_ATTR[sym_glyph.unicode]
|
||||
except KeyError:
|
||||
sym_attr = SYM_ATTR_DEFAULT
|
||||
|
||||
glyphName = sym_glyph.glyphname
|
||||
|
||||
if exactEncoding:
|
||||
@ -396,68 +468,65 @@ def copy_glyphs(sourceFont, sourceFontStart, sourceFontEnd, symbolFont, symbolFo
|
||||
|
||||
sourceFont[currentSourceFontGlyph].glyphname = glyphName
|
||||
|
||||
if args.single:
|
||||
# There are some symbols that are blank, skip those
|
||||
if args.single and sym_dim['width'] and sym_dim['height']:
|
||||
# Now that we have copy/pasted the glyph, it's time to scale and move it
|
||||
|
||||
# Handle glyph stretching
|
||||
#if 'x' in sym_attr['stretch']:
|
||||
# # Stretch the glyph horizontally
|
||||
# scale_ratio = font_dim['width'] / sym_dim['width']
|
||||
scale_ratio_x = 1
|
||||
scale_ratio_y = 1
|
||||
if sym_attr['stretch'] == 'pa':
|
||||
# We want to preserve x/y aspect ratio, so find biggest scale factor that allows
|
||||
scale_ratio_x = font_dim['width'] / sym_dim['width']
|
||||
scale_ratio_y = font_dim['height'] / sym_dim['height']
|
||||
if scale_ratio_x > scale_ratio_y:
|
||||
scale_ratio_x = scale_ratio_y
|
||||
else:
|
||||
scale_ratio_y = scale_ratio_x
|
||||
else:
|
||||
if 'x' in sym_attr['stretch']:
|
||||
# Stretch the glyph horizontally
|
||||
scale_ratio_x = font_dim['width'] / sym_dim['width']
|
||||
if 'y' in sym_attr['stretch']:
|
||||
# Stretch the glyph vertically
|
||||
scale_ratio_y = font_dim['height'] / sym_dim['height']
|
||||
|
||||
# sourceFont.transform(psMat.scale(scale_ratio, 1))
|
||||
#if 'y' in sym_attr['stretch']:
|
||||
# # Stretch the glyph vertically
|
||||
# scale_ratio = font_dim['height'] / sym_dim['height']
|
||||
|
||||
# sourceFont.transform(psMat.scale(1, scale_ratio))
|
||||
sourceFont.transform(psMat.scale(scale_ratio_x, scale_ratio_y))
|
||||
|
||||
# Use the dimensions from the pasted and stretched glyph
|
||||
sym_dim = get_dim(sourceFont[currentSourceFontGlyph])
|
||||
|
||||
# Center-align the glyph vertically
|
||||
font_ycenter = font_dim['height'] / 2
|
||||
sym_ycenter = sym_dim['height'] / 2
|
||||
# Center the symbol by matching the center of the font and center of symbol
|
||||
sym_ycenter = sym_dim['ymax'] - (sym_dim['height'] / 2)
|
||||
font_ycenter = font_dim['ymax'] - (font_dim['height'] / 2)
|
||||
sourceFont.transform(psMat.translate(0, font_ycenter - sym_ycenter))
|
||||
|
||||
# First move it to the ymax (top)
|
||||
sourceFont.transform(psMat.translate(0, font_dim['ymax'] - sym_dim['ymax']))
|
||||
# Handle glyph l/r alignment
|
||||
|
||||
# Then move it the y center difference
|
||||
sourceFont.transform(psMat.translate(0, sym_ycenter - font_ycenter))
|
||||
|
||||
# Ensure that the glyph doesn't extend outside the font's bounding box
|
||||
if sym_dim['width'] > font_dim['width']:
|
||||
# The glyph is too wide, scale it down to fit
|
||||
scale_matrix = psMat.scale(font_dim['width'] / sym_dim['width'], 1)
|
||||
|
||||
sourceFont.transform(scale_matrix)
|
||||
|
||||
# Use the dimensions from the stretched glyph
|
||||
sym_dim = get_dim(sourceFont[currentSourceFontGlyph])
|
||||
|
||||
# Handle glyph alignment
|
||||
#if sym_attr['align'] == 'c':
|
||||
# # Center align
|
||||
# align_matrix = psMat.translate(font_dim['width'] / 2 - sym_dim['width'] / 2 , 0)
|
||||
align_matrix = psMat.translate(font_dim['width'] / 2 - sym_dim['width'] / 2 , 0)
|
||||
#elif sym_attr['align'] == 'r':
|
||||
# # Right align
|
||||
# align_matrix = psMat.translate(font_dim['width'] - sym_dim['width'], 0)
|
||||
#else:
|
||||
# No alignment (left alignment)
|
||||
#align_matrix = psMat.translate(0, 0)
|
||||
# First move it to the xmin (left)
|
||||
left_align_distance = font_dim['xmin']-sym_dim['xmin']
|
||||
if sym_attr['align'] == 'c':
|
||||
# Center align
|
||||
align_matrix = psMat.translate(left_align_distance + ((font_dim['width']/2) - (sym_dim['width']/2)), 0)
|
||||
elif sym_attr['align'] == 'r':
|
||||
# Right align
|
||||
align_matrix = psMat.translate(left_align_distance + font_dim['width'] - sym_dim['width'], 0)
|
||||
else:
|
||||
# Left align
|
||||
align_matrix = psMat.translate(left_align_distance, 0)
|
||||
|
||||
sourceFont.transform(align_matrix)
|
||||
|
||||
#if sym_attr['overlap'] is True:
|
||||
# overlap_width = sourceFont.em / 48
|
||||
if sym_attr['overlap'] is True:
|
||||
overlap_width = sourceFont.em / 48
|
||||
|
||||
# # Stretch the glyph slightly horizontally if it should overlap
|
||||
# sourceFont.transform(psMat.scale((sym_dim['width'] + overlap_width) / sym_dim['width'], 1))
|
||||
# Stretch the glyph slightly horizontally if it should overlap
|
||||
sourceFont.transform(psMat.scale((sym_dim['width'] + overlap_width) / sym_dim['width'], 1))
|
||||
|
||||
# if sym_attr['align'] == 'l':
|
||||
# # The glyph should be left-aligned, so it must be moved overlap_width to the left
|
||||
# # This only applies to left-aligned glyphs because the glyph is scaled to the right
|
||||
# sourceFont.transform(psMat.translate(-overlap_width, 0))
|
||||
if sym_attr['align'] == 'l':
|
||||
# The glyph should be left-aligned, so it must be moved overlap_width to the left
|
||||
# This only applies to left-aligned glyphs because the glyph is scaled to the right
|
||||
sourceFont.transform(psMat.translate(-overlap_width, 0))
|
||||
|
||||
# Ensure the font is considered monospaced on Windows
|
||||
sourceFont[currentSourceFontGlyph].width = font_dim['width']
|
||||
@ -495,7 +564,10 @@ if args.pomicons:
|
||||
if args.fontlinux:
|
||||
copy_glyphs(sourceFont, sourceFontFontLinuxStart, sourceFontFontLinuxEnd, fontlinux, symbolsFontLinuxRangeStart, symbolsFontLinuxRangeEnd, fontlinuxExactEncodingPosition)
|
||||
|
||||
extension = os.path.splitext(sourceFont.path)[1]
|
||||
if args.extension == "":
|
||||
extension = os.path.splitext(sourceFont.path)[1]
|
||||
else:
|
||||
extension = '.'+args.extension
|
||||
|
||||
# the `PfEd-comments` flag is required for Fontforge to save
|
||||
# '.comment' and '.fontlog'.
|
||||
|
Loading…
x
Reference in New Issue
Block a user