Skip to content

Commit

Permalink
programming fonts
Browse files Browse the repository at this point in the history
  • Loading branch information
zhimoe committed Feb 19, 2025
0 parents commit fc6c1c9
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
.DS_Store
__MACOSX
Binary file added Argon as SFMono v1.101.zip
Binary file not shown.
Binary file added Argon as SFMono v1.200.zip
Binary file not shown.
Binary file added Aurulent patched.zip
Binary file not shown.
Binary file added CommitMono pateched.zip
Binary file not shown.
Binary file added FangSongCode.zip
Binary file not shown.
Binary file added FiraCode patched.zip
Binary file not shown.
Binary file added FiraCode redesign dehinted.zip
Binary file not shown.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
> Buy a 4K+ resolution monitor to overcome your programming font addiction, and get the fucking job done!
### Screenshots
Fira Code
![FiraCode](screenshots/firacode.png)
Aurulent
![Aurulent](screenshots/aurulent.png)
Source Code Pro
![SourceCodePro](screenshots/scp.png)

### Best fonts for programming
1. Aurulent: It looks like it was written by an artisan pen, add missing glyphs from fira code, my favorite.
2. Source Code Pro: Simple and crisp, optimized the 0 1 4 r i l glyphs, make it applies to both prose and coding.
3. Fira Code: [Most popular coding font](https://github.com/tonsky/FiraCode), add some powerline glyphs and redesigned the r glyph.
4. 聚珍新仿: 搭配上面的Source Code Pro的中文字体,适用于注释, 也适合电子书阅读.
5. 字语青梅硬笔: 手写中文字体,适用于excalidraw手画风格的架构图.
6. FangSongCode: Monaspace Argon with chinese glyphs from 聚珍新仿, see more on [支持中文的等宽编程字体-FangSongCode](https://zhi.moe/post/programming-font-fangsongcode/)
7. Monaspace Argon: programming font from [GitHub Next Labs](https://monaspace.githubnext.com/#learn-more), the best!

### Tips:
1. you can rename the family name by [fontname.py](https://github.com/chrissimpkins/fontname.py):
```bash
python fontname.py "Monaspace" MonaspaceArgon-Regular.ttf
```

2. for non-4K monitor, you need hint the truetype font:
```bash
sudo apt install ttfautohint
for f in ./*.ttf; do ttfautohint ${f} out/${f} --stem-width-mode qqq --composites ;done
```

3. patch powerline for your font:
```bash
docker run --rm -v ./:/in:Z -v ./patched:/out:Z nerdfonts/patcher --use-single-width-glyphs --boxdrawing --powerline --powerlineextra
```

4. 中英文合并的字体中文间距很大的问题解决方案
```python
from fontTools.ttLib import TTFont
font = TTFont('C:\\Documents\\YaHei.ttf')

# xAvgCharWidth只能脚本设置,fontforge计算的不对
# 设置成中文字符宽度的1/2,否则部分windows软件(字体预览、notepad)中文间距很大
font['OS/2'].xAvgCharWidth = 500
# 下面两个在fontforge也可以设置,设置后terminal可以识别成等宽字体
font['OS/2'].panose.bProportion = 9 # 9表示monospaced,0表示any
font['OS/2'].panose.bFamilyType = 2 # 2表示Latin: Text and Display
font.save('C:\\Documents\\YaHei-R.ttf')
# 注意,大部分terminal展示非ascii字符的宽度是ascii字符*2,
# 由于FangSongCode的ASCII字符是600,所以会用1200宽度展示中文字符,导致看着间距很大并且不是居中
# 目前无解,只能选用中英2:1的字体中文才能正常展示,Yahei:Consolas=1000:550,间距看着会正常一点
```

Binary file added SourceCodePro.zip
Binary file not shown.
99 changes: 99 additions & 0 deletions fontname.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import sys
import os

from fontTools import ttLib

def main(argv):
# command argument tests
if len(argv) < 2:
exit_with_error_msg(f"""
[fontname.py] ERROR: you did not include enough arguments to the script."
Usage: python3 fontname.py [NEW FAMILY NAME] [FONT PATH 1] <FONT PATH 2 ...>"
""")
try:
new_family_name = str(argv[0]) # the first argument is the new typeface name
except Exception as e:
exit_with_error_msg(f"[fontname.py] ERROR: unable to convert argument 1 to string.")

# all remaining arguments on command line are file paths to fonts
font_path_list = argv[1:]

# iterate through all paths provided on command line and rename to `new_font_name` defined by user
for font_path in font_path_list:
if not file_exists(font_path):
exit_with_error_msg(f"[fontname.py] ERROR: the path '{font_path}' does not appear to be a valid file path.")

tt = ttLib.TTFont(font_path)
name_records = tt["name"].names
# ------------------
style = get_font_style(font_path, name_records)

"""
PlatformID == 1
NameRecord.nameID | String ID
record.nameID==0 Copyright
record.nameID==1 Family
record.nameID==2 Styles(SubFamily): Regular/Bold/Italic/Bold Italic
record.nameID==3 UniqueID
record.nameID==4 Fullname: {family} {style}
record.nameID==5 Version
record.nameID==6 Postscript Fullname: {family no space}-{style}
record.nameID==11 Preferred Family:
record.nameID==12 Preferred Styles:
"""

# Postscript name
# - no spaces allowed in family name or the PostScript suffix. should be dash delimited
postscript_name = f"{new_family_name.replace(' ', '')}-{style.replace(' ', '')}"

# modify the opentype table data in memory with updated values
for i in range(len(name_records) - 1, -1, -1):
record = name_records[i]
if record.nameID == 1:
record.string = new_family_name
elif record.nameID == 4:
record.string = f"{new_family_name} {style}"
elif record.nameID == 6:
record.string = postscript_name
else:
...
# TODO: delete other table data like WS family name
# del name_records[i]
try:
tt.save(font_path)
print(f"[OK] Updated '{font_path}' with the name '{new_family_name}'")
except Exception as e:
exit_with_error_msg(f"""
[fontname.py] ERROR: unable to write new name to OpenType name table for {font_path}.
""")


def get_font_style(font_path, name_records) -> str:
style = ""
# determine font style for this file path from name record nameID 2
for record in name_records:
if record.nameID == 2:
style = str(record)
break

# test that a style name was found in the OpenType tables of the font
if len(style) == 0:
exit_with_error_msg(f"""
[fontname.py] ERROR: unable to detect the font style from the OpenType name table in {font_path}.
Unable to complete execution of the script.
""")
return style


def exit_with_error_msg(err_msg):
sys.stderr.write(err_msg)
sys.exit(1)


def file_exists(filepath):
"""Tests for existence of a file on the string filepath"""
return os.path.exists(filepath) and os.path.isfile(filepath)


if __name__ == "__main__":
main(sys.argv[1:])
Binary file added screenshots/aurulent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/firacode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/scp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions screenshots/screenshot_url
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
## screenshots config:
https://carbon.now.sh/?bg=rgba%28171%2C+184%2C+195%2C+1%29&t=3024-night&wt=sharp&l=auto&width=680&ds=true&dsyoff=20px&dsblur=68px&wc=true&wa=true&pv=0px&ph=0px&ln=false&fl=1&fm=monospace&fs=14px&lh=133%25&si=false&es=2x&wm=false&code=%252F%252F%2520Fira%2520Code%2520redesign%2520r%2520glyph%252C%2520narrow%2520width%2520to%2520600%250Aconst%2520pluckDeep%2520%253D%2520key%2520%253D%253E%2520obj%2520%253D%253E%2520key.split%28%27.%27%29.reduce%28%28accum%252C%2520key%29%2520%253D%253E%2520accum%255Bkey%255D%252C%2520obj%29%250A%250Aconst%2520compose%2520%253D%2520%28...fns%29%2520%253D%253E%2520res%2520%253D%253E%2520fns.reduce%28%28accum%252C%2520next%29%2520%253D%253E%2520next%28accum%29%252C%2520res%29%250A%250Aconst%2520unfold%2520%253D%2520%28f%252C%2520seed%29%2520%253D%253E%2520%257B%250A%2520%2520const%2520go%2520%253D%2520%28f%252C%2520seed%252C%2520acc%29%2520%253D%253E%2520%257B%250A%2520%2520%2520%2520const%2520res%2520%253D%2520f%28seed%29%250A%2520%2520%2520%2520return%2520res%2520%253F%2520go%28f%252C%2520res%255B1%255D%252C%2520acc.concat%28%255Bres%255B0%255D%255D%29%29%2520%253A%2520acc%250A%2520%2520%257D%250A%2520%2520return%2520go%28f%252C%2520seed%252C%2520%255B%255D%29%250A%257D
1 change: 1 addition & 0 deletions update
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
git checkout --orphan tmp && git add -A && git commit -am "programming fonts" && git branch -D master && git branch -m master && git push -f origin master

0 comments on commit fc6c1c9

Please sign in to comment.