mirror of
https://github.com/daylinmorgan/monolisa-nerdfont-patch.git
synced 2024-12-22 06:50:44 -06:00
Compare commits
3 commits
870329f52a
...
c06928af07
Author | SHA1 | Date | |
---|---|---|---|
c06928af07 | |||
90ef76cd4a | |||
59b79dc2ac |
6 changed files with 637 additions and 31 deletions
250
.task.mk
Normal file
250
.task.mk
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
# }> [github.com/daylinmorgan/task.mk] <{ #
|
||||||
|
# Copyright (c) 2022 Daylin Morgan
|
||||||
|
# MIT License
|
||||||
|
# 22.9.5
|
||||||
|
#
|
||||||
|
# task.mk should be included at the bottom of your Makefile.
|
||||||
|
# See below for the standard configuration options that should be set prior to including this file.
|
||||||
|
# You can update your .task.mk with `make _update-task.mk`
|
||||||
|
|
||||||
|
# ---- CONFIG ---- #
|
||||||
|
HEADER_COLOR ?= b_cyan
|
||||||
|
PARAMS_COLOR ?= b_magenta
|
||||||
|
ACCENT_COLOR ?= b_yellow
|
||||||
|
GOAL_COLOR ?= $(ACCENT_COLOR)
|
||||||
|
MSG_COLOR ?= faint
|
||||||
|
HELP_SEP ?= |
|
||||||
|
HELP_SORT ?= # sort goals alphabetically
|
||||||
|
|
||||||
|
# python f-string literals
|
||||||
|
EPILOG ?=
|
||||||
|
define USAGE ?=
|
||||||
|
{ansi.$(HEADER_COLOR)}usage{ansi.end}:
|
||||||
|
make <recipe>
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
# ---- [buitlin recipes] ---- #
|
||||||
|
|
||||||
|
|
||||||
|
## h, help | show this help
|
||||||
|
.PHONY: help h
|
||||||
|
help h:
|
||||||
|
$(call py,help_py)
|
||||||
|
|
||||||
|
.PHONY: _help
|
||||||
|
_help: export SHOW_HIDDEN=true
|
||||||
|
_help: help
|
||||||
|
|
||||||
|
ifdef PRINT_VARS
|
||||||
|
|
||||||
|
$(foreach v,$(PRINT_VARS),$(eval export $(v)))
|
||||||
|
|
||||||
|
.PHONY: vars v
|
||||||
|
vars v:
|
||||||
|
$(call py,vars_py,$(PRINT_VARS))
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
## _print-ansi | show all possible ansi color code combinations
|
||||||
|
.PHONY:
|
||||||
|
_print-ansi:
|
||||||
|
$(call py,print_ansi_py)
|
||||||
|
|
||||||
|
# functions to take f-string literals and pass to python print
|
||||||
|
tprint = $(call py,info_py,$(1))
|
||||||
|
tprint-sh = $(call pysh,info_py,$(1))
|
||||||
|
|
||||||
|
_update-task.mk:
|
||||||
|
$(call tprint,Updating task.mk)
|
||||||
|
curl https://raw.githubusercontent.com/daylinmorgan/task.mk/main/task.mk -o .task.mk
|
||||||
|
|
||||||
|
export MAKEFILE_LIST
|
||||||
|
|
||||||
|
# ---- [python/bash script runner] ---- #
|
||||||
|
|
||||||
|
# modified from https://unix.stackexchange.com/a/223093
|
||||||
|
define \n
|
||||||
|
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
escape_shellstring = $(subst `,\`,$(subst ",\",$(subst $$,\$$,$(subst \,\\,$1))))
|
||||||
|
|
||||||
|
escape_printf = $(subst \,\\,$(subst %,%%,$1))
|
||||||
|
|
||||||
|
create_string = $(subst $(\n),\n,$(call escape_shellstring,$(call escape_printf,$1)))
|
||||||
|
|
||||||
|
|
||||||
|
ifdef DEBUG
|
||||||
|
define py
|
||||||
|
@printf "Python Script:\n"
|
||||||
|
@printf -- "----------------\n"
|
||||||
|
@printf "$(call create_string,$($(1)))\n"
|
||||||
|
@printf -- "----------------\n"
|
||||||
|
@printf "$(call create_string,$($(1)))" | python3
|
||||||
|
endef
|
||||||
|
define tbash
|
||||||
|
@printf "Bash Script:\n"
|
||||||
|
@printf -- "----------------\n"
|
||||||
|
@printf "$(call create_string,$($(1)))\n"
|
||||||
|
@printf -- "----------------\n"
|
||||||
|
@printf "$(call create_string,$($(1)))" | bash
|
||||||
|
endef
|
||||||
|
else
|
||||||
|
py = @printf "$(call create_string,$($(1)))" | python3
|
||||||
|
tbash = @printf "$(call create_string,$($(1)))" | bash
|
||||||
|
endif
|
||||||
|
|
||||||
|
pysh = printf "$(call create_string,$($(1)))" | python3
|
||||||
|
|
||||||
|
# ---- [python scripts] ---- #
|
||||||
|
|
||||||
|
|
||||||
|
define help_py
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
$(ansi_py)
|
||||||
|
|
||||||
|
pattern = re.compile(r"^## (.*) \| (.*)")
|
||||||
|
|
||||||
|
makefile = ""
|
||||||
|
for file in os.getenv("MAKEFILE_LIST").split():
|
||||||
|
with open(file, "r") as f:
|
||||||
|
makefile += f.read() + "\n\n"
|
||||||
|
|
||||||
|
|
||||||
|
def get_help(file):
|
||||||
|
for line in file.splitlines():
|
||||||
|
match = pattern.search(line)
|
||||||
|
if match:
|
||||||
|
if not os.getenv("SHOW_HIDDEN") and match.groups()[0].startswith("_"):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
yield match.groups()
|
||||||
|
|
||||||
|
|
||||||
|
print(f"""$(USAGE)""")
|
||||||
|
|
||||||
|
goals = list(get_help(makefile))
|
||||||
|
if os.getenv("SORT_HELP",False):
|
||||||
|
goals.sort(key=lambda i: i[0])
|
||||||
|
goal_len = max(len(goal[0]) for goal in goals)
|
||||||
|
|
||||||
|
for goal, msg in goals:
|
||||||
|
print(
|
||||||
|
f"{ansi.$(GOAL_COLOR)}{goal:>{goal_len}}{ansi.end} $(HELP_SEP) {ansi.$(MSG_COLOR)}{msg}{ansi.end}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"""$(EPILOG)""")
|
||||||
|
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
define ansi_py
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
color2byte = dict(
|
||||||
|
black=0,
|
||||||
|
red=1,
|
||||||
|
green=2,
|
||||||
|
yellow=3,
|
||||||
|
blue=4,
|
||||||
|
magenta=5,
|
||||||
|
cyan=6,
|
||||||
|
white=7,
|
||||||
|
)
|
||||||
|
|
||||||
|
state2byte = dict(
|
||||||
|
bold=1, faint=2, italic=3, underline=4, blink=5, fast_blink=6, crossed=9
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def fg(byte):
|
||||||
|
return 30 + byte
|
||||||
|
|
||||||
|
|
||||||
|
def bg(byte):
|
||||||
|
return 40 + byte
|
||||||
|
|
||||||
|
|
||||||
|
class Ansi:
|
||||||
|
"""ANSI color codes"""
|
||||||
|
|
||||||
|
def setcode(self, name, escape_code):
|
||||||
|
if not sys.stdout.isatty() or os.getenv("NO_COLOR", False):
|
||||||
|
setattr(self, name, "")
|
||||||
|
else:
|
||||||
|
setattr(self, name, escape_code)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.setcode("end", "\033[0m")
|
||||||
|
for name, byte in color2byte.items():
|
||||||
|
self.setcode(name, f"\033[{fg(byte)}m")
|
||||||
|
self.setcode(f"b_{name}", f"\033[1;{fg(byte)}m")
|
||||||
|
self.setcode(f"d_{name}", f"\033[2;{fg(byte)}m")
|
||||||
|
for bgname, bgbyte in color2byte.items():
|
||||||
|
self.setcode(f"{name}_on_{bgname}", f"\033[{bg(bgbyte)};{fg(byte)}m")
|
||||||
|
for name, byte in state2byte.items():
|
||||||
|
self.setcode(name, f"\033[{byte}m")
|
||||||
|
|
||||||
|
|
||||||
|
a = ansi = Ansi()
|
||||||
|
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
define info_py
|
||||||
|
|
||||||
|
|
||||||
|
$(ansi_py)
|
||||||
|
|
||||||
|
print(f"""$(2)""")
|
||||||
|
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
define print_ansi_py
|
||||||
|
|
||||||
|
|
||||||
|
$(ansi_py)
|
||||||
|
|
||||||
|
codes_names = {
|
||||||
|
getattr(ansi, attr): attr
|
||||||
|
for attr in dir(ansi)
|
||||||
|
if attr[0:1] != "_" and attr != "end" and attr != "setcode"
|
||||||
|
}
|
||||||
|
for code in sorted(codes_names.keys(), key=lambda item: (len(item), item)):
|
||||||
|
print("{:>20} {}".format(codes_names[code], code + "******" + ansi.end))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
define vars_py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
$(ansi_py)
|
||||||
|
|
||||||
|
vars = "$2".split()
|
||||||
|
length = max((len(v) for v in vars))
|
||||||
|
|
||||||
|
print(f"{ansi.$(HEADER_COLOR)}vars:{ansi.end}\n")
|
||||||
|
|
||||||
|
for v in vars:
|
||||||
|
print(f" {ansi.b_magenta}{v:<{length}}{ansi.end} = {os.getenv(v)}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
27
Makefile
27
Makefile
|
@ -6,33 +6,52 @@ ML_TYPES := $(shell find MonoLisa -mindepth 1 -type d -printf "%f ")
|
||||||
UNKNOWN := $(filter-out $(OK_TYPES),$(ML_TYPES))
|
UNKNOWN := $(filter-out $(OK_TYPES),$(ML_TYPES))
|
||||||
$(if $(UNKNOWN),$(error unknown font type in ./MonoLisa: $(UNKNOWN)))
|
$(if $(UNKNOWN),$(error unknown font type in ./MonoLisa: $(UNKNOWN)))
|
||||||
|
|
||||||
|
msg = $(call tprint,{a.bold}==>{a.end} {a.b_magenta}$(1){a.end} {a.bold}<=={a.end})
|
||||||
|
|
||||||
|
## patch | add nerd fonts to MonoLisa
|
||||||
.PHONY: patch
|
.PHONY: patch
|
||||||
patch: $(addprefix patch-,$(ML_TYPES))
|
patch: $(addprefix patch-,$(ML_TYPES))
|
||||||
|
|
||||||
patch-%: ./bin/font-patcher
|
patch-%: ./bin/font-patcher
|
||||||
@echo "==> Patching MonoLisa $* Files <=="
|
$(call msg, Patching MonoLisa $* Files)
|
||||||
@./bin/patch-monolisa $* $(ARGS)
|
@./bin/patch-monolisa $* $(ARGS)
|
||||||
|
|
||||||
|
## update-fonts | move fonts and update fc-cache
|
||||||
.PHONY: update-fonts
|
.PHONY: update-fonts
|
||||||
update-fonts:
|
update-fonts:
|
||||||
@echo "==> Adding Fonts To System <=="
|
$(call msg,Adding Fonts To System)
|
||||||
@./bin/update-fonts
|
@./bin/update-fonts
|
||||||
@fc-cache -f -v
|
@fc-cache -f -v
|
||||||
|
|
||||||
|
## check | check fc-list for MonoLisa
|
||||||
.PHONY: check
|
.PHONY: check
|
||||||
check:
|
check:
|
||||||
@echo "==> Checking System For Fonts <=="
|
$(call msg, Checking System for Fonts)
|
||||||
@fc-list | grep "MonoLisa"
|
@fc-list | grep "MonoLisa"
|
||||||
|
|
||||||
|
## update-src | update nerd fonts source
|
||||||
.PHONY: update-src
|
.PHONY: update-src
|
||||||
update-src:
|
update-src:
|
||||||
@echo "==> Updating Source File <=="
|
$(call msg,Updating Source Files)
|
||||||
@./bin/update-src
|
@./bin/update-src
|
||||||
|
|
||||||
|
## lint | check shell scripts
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint:
|
lint:
|
||||||
@shfmt -w -s $(shell shfmt -f bin/)
|
@shfmt -w -s $(shell shfmt -f bin/)
|
||||||
|
|
||||||
|
## clean | remove patched fonts
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@rm -r patched/*
|
@rm -r patched/*
|
||||||
|
|
||||||
|
define USAGE
|
||||||
|
{a.b_green}Update MonoLisa with Nerd Fonts! {a.end}
|
||||||
|
|
||||||
|
{a.$(HEADER_COLOR)}usage{a.end}:
|
||||||
|
make <recipe>
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
-include .task.mk
|
||||||
|
$(if $(filter help,$(MAKECMDGOALS)),.task.mk: ; curl -fsSL https://raw.githubusercontent.com/daylinmorgan/task.mk/v22.9.5/task.mk -o .task.mk)
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
tested w/ MonoLisa v1.808
|
tested w/ MonoLisa v1.808
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="./assets/help.svg" width=400>
|
||||||
|
</p>
|
||||||
|
|
||||||
## Before You Begin
|
## Before You Begin
|
||||||
|
|
||||||
First you will need to install `fontforge`
|
First you will need to install `fontforge`
|
||||||
|
|
111
assets/help.svg
Normal file
111
assets/help.svg
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
<svg class="rich-terminal shadow" viewBox="0 0 585.3333333333334 399.5333333333333" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Generated with Rich https://www.textualize.io -->
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: "Fira Code";
|
||||||
|
src: local("FiraCode-Regular"),
|
||||||
|
url("https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@2.1.0/patched-fonts/FiraCode/Regular/complete/Fira%20Code%20Regular%20Nerd%20Font%20Complete.ttf") format("truetype");
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Fira Code";
|
||||||
|
src: local("FiraCode-Bold"),
|
||||||
|
url("https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@2.1.0/patched-fonts/FiraCode/Bold/complete/Fira%20Code%20Bold%20Nerd%20Font%20Complete.ttf") format("truetype");
|
||||||
|
font-style: bold;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-747138606-matrix {
|
||||||
|
font-family: Fira Code, monospace;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 24.4px;
|
||||||
|
font-variant-east-asian: full-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-747138606-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadow {
|
||||||
|
-webkit-filter: drop-shadow( 2px 5px 2px rgba(0, 0, 0, .7));
|
||||||
|
filter: drop-shadow( 2px 5px 2px rgba(0, 0, 0, .7));
|
||||||
|
}
|
||||||
|
.terminal-747138606-r1 { fill: #a6e3a1;font-weight: bold }
|
||||||
|
.terminal-747138606-r2 { fill: #c6d0f5 }
|
||||||
|
.terminal-747138606-r3 { fill: #94e2d5;font-weight: bold }
|
||||||
|
.terminal-747138606-r4 { fill: #f9e2af;font-weight: bold }
|
||||||
|
.terminal-747138606-r5 { fill: #8288a5 }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<defs>
|
||||||
|
<clipPath id="terminal-747138606-clip-terminal">
|
||||||
|
<rect x="0" y="0" width="548.0" height="316.2" />
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-0">
|
||||||
|
<rect x="0" y="1.5" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-1">
|
||||||
|
<rect x="0" y="25.9" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-2">
|
||||||
|
<rect x="0" y="50.3" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-3">
|
||||||
|
<rect x="0" y="74.7" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-4">
|
||||||
|
<rect x="0" y="99.1" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-5">
|
||||||
|
<rect x="0" y="123.5" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-6">
|
||||||
|
<rect x="0" y="147.9" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-7">
|
||||||
|
<rect x="0" y="172.3" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-8">
|
||||||
|
<rect x="0" y="196.7" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-9">
|
||||||
|
<rect x="0" y="221.1" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-10">
|
||||||
|
<rect x="0" y="245.5" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="terminal-747138606-line-11">
|
||||||
|
<rect x="0" y="269.9" width="549" height="24.65"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<rect fill="#1e1e2e" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="10.1667" y="1" width="565" height="365.2" rx="8"/><text class="terminal-747138606-title" fill="#c6d0f5" text-anchor="middle" x="282" y="27">help</text>
|
||||||
|
<g transform="translate(32,22)">
|
||||||
|
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
|
||||||
|
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
|
||||||
|
<circle cx="44" cy="0" r="7" fill="#28c840"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(18.166666666666664, 41) scale(.95)" clip-path="url(#terminal-747138606-clip-terminal)">
|
||||||
|
|
||||||
|
<g class="terminal-747138606-matrix">
|
||||||
|
<text class="terminal-747138606-r1" x="0" y="20" textLength="402.6" clip-path="url(#terminal-747138606-line-0)">Update MonoLisa with Nerd Fonts! </text><text class="terminal-747138606-r2" x="549" y="20" textLength="12.2" clip-path="url(#terminal-747138606-line-0)">
|
||||||
|
</text><text class="terminal-747138606-r2" x="549" y="44.4" textLength="12.2" clip-path="url(#terminal-747138606-line-1)">
|
||||||
|
</text><text class="terminal-747138606-r3" x="0" y="68.8" textLength="61" clip-path="url(#terminal-747138606-line-2)">usage</text><text class="terminal-747138606-r2" x="61" y="68.8" textLength="12.2" clip-path="url(#terminal-747138606-line-2)">:</text><text class="terminal-747138606-r2" x="549" y="68.8" textLength="12.2" clip-path="url(#terminal-747138606-line-2)">
|
||||||
|
</text><text class="terminal-747138606-r2" x="97.6" y="93.2" textLength="158.6" clip-path="url(#terminal-747138606-line-3)">make <recipe></text><text class="terminal-747138606-r2" x="549" y="93.2" textLength="12.2" clip-path="url(#terminal-747138606-line-3)">
|
||||||
|
</text><text class="terminal-747138606-r2" x="549" y="117.6" textLength="12.2" clip-path="url(#terminal-747138606-line-4)">
|
||||||
|
</text><text class="terminal-747138606-r4" x="0" y="142" textLength="146.4" clip-path="url(#terminal-747138606-line-5)">       patch</text><text class="terminal-747138606-r2" x="146.4" y="142" textLength="36.6" clip-path="url(#terminal-747138606-line-5)"> | </text><text class="terminal-747138606-r5" x="183" y="142" textLength="317.2" clip-path="url(#terminal-747138606-line-5)">add nerd fonts to MonoLisa</text><text class="terminal-747138606-r2" x="549" y="142" textLength="12.2" clip-path="url(#terminal-747138606-line-5)">
|
||||||
|
</text><text class="terminal-747138606-r4" x="0" y="166.4" textLength="146.4" clip-path="url(#terminal-747138606-line-6)">update-fonts</text><text class="terminal-747138606-r2" x="146.4" y="166.4" textLength="36.6" clip-path="url(#terminal-747138606-line-6)"> | </text><text class="terminal-747138606-r5" x="183" y="166.4" textLength="366" clip-path="url(#terminal-747138606-line-6)">move fonts and update fc-cache</text><text class="terminal-747138606-r2" x="549" y="166.4" textLength="12.2" clip-path="url(#terminal-747138606-line-6)">
|
||||||
|
</text><text class="terminal-747138606-r4" x="0" y="190.8" textLength="146.4" clip-path="url(#terminal-747138606-line-7)">       check</text><text class="terminal-747138606-r2" x="146.4" y="190.8" textLength="36.6" clip-path="url(#terminal-747138606-line-7)"> | </text><text class="terminal-747138606-r5" x="183" y="190.8" textLength="317.2" clip-path="url(#terminal-747138606-line-7)">check fc-list for MonoLisa</text><text class="terminal-747138606-r2" x="549" y="190.8" textLength="12.2" clip-path="url(#terminal-747138606-line-7)">
|
||||||
|
</text><text class="terminal-747138606-r4" x="0" y="215.2" textLength="146.4" clip-path="url(#terminal-747138606-line-8)">  update-src</text><text class="terminal-747138606-r2" x="146.4" y="215.2" textLength="36.6" clip-path="url(#terminal-747138606-line-8)"> | </text><text class="terminal-747138606-r5" x="183" y="215.2" textLength="292.8" clip-path="url(#terminal-747138606-line-8)">update nerd fonts source</text><text class="terminal-747138606-r2" x="549" y="215.2" textLength="12.2" clip-path="url(#terminal-747138606-line-8)">
|
||||||
|
</text><text class="terminal-747138606-r4" x="0" y="239.6" textLength="146.4" clip-path="url(#terminal-747138606-line-9)">        lint</text><text class="terminal-747138606-r2" x="146.4" y="239.6" textLength="36.6" clip-path="url(#terminal-747138606-line-9)"> | </text><text class="terminal-747138606-r5" x="183" y="239.6" textLength="231.8" clip-path="url(#terminal-747138606-line-9)">check shell scripts</text><text class="terminal-747138606-r2" x="549" y="239.6" textLength="12.2" clip-path="url(#terminal-747138606-line-9)">
|
||||||
|
</text><text class="terminal-747138606-r4" x="0" y="264" textLength="146.4" clip-path="url(#terminal-747138606-line-10)">       clean</text><text class="terminal-747138606-r2" x="146.4" y="264" textLength="36.6" clip-path="url(#terminal-747138606-line-10)"> | </text><text class="terminal-747138606-r5" x="183" y="264" textLength="244" clip-path="url(#terminal-747138606-line-10)">remove patched fonts</text><text class="terminal-747138606-r2" x="549" y="264" textLength="12.2" clip-path="url(#terminal-747138606-line-10)">
|
||||||
|
</text><text class="terminal-747138606-r4" x="0" y="288.4" textLength="146.4" clip-path="url(#terminal-747138606-line-11)">     h, help</text><text class="terminal-747138606-r2" x="146.4" y="288.4" textLength="36.6" clip-path="url(#terminal-747138606-line-11)"> | </text><text class="terminal-747138606-r5" x="183" y="288.4" textLength="170.8" clip-path="url(#terminal-747138606-line-11)">show this help</text><text class="terminal-747138606-r2" x="549" y="288.4" textLength="12.2" clip-path="url(#terminal-747138606-line-11)">
|
||||||
|
</text><text class="terminal-747138606-r2" x="549" y="312.8" textLength="12.2" clip-path="url(#terminal-747138606-line-12)">
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 9 KiB |
260
bin/font-patcher
260
bin/font-patcher
|
@ -1,11 +1,14 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# coding=utf8
|
# coding=utf8
|
||||||
# Nerd Fonts Version: 2.1.0
|
# Nerd Fonts Version: 2.2.1
|
||||||
# script version: 3.0.1
|
# Script version is further down
|
||||||
|
|
||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
version = "2.1.0"
|
# Change the script version when you edit this script:
|
||||||
|
script_version = "3.0.3"
|
||||||
|
|
||||||
|
version = "2.2.1"
|
||||||
projectName = "Nerd Fonts"
|
projectName = "Nerd Fonts"
|
||||||
projectNameAbbreviation = "NF"
|
projectNameAbbreviation = "NF"
|
||||||
projectNameSingular = projectName[:-1]
|
projectNameSingular = projectName[:-1]
|
||||||
|
@ -36,6 +39,122 @@ except ImportError:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# This is for experimenting
|
||||||
|
sys.path.insert(0, os.path.abspath(os.path.dirname(sys.argv[0])) + '/bin/scripts/name_parser/')
|
||||||
|
try:
|
||||||
|
from FontnameParser import FontnameParser
|
||||||
|
from FontnameTools import FontnameTools
|
||||||
|
FontnameParserOK = True
|
||||||
|
except ImportError:
|
||||||
|
FontnameParserOK = False
|
||||||
|
|
||||||
|
class TableHEADWriter:
|
||||||
|
""" Access to the HEAD table without external dependencies """
|
||||||
|
def getlong(self, pos = None):
|
||||||
|
""" Get four bytes from the font file as integer number """
|
||||||
|
if pos:
|
||||||
|
self.goto(pos)
|
||||||
|
return (ord(self.f.read(1)) << 24) + (ord(self.f.read(1)) << 16) + (ord(self.f.read(1)) << 8) + ord(self.f.read(1))
|
||||||
|
|
||||||
|
def getshort(self, pos = None):
|
||||||
|
""" Get two bytes from the font file as integer number """
|
||||||
|
if pos:
|
||||||
|
self.goto(pos)
|
||||||
|
return (ord(self.f.read(1)) << 8) + ord(self.f.read(1))
|
||||||
|
|
||||||
|
def putlong(self, num, pos = None):
|
||||||
|
""" Put number as four bytes into font file """
|
||||||
|
if pos:
|
||||||
|
self.goto(pos)
|
||||||
|
self.f.write(bytearray([(num >> 24) & 0xFF, (num >> 16) & 0xFF ,(num >> 8) & 0xFF, num & 0xFF]))
|
||||||
|
self.modified = True
|
||||||
|
|
||||||
|
def putshort(self, num, pos = None):
|
||||||
|
""" Put number as two bytes into font file """
|
||||||
|
if pos:
|
||||||
|
self.goto(pos)
|
||||||
|
self.f.write(bytearray([(num >> 8) & 0xFF, num & 0xFF]))
|
||||||
|
self.modified = True
|
||||||
|
|
||||||
|
def calc_checksum(self, start, end, checksum = 0):
|
||||||
|
""" Calculate a font table checksum, optionally ignoring another embedded checksum value (for table 'head') """
|
||||||
|
self.f.seek(start)
|
||||||
|
for i in range(start, end - 4, 4):
|
||||||
|
checksum += self.getlong()
|
||||||
|
checksum &= 0xFFFFFFFF
|
||||||
|
i += 4
|
||||||
|
extra = 0
|
||||||
|
for j in range(4):
|
||||||
|
if i + j <= end:
|
||||||
|
extra += ord(self.f.read(1))
|
||||||
|
extra = extra << 8
|
||||||
|
checksum = (checksum + extra) & 0xFFFFFFFF
|
||||||
|
return checksum
|
||||||
|
|
||||||
|
def find_head_table(self):
|
||||||
|
""" Search all tables for the HEAD table and store its metadata """
|
||||||
|
self.f.seek(4)
|
||||||
|
numtables = self.getshort()
|
||||||
|
self.f.seek(3*2, 1)
|
||||||
|
|
||||||
|
for i in range(numtables):
|
||||||
|
tab_name = self.f.read(4)
|
||||||
|
self.tab_check_offset = self.f.tell()
|
||||||
|
self.tab_check = self.getlong()
|
||||||
|
self.tab_offset = self.getlong()
|
||||||
|
self.tab_length = self.getlong()
|
||||||
|
if tab_name == b'head':
|
||||||
|
return
|
||||||
|
raise Exception('No HEAD table found')
|
||||||
|
|
||||||
|
def goto(self, where):
|
||||||
|
""" Go to a named location in the file or to the specified index """
|
||||||
|
if type(where) is str:
|
||||||
|
positions = {'checksumAdjustment': 2+2+4,
|
||||||
|
'flags': 2+2+4+4+4,
|
||||||
|
'lowestRecPPEM': 2+2+4+4+4+2+2+8+8+2+2+2+2+2,
|
||||||
|
}
|
||||||
|
where = self.tab_offset + positions[where]
|
||||||
|
self.f.seek(where)
|
||||||
|
|
||||||
|
|
||||||
|
def calc_full_checksum(self, check = False):
|
||||||
|
""" Calculate the whole file's checksum """
|
||||||
|
self.f.seek(0, 2)
|
||||||
|
self.end = self.f.tell()
|
||||||
|
full_check = self.calc_checksum(0, self.end, (-self.checksum_adj) & 0xFFFFFFFF)
|
||||||
|
if check and (0xB1B0AFBA - full_check) & 0xFFFFFFFF != self.checksum_adj:
|
||||||
|
sys.exit("Checksum of whole font is bad")
|
||||||
|
return full_check
|
||||||
|
|
||||||
|
def calc_table_checksum(self, check = False):
|
||||||
|
tab_check_new = self.calc_checksum(self.tab_offset, self.tab_offset + self.tab_length - 1, (-self.checksum_adj) & 0xFFFFFFFF)
|
||||||
|
if check and tab_check_new != self.tab_check:
|
||||||
|
sys.exit("Checksum of 'head' in font is bad")
|
||||||
|
return tab_check_new
|
||||||
|
|
||||||
|
def reset_table_checksum(self):
|
||||||
|
new_check = self.calc_table_checksum()
|
||||||
|
self.putlong(new_check, self.tab_check_offset)
|
||||||
|
|
||||||
|
def reset_full_checksum(self):
|
||||||
|
new_adj = (0xB1B0AFBA - self.calc_full_checksum()) & 0xFFFFFFFF
|
||||||
|
self.putlong(new_adj, 'checksumAdjustment')
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.f.close()
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.modified = False
|
||||||
|
self.f = open(filename, 'r+b')
|
||||||
|
|
||||||
|
self.find_head_table()
|
||||||
|
|
||||||
|
self.flags = self.getshort('flags')
|
||||||
|
self.lowppem = self.getshort('lowestRecPPEM')
|
||||||
|
self.checksum_adj = self.getlong('checksumAdjustment')
|
||||||
|
|
||||||
|
|
||||||
class font_patcher:
|
class font_patcher:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -44,7 +163,6 @@ class font_patcher:
|
||||||
self.config = None # class 'configparser.ConfigParser'
|
self.config = None # class 'configparser.ConfigParser'
|
||||||
self.sourceFont = None # class 'fontforge.font'
|
self.sourceFont = None # class 'fontforge.font'
|
||||||
self.octiconsExactEncodingPosition = True
|
self.octiconsExactEncodingPosition = True
|
||||||
self.fontlinuxExactEncodingPosition = True
|
|
||||||
self.patch_set = None # class 'list'
|
self.patch_set = None # class 'list'
|
||||||
self.font_dim = None # class 'dict'
|
self.font_dim = None # class 'dict'
|
||||||
self.onlybitmaps = 0
|
self.onlybitmaps = 0
|
||||||
|
@ -62,7 +180,8 @@ class font_patcher:
|
||||||
self.sourceFont = fontforge.open(self.args.font, 1) # 1 = ("fstypepermitted",))
|
self.sourceFont = fontforge.open(self.args.font, 1) # 1 = ("fstypepermitted",))
|
||||||
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_font_names()
|
self.setup_version()
|
||||||
|
self.setup_name_backup()
|
||||||
self.remove_ligatures()
|
self.remove_ligatures()
|
||||||
make_sure_path_exists(self.args.outputdir)
|
make_sure_path_exists(self.args.outputdir)
|
||||||
self.check_position_conflicts()
|
self.check_position_conflicts()
|
||||||
|
@ -81,7 +200,7 @@ class font_patcher:
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
|
|
||||||
print("{} Patcher v{} executing\n".format(projectName, version))
|
print("{} Patcher v{} ({}) executing\n".format(projectName, version, script_version))
|
||||||
|
|
||||||
if self.args.single:
|
if self.args.single:
|
||||||
# Force width to be equal on all glyphs to ensure the font is considered monospaced on Windows.
|
# Force width to be equal on all glyphs to ensure the font is considered monospaced on Windows.
|
||||||
|
@ -124,19 +243,53 @@ class font_patcher:
|
||||||
|
|
||||||
if symfont:
|
if symfont:
|
||||||
symfont.close()
|
symfont.close()
|
||||||
print("\nDone with Patch Sets, generating font...")
|
|
||||||
|
|
||||||
|
# The grave accent and fontforge:
|
||||||
|
# If the type is 'auto' fontforge changes it to 'mark' on export.
|
||||||
|
# We can not prevent this. So set it to 'baseglyph' instead, as
|
||||||
|
# that resembles the most common expectations.
|
||||||
|
# This is not needed with fontforge March 2022 Release anymore.
|
||||||
|
if "grave" in self.sourceFont:
|
||||||
|
self.sourceFont["grave"].glyphclass="baseglyph"
|
||||||
|
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
# the `PfEd-comments` flag is required for Fontforge to save '.comment' and '.fontlog'.
|
# the `PfEd-comments` flag is required for Fontforge to save '.comment' and '.fontlog'.
|
||||||
if self.sourceFont.fullname != None:
|
if self.sourceFont.fullname != None:
|
||||||
self.sourceFont.generate(self.args.outputdir + "/" + self.sourceFont.fullname + self.extension, flags=(str('opentype'), str('PfEd-comments')))
|
outfile = self.args.outputdir + "/" + self.sourceFont.fullname + self.extension
|
||||||
print("\nGenerated: {}".format(self.sourceFont.fontname))
|
self.sourceFont.generate(outfile, flags=(str('opentype'), str('PfEd-comments')))
|
||||||
|
message = "\nGenerated: {} in '{}'".format(self.sourceFont.fullname, outfile)
|
||||||
else:
|
else:
|
||||||
self.sourceFont.generate(self.args.outputdir + "/" + self.sourceFont.cidfontname + self.extension, flags=(str('opentype'), str('PfEd-comments')))
|
outfile = self.args.outputdir + "/" + self.sourceFont.cidfontname + self.extension
|
||||||
print("\nGenerated: {}".format(self.sourceFont.fullname))
|
self.sourceFont.generate(outfile, flags=(str('opentype'), str('PfEd-comments')))
|
||||||
|
message = "\nGenerated: {} in '{}'".format(self.sourceFont.fontname, outfile)
|
||||||
|
|
||||||
|
# Adjust flags that can not be changed via fontforge
|
||||||
|
try:
|
||||||
|
source_font = TableHEADWriter(self.args.font)
|
||||||
|
dest_font = TableHEADWriter(outfile)
|
||||||
|
if source_font.flags & 0x08 == 0 and dest_font.flags & 0x08 != 0:
|
||||||
|
print("Changing flags from 0x{:X} to 0x{:X}".format(dest_font.flags, dest_font.flags & ~0x08))
|
||||||
|
dest_font.putshort(dest_font.flags & ~0x08, 'flags') # clear 'ppem_to_int'
|
||||||
|
if source_font.lowppem != dest_font.lowppem:
|
||||||
|
print("Changing lowestRecPPEM from {} to {}".format(dest_font.lowppem, source_font.lowppem))
|
||||||
|
dest_font.putshort(source_font.lowppem, 'lowestRecPPEM')
|
||||||
|
if dest_font.modified:
|
||||||
|
dest_font.reset_table_checksum()
|
||||||
|
dest_font.reset_full_checksum()
|
||||||
|
except Exception as error:
|
||||||
|
print("Can not handle font flags ({})".format(repr(error)))
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
source_font.close()
|
||||||
|
dest_font.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
print(message)
|
||||||
|
|
||||||
if self.args.postprocess:
|
if self.args.postprocess:
|
||||||
subprocess.call([self.args.postprocess, self.args.outputdir + "/" + self.sourceFont.fullname + self.extension])
|
subprocess.call([self.args.postprocess, outfile])
|
||||||
print("\nPost Processed: {}".format(self.sourceFont.fullname))
|
print("\nPost Processed: {}".format(outfile))
|
||||||
|
|
||||||
|
|
||||||
def setup_arguments(self):
|
def setup_arguments(self):
|
||||||
|
@ -166,12 +319,14 @@ class font_patcher:
|
||||||
parser.add_argument('-ext', '--extension', dest='extension', default="", type=str, nargs='?', help='Change font file type to create (e.g., ttf, otf)')
|
parser.add_argument('-ext', '--extension', dest='extension', default="", type=str, nargs='?', help='Change font file type to create (e.g., ttf, otf)')
|
||||||
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)')
|
||||||
|
|
||||||
# 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)
|
||||||
progressbars_group_parser.add_argument('--progressbars', dest='progressbars', action='store_true', help='Show percentage completion progress bars per Glyph Set')
|
progressbars_group_parser.add_argument('--progressbars', dest='progressbars', action='store_true', help='Show percentage completion progress bars per Glyph Set')
|
||||||
progressbars_group_parser.add_argument('--no-progressbars', dest='progressbars', action='store_false', help='Don\'t show percentage completion progress bars per Glyph Set')
|
progressbars_group_parser.add_argument('--no-progressbars', dest='progressbars', action='store_false', help='Don\'t show percentage completion progress bars per Glyph Set')
|
||||||
parser.set_defaults(progressbars=True)
|
parser.set_defaults(progressbars=True)
|
||||||
|
parser.add_argument('--also-windows', dest='alsowindows', default=False, action='store_true', help='Create two fonts, the normal and the --windows version')
|
||||||
|
|
||||||
# symbol fonts to include arguments
|
# symbol fonts to include arguments
|
||||||
sym_font_group = parser.add_argument_group('Symbol Fonts')
|
sym_font_group = parser.add_argument_group('Symbol Fonts')
|
||||||
|
@ -189,6 +344,9 @@ class font_patcher:
|
||||||
|
|
||||||
self.args = parser.parse_args()
|
self.args = parser.parse_args()
|
||||||
|
|
||||||
|
if self.args.makegroups and not FontnameParserOK:
|
||||||
|
sys.exit(projectName + ": FontnameParser module missing (bin/scripts/name_parser/Fontname*), can not --makegroups".format(projectName))
|
||||||
|
|
||||||
# if you add a new font, set it to True here inside the if condition
|
# if you add a new font, set it to True here inside the if condition
|
||||||
if self.args.complete:
|
if self.args.complete:
|
||||||
self.args.fontawesome = True
|
self.args.fontawesome = True
|
||||||
|
@ -219,6 +377,9 @@ class font_patcher:
|
||||||
font_complete = False
|
font_complete = False
|
||||||
self.args.complete = font_complete
|
self.args.complete = font_complete
|
||||||
|
|
||||||
|
if self.args.alsowindows:
|
||||||
|
self.args.windows = 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.
|
||||||
|
@ -239,7 +400,17 @@ class font_patcher:
|
||||||
# ])
|
# ])
|
||||||
|
|
||||||
|
|
||||||
|
def setup_name_backup(self):
|
||||||
|
""" Store the original font names to be able to rename the font multiple times """
|
||||||
|
self.original_fontname = self.sourceFont.fontname
|
||||||
|
self.original_fullname = self.sourceFont.fullname
|
||||||
|
self.original_familyname = self.sourceFont.familyname
|
||||||
|
|
||||||
|
|
||||||
def setup_font_names(self):
|
def setup_font_names(self):
|
||||||
|
self.sourceFont.fontname = self.original_fontname
|
||||||
|
self.sourceFont.fullname = self.original_fullname
|
||||||
|
self.sourceFont.familyname = self.original_familyname
|
||||||
verboseAdditionalFontNameSuffix = " " + projectNameSingular
|
verboseAdditionalFontNameSuffix = " " + projectNameSingular
|
||||||
if self.args.windows: # attempt to shorten here on the additional name BEFORE trimming later
|
if self.args.windows: # attempt to shorten here on the additional name BEFORE trimming later
|
||||||
additionalFontNameSuffix = " " + projectNameAbbreviation
|
additionalFontNameSuffix = " " + projectNameAbbreviation
|
||||||
|
@ -285,6 +456,27 @@ class font_patcher:
|
||||||
additionalFontNameSuffix += " M"
|
additionalFontNameSuffix += " M"
|
||||||
verboseAdditionalFontNameSuffix += " Mono"
|
verboseAdditionalFontNameSuffix += " Mono"
|
||||||
|
|
||||||
|
if FontnameParserOK and self.args.makegroups:
|
||||||
|
use_fullname = type(self.sourceFont.fullname) == str # Usually the fullname is better to parse
|
||||||
|
# Use fullname if it is 'equal' to the fontname
|
||||||
|
if self.sourceFont.fullname:
|
||||||
|
use_fullname |= self.sourceFont.fontname.lower() == FontnameTools.postscript_char_filter(self.sourceFont.fullname).lower()
|
||||||
|
# Use fullname for any of these source fonts (that are impossible to disentangle from the fontname, we need the blanks)
|
||||||
|
for hit in [ 'Meslo' ]:
|
||||||
|
use_fullname |= self.sourceFont.fontname.lower().startswith(hit.lower())
|
||||||
|
parser_name = self.sourceFont.fullname if use_fullname else self.sourceFont.fontname
|
||||||
|
# Gohu fontnames hide the weight, but the file names are ok...
|
||||||
|
if parser_name.startswith('Gohu'):
|
||||||
|
parser_name = os.path.splitext(os.path.basename(self.args.font))[0]
|
||||||
|
n = FontnameParser(parser_name)
|
||||||
|
if not n.parse_ok:
|
||||||
|
print("Have only minimal naming information, check resulting name. Maybe omit --makegroups option")
|
||||||
|
n.drop_for_powerline()
|
||||||
|
n.enable_short_families(True, "Noto")
|
||||||
|
n.set_for_windows(self.args.windows)
|
||||||
|
|
||||||
|
# All the following stuff is ignored in makegroups-mode
|
||||||
|
|
||||||
# basically split the font name around the dash "-" to get the fontname and the style (e.g. Bold)
|
# basically split the font name around the dash "-" to get the fontname and the style (e.g. Bold)
|
||||||
# this does not seem very reliable so only use the style here as a fallback if the font does not
|
# this does not seem very reliable so only use the style here as a fallback if the font does not
|
||||||
# have an internal style defined (in sfnt_names)
|
# have an internal style defined (in sfnt_names)
|
||||||
|
@ -343,8 +535,9 @@ class font_patcher:
|
||||||
familyname += " Mono"
|
familyname += " Mono"
|
||||||
|
|
||||||
# Don't truncate the subfamily to keep fontname unique. MacOS treats fonts with
|
# Don't truncate the subfamily to keep fontname unique. MacOS treats fonts with
|
||||||
# the same name as the same font, even if subFamily is different.
|
# the same name as the same font, even if subFamily is different. Make sure to
|
||||||
fontname += '-' + subFamily
|
# keep the resulting fontname (PostScript name) valid by removing spaces.
|
||||||
|
fontname += '-' + subFamily.replace(' ', '')
|
||||||
|
|
||||||
# rename font
|
# rename font
|
||||||
#
|
#
|
||||||
|
@ -418,6 +611,7 @@ class font_patcher:
|
||||||
fullname = replace_font_name(fullname, additionalFontNameReplacements2)
|
fullname = replace_font_name(fullname, additionalFontNameReplacements2)
|
||||||
fontname = replace_font_name(fontname, additionalFontNameReplacements2)
|
fontname = replace_font_name(fontname, additionalFontNameReplacements2)
|
||||||
|
|
||||||
|
if not (FontnameParserOK and self.args.makegroups):
|
||||||
# replace any extra whitespace characters:
|
# replace any extra whitespace characters:
|
||||||
self.sourceFont.familyname = " ".join(familyname.split())
|
self.sourceFont.familyname = " ".join(familyname.split())
|
||||||
self.sourceFont.fullname = " ".join(fullname.split())
|
self.sourceFont.fullname = " ".join(fullname.split())
|
||||||
|
@ -427,9 +621,18 @@ class font_patcher:
|
||||||
self.sourceFont.appendSFNTName(str('English (US)'), str('Family'), self.sourceFont.familyname)
|
self.sourceFont.appendSFNTName(str('English (US)'), str('Family'), self.sourceFont.familyname)
|
||||||
self.sourceFont.appendSFNTName(str('English (US)'), str('Compatible Full'), self.sourceFont.fullname)
|
self.sourceFont.appendSFNTName(str('English (US)'), str('Compatible Full'), self.sourceFont.fullname)
|
||||||
self.sourceFont.appendSFNTName(str('English (US)'), str('SubFamily'), subFamily)
|
self.sourceFont.appendSFNTName(str('English (US)'), str('SubFamily'), subFamily)
|
||||||
|
else:
|
||||||
|
fam_suffix = projectNameSingular if not self.args.windows else projectNameAbbreviation
|
||||||
|
fam_suffix += ' Mono' if self.args.single else ''
|
||||||
|
n.inject_suffix(verboseAdditionalFontNameSuffix, additionalFontNameSuffix, fam_suffix)
|
||||||
|
n.rename_font(self.sourceFont)
|
||||||
|
|
||||||
self.sourceFont.comment = projectInfo
|
self.sourceFont.comment = projectInfo
|
||||||
self.sourceFont.fontlog = projectInfo
|
self.sourceFont.fontlog = projectInfo
|
||||||
|
|
||||||
|
|
||||||
|
def setup_version(self):
|
||||||
|
""" Add the Nerd Font version to the original version """
|
||||||
# print("Version was {}".format(sourceFont.version))
|
# print("Version was {}".format(sourceFont.version))
|
||||||
if self.sourceFont.version != None:
|
if self.sourceFont.version != None:
|
||||||
self.sourceFont.version += ";" + projectName + " " + version
|
self.sourceFont.version += ";" + projectName + " " + version
|
||||||
|
@ -463,8 +666,6 @@ class font_patcher:
|
||||||
# Prevent glyph encoding position conflicts between glyph sets
|
# Prevent glyph encoding position conflicts between glyph sets
|
||||||
if self.args.fontawesome and self.args.octicons:
|
if self.args.fontawesome and self.args.octicons:
|
||||||
self.octiconsExactEncodingPosition = False
|
self.octiconsExactEncodingPosition = False
|
||||||
if self.args.fontawesome or self.args.octicons:
|
|
||||||
self.fontlinuxExactEncodingPosition = False
|
|
||||||
|
|
||||||
|
|
||||||
def setup_patch_set(self):
|
def setup_patch_set(self):
|
||||||
|
@ -603,7 +804,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': self.fontlinuxExactEncodingPosition, 'SymStart': 0xF100, 'SymEnd': 0xF12D, 'SrcStart': 0xF300, 'SrcEnd': 0xF32D, '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.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
|
||||||
|
@ -653,7 +854,9 @@ class font_patcher:
|
||||||
# Ignore the y-values, os2_winXXXXX values set above are used for line height
|
# Ignore the y-values, os2_winXXXXX values set above are used for line height
|
||||||
#
|
#
|
||||||
# 0x00-0x17f is the Latin Extended-A range
|
# 0x00-0x17f is the Latin Extended-A range
|
||||||
for glyph in range(0x00, 0x17f):
|
for glyph in range(0x21, 0x17f):
|
||||||
|
if glyph in range(0x7F, 0xBF):
|
||||||
|
continue # ignore special characters like '1/4' etc
|
||||||
try:
|
try:
|
||||||
(_, _, xmax, _) = self.sourceFont[glyph].boundingBox()
|
(_, _, xmax, _) = self.sourceFont[glyph].boundingBox()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -665,6 +868,17 @@ class font_patcher:
|
||||||
|
|
||||||
# Calculate font height
|
# Calculate font height
|
||||||
self.font_dim['height'] = abs(self.font_dim['ymin']) + self.font_dim['ymax']
|
self.font_dim['height'] = abs(self.font_dim['ymin']) + self.font_dim['ymax']
|
||||||
|
if self.font_dim['height'] == 0:
|
||||||
|
# This can only happen if the input font is empty
|
||||||
|
# Assume we are using our prepared templates
|
||||||
|
self.font_dim = {
|
||||||
|
'xmin' : 0,
|
||||||
|
'ymin' : -self.sourceFont.descent,
|
||||||
|
'xmax' : self.sourceFont.em,
|
||||||
|
'ymax' : self.sourceFont.ascent,
|
||||||
|
'width' : self.sourceFont.em,
|
||||||
|
'height': abs(self.sourceFont.descent) + self.sourceFont.ascent,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_scale_factor(self, sym_dim):
|
def get_scale_factor(self, sym_dim):
|
||||||
|
@ -1030,6 +1244,14 @@ def main():
|
||||||
check_fontforge_min_version()
|
check_fontforge_min_version()
|
||||||
patcher = font_patcher()
|
patcher = font_patcher()
|
||||||
patcher.patch()
|
patcher.patch()
|
||||||
|
print("\nDone with Patch Sets, generating font...\n")
|
||||||
|
patcher.setup_font_names()
|
||||||
|
patcher.generate()
|
||||||
|
# This mainly helps to improve CI runtime
|
||||||
|
if patcher.args.alsowindows:
|
||||||
|
patcher.args.windows = True
|
||||||
|
patcher.setup_font_names()
|
||||||
|
patcher.generate()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue