您使用终端吗? Terminal.app? iTerm2?超?或者是其他东西?
那您用什么字体呢?门洛? Consolas?混蛋?这就是今天的故事。
-
目标读者
- 想要在终端和编辑器中使用超酷等宽字体的人。
- 想要使用FontForge Python使用现有字体的人。
编程字体SF Mono Square
我使用Ricty已有很长时间了,但是我一直非常注重自己制作字体。由于许可证的原因,无法分发创建的产品,但是Homebrew使任何人都可以引入它。
1 2 3 | brew tap delphinus/sfmono-square brew install sfmono-square # /usr/local/opt/sfmono-square/share/fonts にフォントが作成されます |
SF Mono Square具有以下功能。
- 仓库:delphinus /自制-sfmono-square
-
Apple的正版SF Mono用于半角字体,而Migu 1M用于全角字体。
- 您可以在以下Qiita文章中阅读有关旧金山的更多信息。
- 探索San Francisco Fonts-Qiita
- 调整字形,以使半角或全角的宽度正好为1:2。
- 可视化双字节空间。
-
书呆子字形(包括所谓的电力线字形)的添加。
- 许多其他字形调整。
简而言之,它是Ricty的SF Mono版本+α。
-
显示TypeScript代码的示例
-
日语很完美
-
配有从电力线字形和书呆子字体派生的各种图标
SF Mono是最近的macOS和Xcode的标准配置。这是一个有趣的许可证,但是除非您出售或分发字体文件本身,否则以这种方式修改和使用它似乎没有问题(我与Apple联系)。这适用于macOS中包含的所有字体,而不仅限于SF Mono。好胖
下面,我将描述如何决定创建SF Mono Square,然后将解释如何实际创建字体。
编程字体需要什么
使用终端或编辑器时应为字体选择什么?这是我认为重要的清单(至少对我而言)。
1.必须为等宽字体
如果您问10个人,则10个人会同意。用比例字体编码是不可能的。
2.字体必须适合在CLI环境或IDE
中使用。
"工作"包括浏览日志和文档以及编码。最重要的是,这些字符应易于阅读,并且不应与其他字符混淆。具体而言,以下几点至关重要。
-
一眼就能分辨出
0 ,o ,o ,1 ,i ,i ,l 。 - 适当的字符间距和行间距。
对许多人来说,这些应该是强制性的。其他一些"编程"字体具有以下优点:
3.支持双字节字符
有终端应用程序,例如
iTerm2,可以为半角和全角指定不同的字体,但是仍有许多应用程序,例如Terminal.app,仅允许您指定一种字体。如果您想使用这样的应用程序,或者只是想拥有统一的外观,则在一种字体中包含半角或全角字形会很好。
M FONTS的M系列,Ricty,Chintz Gothic等都很有名。特别是Ricty是一种具有主导世界的各种独特功能(稍后描述)的字体。
-
Ricty中的文本示例。
4.支持连字(连字)
这可能与2.易于阅读背道而驰,但是它之所以受欢迎,是因为它比CLI环境中的表达更具表达力。
费拉密码,Hasklig,Iosevka等很有名。上述Sarasa Gothic是从Iosevka派生的一种字体,因此它支持连字(可能是唯一的日语字体)。
-
Sarasa Gothic中的文本示例。
但是,这次创建的SF Mono Square不支持这种连字。有时在技术上很难制造,但就个人而言并不是那么重要...我想下次尝试。
5.支持各种外部字符
在以前不经常使用连字的年代,对于那些不愿使用CLI(主要是Vim)表现力的人来说,Powerline是一场革命。我使用了一个补丁程序为字体添加了新的外部字符(字形),以便获得很酷的状态行并在Vim和各种shell中进行提示。
这个想法也影响了那些制作新程序字体的人。在那之后,吸引人的是,一种又一种的字体可用于电力线。即使现在Powerline本身已经放慢了速度,包含所谓的" Powerline标志符号"的字体也证明它们是用于编程的。
-
当您要使状态行看起来很酷时,这是必不可少的。
另外,Nerd Fonts是一个使这个想法更进一步的项目。从站点上可以看到,我们已经发布了一个补丁,该补丁将用于Web应用程序的UI图标的字形(例如Font Awesome和Octicons)放置在字体的外部字符区域中。如果您走的很远,则很容易在2.中看到,并且我认为它并没有造成混淆,因此最好不要过分依赖它。
Ricty怎么了
好吧,这是里奇(Ricty)来了几次。可以说这是日语环境中编程字体的确定版本,即使发布了很长时间也是如此。可以更快地查看官方网站的功能,但是其中有一些功能。
-
使用Ricty的文字范例
- 流行的Inconsolata用于半角字体。
- 源自Migu 1M的易于阅读的双字节字符。特别是,易于区分浊音标记和半浊音标记的假名字符是独特的。
-
可视化双字节空间。
- 许多编辑器功能都可以执行此操作,但是现在只需安装字体即可实现。
- 其他各种。
好吧,我对此感兴趣的是Inconsolata粗体字。当我使用Ricty在终端中编写代码时,感觉宽度很小。 SF Mono没有那个。
-
Ricty 16pt
-
SF Mono 14pt
这是从哪里来的?字体的纵横比是不同的
检查FontForge中的字体详细信息
FontForge是一个开源字体编辑软件。与Mac / Windows / Linux兼容。对于Mac,您可以从官方网站下载它,也可以使用Homebrew安装它。
1 2 | brew install fontforge brew cask install fontforge |
在Finder中双击
现在,我们在FontForge中打开Inconsolata和SF Mono。您可以从以下获得每个。
- Inconsolata→Google字体
- SF Mono→字体--Apple Developer
<表格>
tr>
header>
<身体>
![スクリーンショット 2018-12-16 15.57.08.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2Fbfcf0870-e9a1-9d97-5124-b968ea2617c6.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=1aaab000419d49fee6fc30c0eb21ec0a)
![スクリーンショット 2018-12-16 15.57.12.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2Fc0623789-f420-7cb9-6579-fec8ff8b6fa5.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=df0a3d6fb12e8a722ad6b6a4d8793f9c)
tr>
tbody>
table>
我刚刚打开了相同的" A"字形。如果查看此内容,可以看到围绕该字形的矩形在Inconsolata中垂直拉长。长宽比的计算如下。
<表格>
tr>
header>
<身体>
tr>
tr>
tbody>
table>
- 在此,"垂直"使用"上升下降"的值。单击此处以获取术语的详细说明。
SF Mono纵横比,您在某处看到过吗?所以。黄金比例!这是SF Mono字形看起来很漂亮的秘密。
日语字体长宽比
这里的问题是日语字体。可以自由确定字母字符的长宽比,但是假名和假名在日语中基本上是正方形。您必须管理纵横比才能将其与SF Mono结合使用。现在,我们比较一下SF Mono和Migu 1M度量标准(确定字体格式的数字)。
<表格>
tr>
header>
<身体>
tr>
tr>
tbody>
table>
<表格>
tr>
header>
<身体>
![SF Mono Ascent-Descent.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2F7b5f6bb8-0e2f-21e4-c49d-112fb8be59e1.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=e45e6663920c1283cb0d705306350846)
![Migu 1M Ascent-Descent.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2F30a470c8-c3d9-c3f3-e530-60563eaca4c7.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=b034133e215472e62ec4420d801cb566)
tr>
tbody>
table>
如果并排查看,则字形除了长宽比之外,排列方式也有所不同。具体来说,Migu 1M的Ascent范围更广,因此通常低于SF Mono。换句话说,有必要在保持字体的纵横比均匀的同时上下移动字体一点。
制作字体
还有许多其他要考虑的问题,但首先让我们实际创建一种字体。
FontForge允许您在GUI中自由调整字体,但是如果要对所有字形都进行同样的调整,则使用脚本更容易。 FontForge可以使用Python自动化,因此可以使用它。
简单来说,如果要组合两种字体中的一种,则可以编写如下。
1 2 3 4 5 6 | import fontforge font = fontforge.font() font.mergeFonts('SFMono-Regular.otf') font.mergeFonts('migu-1m-regular.ttf') font.generate('merged-font.ttf') |
很简单!但是,这不允许您调整字形的大小和位置,并且不包括字体名称或其他信息。要进行这些设置,需要进行大量的调整。让我们跟随下面的实际脚本。
SF Mono Square的详细说明
下面的存储库中总结了用于创建
字体的脚本(也可以用作自制水龙头)。让我们阅读每个脚本。
- 仓库:delphinus /自制-sfmono-square
自制公式-sfmono-square.rb
从此处单击↑之类的文件名,以打开GitHub的链接。
这是一个Homebrew配置文件。安装必要的应用程序(FontForge,Python等)后,我运行一个名为
- 酿造/ Formula-Cookbook.md掌握·自制/酿造
截至2020年7月,Homebrew的
为解决此问题,
1 2 3 4 5 6 7 8 9 10 11 12 | # Set path for fontforge library to use it in Python fontforge_lib = Formulary.factory("fontforge").lib / "python3.8/site-packages" # Supply the full path for Python3.8 executable to use with fontforge python38 = Formulary.factory("[email protected]").bin / "python3" system python38, "-c", <<~PYTHON import sys sys.path.append('#{buildpath / 'src'}') sys.path.append('#{fontforge_lib}') import build sys.exit(build.build('#{version}')) PYTHON |
构建脚本主体– build.py
该脚本为每个阶段调用其他脚本。那时,当播放多个字体文件时,使用
Migu 1M调整-migu1m.py
该脚本对Migu 1M字体进行了各种调整。
1.上升/下降(字体高度)调整
字体的高度由两个属性
1 2 3 4 5 6 7 8 | ASCENT = 1638 DESCENT = 410 OLD_EM = 1000 EM = ASCENT + DESCENT font.ascent = float(ASCENT) / EM * OLD_EM font.descent = float(DESCENT) / EM * OLD_EM font.em = EM |
2.缩小字形
如果您附加纵横比为黄金比例的SF Mono和适合正方形的字形Migu 1M,则Migu 1M的字形会相对较大。需要提前减少,但是这个百分比已经是直觉和经验了。这次我使用的是82%的值,但我别无选择,只能反复尝试查找看起来不错的值。
您可以通过为
字形。手工编写矩阵很困难,因此让我们使用
1 2 3 4 5 6 7 8 9 10 | # 0.82 倍に縮小するための行列 scale = psMat.scale(0.82) # scale() だけだと左に寄りすぎてしまうので、translate() で右にずらす # EM は横幅全体を表す値(今回の場合は 2048) x = EM * (1 - 0.82) / 2 trans = psMat.translate(x, 0) # 2つの行列の積を求める mat = psMat.compose(scale, trans) # 変換実行! glyph.transform(mat) |
这里最棘手的部分是赋予
3.可视化双字节空间
双字节空间的可视化(这是Ricty的主要功能)也在SF Mono Square中实现。这是受Ricty的生成脚本启发的。
1 2 3 4 5 6 7 8 9 10 11 12 13 | font.selection.none() # ? をコピーして 0x3000(全角空白のコードポイント)に貼り付け font.selection.select(0x2610) font.copy() font.selection.select(0x3000) font.paste() # ? をコピーして 0x3000 に貼り付け font.selection.select(0x271a) font.copy() font.selection.select(0x3000) font.pasteInto() # intersect() メソッドで、重なり合った部分のみを残してそれ以外を削除 font.intersect() |
您认为这很好。
4.斜体
进行所有修改后,最后创建斜体字体。 Migu 1M字体仅在常规和粗体中可用。创建倾斜和粗体倾斜以匹配SF Mono。
1 2 3 | mat = psMat.skew(0.2) font.selection.all() font.transform(mat) |
感觉很好。
SF单声道调整-sfmono.py
接下来,我们将修改SF Mono本身。
1.补充斜体字形
SF Mono具有一些字形,例如框形文字和删除了斜体和粗体斜体的箭头。要弥补这一点,分别从常规和粗体复制。
1 2 | font = fontforge.open('SFMono-RegularItalic.otf') font.mergeFonts('SFMono-Regular.otf') |
顺便说一句,当搜索此类信息时,称为pettarin / glyphIgo的工具很有用。将显示包含字体的字形列表。
-
顺便说一句,该工具不适用于Python3,因此我将发布通过分叉修复的工具。
- 三角洲/雕文
1 2 | # フォントファイルの含むグリフ一覧を標準出力に吐き出す glyphIgo.py list -f SFMono-Regular.otf |
2.将长宽比设置为1:2
好吧,这是肝脏。最初,我为此制作了这种字体。
为了将SF Mono与Migu 1M结合使用,必须调整纵横比,使其恰好是半角。
<表格>
tr>
header>
<身体>
tr>
tr>
tr>
tbody>
table>
1 2 3 4 5 6 7 | OLD_WIDTH = 1266 WIDTH = 1024 SCALE_DOWN = float(WIDTH) / OLD_WIDTH mat = psMat.scale(SCALE_DOWN) glyph.transform(mat) glyph.width = WIDTH |
<表格>
tr>
header>
<身体>
![スクリーンショット 2018-12-16 15.57.12.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2Fc0623789-f420-7cb9-6579-fec8ff8b6fa5.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=df0a3d6fb12e8a722ad6b6a4d8793f9c)
![スクリーンショット 2018-12-16 16.38.59.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2Fbf813e00-f1ef-91f1-0c1c-646acca0cdef.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=9119b1384250ef56070f7e53e35320fc)
tr>
tbody>
table>
较小,宽度较窄。而已。
SF Mono和Migu 1M-sfmono_square.py 的合成
最后,附加SF Mono和Migu 1M。在那之后,这是对愤怒的波浪的微调。
1.设置字体信息
在附加字体之前,请准备一个空字体并为其设置字体信息。
"字体信息"不仅是字体名称和许可证。有证据表明,由于历史原因已将信息添加到Ad Hoc中,因此我只是搜索通过反复试验设置的值。
- 无论如何,几乎没有信息...我用我想知道的短语搜索了Microsoft的OpenType规范。
- FontForge的Python API的文档非常糟糕。我依靠davidhalter / jedi-vim代码完成来查找属性。
这里没有显示详细的代码,因为设置它的唯一方法是以简单的方式将值设置为属性。看一下实际的代码。
1 2 3 4 5 6 7 | # 空フォントを作る font = fontforge.font() # ひたすら値を設定しまくる font.ascent = ASCENT font.descent = DESCENT ... |
2.连接SF Mono和Migu 1M
只需将其合并为
1中创建的空字体。这是一个瞬间的杀戮。
1 2 | font.mergeFonts('modified-migu1m-regular.ttf') font.mergeFonts('modified-SFMono-Regular.otf') |
3.将来自Migu 1M的双字节字符替换为SF Mono字形
此处的"双字节字符"是Unicode块中所谓的半角或全角字符。所谓的全角数字或全角字母。从代码点U FF01开始有95个字符。
Migu 1M单独使用时不会感到奇怪,但是与SF Mono结合使用时,它看起来有点轻。这可以通过复制SF Mono的半角字符来解决。
1 2 3 4 5 6 7 8 9 10 11 12 | hankaku_start = 0x21 zenkaku_start = 0xff01 glyphs_num = 95 font.selection.none() for i in range(0, glyphs_num): # 半角文字をコピー font.selection.select(i + hankaku_start) font.copy() # 全角文字に貼り付け font.selection.select(i + zenkaku_start) font.paste() font.selection.none() |
如果仅复制它,则字体将保持在左侧附近。稍微向右移动。
1 2 3 | # 毎度おなじみ translate() trans = translate(WIDTH / 4, 0) glyph.transform(trans) |
这还没有结束。 Half-width?全角形状包含括号,例如
<表格>
tr>
header>
<身体>
![move-to-right.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2F75bb43fd-9315-c3d8-f4c3-57d8687a42f2.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=e33823032adb34e7409bb01daa72f560)
![move-to-left.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2Fdc10281f-8951-09d6-05e1-4ed86c2008a4.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=450df8892bcc618964e56f83b9c30307)
tr>
tbody>
table>
此外,某些异常括号
-
变形前
-
改造后
终于(在这里)完成了。
4.使一些符号变为半角
最近,由于Unicode的普及,许多CLI工具使用了各种符号。例如,jonas / tig使用许多符号来表示漂亮的提交树。
在此类CLI工具中使用的许多符号(例如
1 2 3 4 5 6 7 8 9 10 | # 以下のグリフは半角にする HANKAKU_GLYPHS = [ 0x25a0, # BLACK SQUARE 0x25a1, # □ WHITE SQUARE 0x25cb, # ○ WHITE CIRCLE 0x25cc, # ? DOTTED CIRCLE 0x25ce, # ◎ BULLSEYE 0x25cf, # ● BLACK CIRCLE 0x25ef, # ? LARGE CIRCLE ] |
现在,如何将全角字形转换为半角字形,以免感到奇怪?但是没有简单的方法可以做到这一点。每次只能盯着实际字形来选择最佳的变换矩阵。
在这里,多次出现的
1 2 3 | # (例)グリフを 0.8 倍にする mat = psMat.scale(0.8) glyph.transform(mat) |
即使您说"乘以0.8",也无法指定将中心点缩小的位置,并且文档中也没有关于中心点的描述。实际尝试时,我发现中心点位于(0,DESCENT)。
我们还发现Migu 1M符号与左下角(DESCENT,DESCENT)和右上角(WIDTH --DESCENT,WIDTH --DESCENT)配合成正方形。基于此,您可以通过执行以下操作来生成半角字形。
1 2 3 4 5 6 7 8 9 10 11 12 13 | WIDTH = 2048 DESCENT = 410 SCALE_DOWN = 0.65 # 縮小比率。この比率は何度か試して決めました。 orig_glyph_width = WIDTH - DESCENT * 2 # 元々のグリフの幅、および、高さ glyph_width = float(orig_glyph_width) * SCALE_DOWN # 変換後のグリフの幅、および、高さ trans_x = (WIDTH / 2 - glyph_width) / 2 # 縮小後に右にずらす trans_y = (WIDTH - glyph_width) / 2 - DESCENT # 縮小後に上にずらす trans = psMat.translate(trans_x, trans_y) origin = psMat.translate(-DESCENT, 0) # グリフを中心点に合わせる行列 scl = psMat.scale(SCALE_DOWN) # グリフを縮小する行列 mat = psMat.compose(psMat.compose(origin, scl), trans) glyph.transform(mat) |
<表格>
tr>
header>
<身体>
![スクリーンショット 2018-12-16 17.19.26.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2F45fa942c-2275-874d-2c74-09b1cae80e76.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=e9720ea6c5320a79b83029393537f3d4)
![スクリーンショット 2018-12-16 17.19.29.png](http://i1.wp.com/qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F8880%2F0a671d92-9412-f678-743d-5343289df35b.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=a66cd48d08237ab5e053b29fe924deda)
tr>
tbody>
table>
不,很难。我数学不好,所以很累。
书呆子字体标志符号合成-font_patcher.py
最后,通过Nerd Fonts合成字形。最初,我为此使用了官方脚本字体修补程序,但是我完全重写了它以进行一些修改。具体来说,它在以下几点上不同于原始的书呆子字体。
1.更改了Octicons的代码点,材质图标
<表格>
tr>
header>
<身体>
tr>
tr>
tbody>
table>
进行此更改的原因是,Nerd Fonts使用的区域是可用于此类外部字符的专用区域(U E000 .. U),因为它与F8FF不同。私有使用区域之后立即以U F900开头的CJK兼容汉字包括通常用于专有名词(例如"﨑(U FA11)"和" Fuku(U FA1B)")等专有名词的汉字。这是个问题。
-
我们已与总公司就此事提出了一个问题。预计将在下一个主要版本升级中解决。
- [建议]修复某些字形的无效代码点·问题#365·黑柳病/书呆子字体
2.调整每个字形的大小
书呆子字体包括除Octicon和Material图标之外的各种图标集,但是由于它们是单独开发的,因此字形的大小会有所不同。通过对每一个进行较小的修改,我对其进行了调整,以使它们看起来尽可能相似。
1 2 3 4 5 6 7 8 9 10 11 | if info['name'] == 'Seti-UI + Custom': # この例では縦横それぞれ 1.1 倍に拡大した上、 # 左に 100、下に 450 動かしています。 x_ratio = 1.1 y_ratio = 1.1 x_diff = -100 y_diff = -450 elif info['name'] == 'Devicons': # 以下延々と続く ... |
如上所述,我已进行了一些小的更正。请参阅实际代码以获取完整列表。
这是校正前后的比较...以这种方式进行比较时非常微妙。但是我对此很担心!
最后
我们已经了解了有关创建字体的更多信息。我所做的只是从现有字体进行合成,但这使得调整细节非常困难。那些从头开始创建字体的人真的很沮丧。
网上很少有关于使用FontForge修改字体的信息(尤其是日语)。希望本文能为您带来字体爱好者的舒适生活。