Skip to content
Permalink
Browse files

add two articles & update summary for some old articles

  • Loading branch information...
masakichi committed Jul 20, 2019
1 parent 0978361 commit 9b242647b3c087ce53ff27aac63a80d5a9859c12
@@ -14,9 +14,13 @@ url: "/post/anki-the-best-memory-app-for-learning-japanese"
熟悉日语的朋友可能意识到了,Anki 是「暗記」的读音。其实就是记忆的意思。它的核心理念非常简单,其实就是围绕**卡片**展开的,分为正面和反面。拿背单词来说的话,正面可以是单词本身,反面可以是对应的解释,读音等等,总之是让你回忆起来关于那个单词你需要记忆的要素。然后,对于这个单词,做出你对它熟悉程度的评价值。Anki 通过收集你对这些卡片的熟悉程度,决定在合适的时间再次出示这张卡片询问你对卡片的熟悉程度,以此来强化记忆,久而久之就会对需要记忆的单词越来越熟悉,因此再次出现的间隔也会越来越长,据说甚至最长会到数年。(我目前最长间隔的卡片大概是几个月之后会再次出现提醒下我。)总而言之 Anki 会为我们做的有:

- 生成用于记忆的卡片

- 收集我们对于每张卡片的记忆评价值

- 基于我们对卡片的熟悉程度安排每天的记忆任务

<!--more-->

![AnkiDroid](anki-android.png)

相对 Anki 为我们完成的事情,我们也有义务做一些事情。很显然,卡片不会凭空生成,需要我们提供。不过严格来说,我们提供的并不是卡片,而是类似**笔记**一样的东西。笔记是用来生成卡片的材料,这是一个非常优秀的理念,这比我们用纸和笔亲自做记忆卡片要高效和易于管理很多。拿我自己背日语单词来说的话,对于一个单词,我首先需要这个单词本身的数据(废话),其次是它的读音,释义,例句等。另外作为备注我们甚至希望记录它是在哪里被我们发现的。(如果是网页里看到的话,我们也许可以记录下出现这个单词的 URL,对于电子书的话,我们可以记录下出处的上下文)而这些一项一项数据,分别是一个个字段,他们一起组成了关于那个单词的笔记。我们需要定义一下这些字段的名字都叫啥,然后就可以愉快得做笔记了。(这是我们使用 Anki 最需要我们操心的部分)有了笔记,接下来我们定义一套规则,用来生成卡片。听起来好像很复杂,其实很简单,说白了就是,你需要在卡片的正面显示什么,背面显示什么,因为我们收集的笔记字段很多,但其实并不都需要放在卡片里,比如你收集了单词出处的链接,(一般来说)这个链接你当然不需要记住它。你把这个正反面的对应关系告诉 Anki,接下来就放心交给它,让它给我们生成我们用来记忆的卡片就行了。总的来说,我们需要插手做的就是:
@@ -30,6 +30,8 @@ url: "/post/unicode-rei"

这些话题展开了调查,在此总结一下。

<!--more-->

## 关于 Unicode

为了理解「中日韩兼容表意文字」,首先需要理解 **Unicode 的理念****字源分离原则**[^字源分离原则]。
@@ -0,0 +1,35 @@
---
title: "自由研究 0: 字体(fontconfig 編)"
date: 2019-07-17
tags: ["字体", "自由研究"]
isCJKLanguage: true
draft: false
url: "/post/fontconfig-introduction"
---

我尝试着去了解字体方面的知识,印象中一共有两次。一次是去年从 [macOS 转到 Arch Linux](https://gimo.me/post/from-macos-to-archlinux/) 上的时候,一次是昨天尝试着把一个字体旋转 270 度的时候。

我首先声明我并没有任何制作字体或者是搭配展示字体给其他人看的经历,我所描写的事情说到底不过是我通过自己收集情报、自己尝试得出的一些结论,至于这个结论是否正确,还请读者自己判读。

<!--more-->

这篇文章主要说的是第一次尝试了解字体知识时候的经历,彼时正好换电脑系统,在那之前一直使用 mac 系统,可能这个系统默认的字体搭配地比较好,或者我这个人比较愚钝一直没关注电脑上显示的各种字体,最多也就是更换一下写代码时候编辑器的字体,仅此而已。直到我安装上 Arch Linux 之后,发现中文是显示不出来的,也就是出现了所谓的「豆腐块」,为了解决这个问题显然我们需要安装字体,目前 Linux 上应对 CJK 文字的显示主流就是 Adobe 提供的思源宋体、黑体这一套(因为是 Adobe 和 Google 一起开发的,Google 这边叫 Noto Serif/Sans CJK)安装好之后,基本上中日韩的文字就能正确显示了,当然显示地好不好看另说,至少没有豆腐块了。然后我就产生了一个朴素的疑问,我的系统怎么知道我安装了这些字体呢?我的系统又怎么知道用哪一款字体呢?比如我完全可以安装几款不同的西文、中文、日文字体,我上豆瓣网的时候,豆瓣日记里显示字体的时候,它是怎么决定用那一款字体或者哪几款字体的呢?有过编写 CSS 的朋友可能就要说了,因为样式里写了 font-family 的值呀,确实是这样没有错,可是这个值里写的字体名称我都没有安装诶,我的系统是怎么挑出来的呢?于是我就想我的电脑里肯定有一款软件是专门来管这档子事情的,就是你告诉我一个或者一串想要使用的字体,我按照我计算的结果给你一个回应,这样我的浏览器也好、其他软件也好才能正确显示出字体来。经过一番资料查找,这个软件在 Linux 上叫 fontconfig。(Windows 和 macOS 上肯定也有类似的软件)它就像一个中介,在其他软件需要使用字体的时候先来问他一声。再回到上面的问题

1. 我们安装好了思源黑体之后,为什么系统就能正确显示中文了呢?
因为我安装字体的路径正好是 fontconfig 去寻找字体的地方,想象一下电脑里有个叫作字体仓库的地方,字体默认安装的地点就是那个仓库。这样就解释了为什么安装完字体系统就能识别出这款字体了。(事实上,系统可能不只一个这样的字体仓库,以 fontconfig 为例,系统级别的仓库在 /usr/share/fonts 里,用户级别的在 ~/.fonts 里,而这些地址应该可以通过修改 fontconfig 的配置文件任意定制)
2. 系统怎么知道用这款字体而不是那一款呢?
肯定有一个优先级的关系,这个就是 fontconfig 的主要功能了,根据用户或者某个程序的查询返回一个带有优先级的字体列表供查询方使用。这个定义具体优先级的规则就有用户来定义了,而为什么用户没有定义也能显示一些默认的字体,那是因为 fontconfig 在安装的时候内置了一些基本的配置(相当于替用户做了一部分决策),保证你安装之后不至于什么字体都展示不了,同样地在安装某些字体安装包的时候甚至也会预制一些这个字体相关的 fontconfig 配置文件。而想要让自己的系统里的各种字体显示得一致又大体符合自己的期望,就需要自己动手写一个属于自己的配置文件,而基本语法在系统搭载的默认配置里都有,那里的配置方法无疑是教科书一样的存在,有很高的学习价值。通过阅读那里的配置(或者其他发行版的配置文件),你大概就可以尝试着定制自己的字体优先级了。

有了以上知识之后,我们可以做些什么呢?显然我们可以按照我们的意志来自定义 fontconfig 返回字体的优先级。在这之前,我们还需要有一点儿基本的字体知识。一般来说我们通常遇到的软件会和三种字体打交道分别是 serif,sans-serif,monospace,分别代表衬线字体,非衬线字体和等宽字体,衬线、非衬线这是西文里的叫法,对应到我们中文或者日文相当于宋体(明朝体),黑体(ゴシック体)。而等宽字体这个概念对于西方字母来说比较明显,而对于汉字来说似乎意义不大,好像都是等宽的。有了这些知识之后,我们明白了一个道理,要想定制自己电脑上字体显示的方式,就是定义字体名字是 serif,sans-serif,monospace 的时候,fontconfig 应该给出怎样的字体匹配列表。然后就会涉及到字体的 fallback 问题,这是什么问题呢?因为一款字体中实现的 glyph(字形,就是某个字到底长什么样子)是有限的(比方说一款英文字体里就没有实现中文字形),我们打了一段话里面可能有英文、中文、还有👌这样的绘文字,就需要多个字体来渲染这段话。如何定义多个字体的渲染优先级就是我们能用 fontconfig 完成的任务了。比如在我这里,拿豆瓣日记来说吧,正文部分它指定了用 sans-serif 字体去渲染,在我的定义里就变成了:Source Sans Pro 你先去试试水,如果你渲染不了了就让 Noto Color Emoji(一款 Google 出的绘文字字体) 去接手,如果你也渲染不了就交给 Sony Mobile UD Gothic (我的索尼手机搭载的默认字体)去渲染,如果它再渲染不了就交给 Noto Sans CJK JP 去渲染,依次往后推,这个过程就叫 fallback。这个长长的备用链,在外部使用者而言,其实非常简单只需要指定个字体名称比如说叫 sans-serif。

但是我们仔细想想,serif 也好,sans-serif 也好还是 monospace,我们电脑上其实都没有这些字体,而我们的系统却能显示出来其实是因为默认的 fontconfig 配置文件里定义了很多这样抽象的字体阵营。也就是说我们通过配置文件来决定了一款字体是属于哪个阵营的。而说到底,这个阵营无非就是个代号,所以你要是愿意完全可以把一款衬线字体(serif)划分到非衬线字体的阵营(sans-serif),这没有任何问题,甚至可以自己命名一个叫 douban 的字体阵营,然后只要定义好字体名是 douban 的时候,真正用于展示的字体优先级是怎样的就行了,这种无中生有的方式是一种灵活的方式。fontconfig 不仅可以无中生有,还能偷梁换柱。什么意思呢,比如某个软件或者某个网站指定了一款字体,但是这款字体我不喜欢,但是我又不想把它从我的电脑上删除,怎么办呢?你可以告诉 fontconfig 让它把那款字体变成任何一款你想要的字体,或者某个字体阵营。比如你可以把 Helvetica、Arial 统统换成 Source Sans Pro(简单一点儿直接换成 sans-serif,如果 sans-serif 你已经精心设置过优先级了的话)。说着似乎有点儿绕(不过这么长的文章看到这里也辛苦了),简单地说明 fontconfig 的灵活性的话,相当于你问主持人要个村上春树,主持人给你扔出个村上信五。(这个例子反而更迷惑了可能)

除此之外,fontconfig 还能对字体进行一些微调,比如西文字体和 CJK 字体都在一段话里的时候,可以适当调整西文字体的大小让整体显得更协调。其他诸多功能还是阅读它的文档比较好。

以上就是第一回字体研究得出的结论了。

(下面附上一些截图)

{{< figure src="ja_wikipedia.jpg" class="center" title="日文维基百科页面" >}}

{{< figure src="termite_monospace.jpg" class="center" title="终端软件只需要指定 Monospace 就能正确显示各种符号" >}}
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,44 @@
---
title: "自由研究 1: 字体料理"
date: 2019-07-19
tags: ["字体", "自由研究"]
isCJKLanguage: true
draft: false
url: "/post/font-creation-introduction"
---

上回说了[如何使用 fontconfig 搭配字体]({{< relref "/自由研究 0: 字体(fontconfig 編)" >}}),咋看之下似乎很科学。但有一个明显的问题,就是如果某个软件、或者某个系统压根不支持 fontconfig 呢?没有错,所有在 fontconfig 里做的努力都打了水漂。为了解决这个问题,或者兼顾不同的平台,很多字体爱好者想到了一个办法,那就是把自己喜欢的或者想要的几个字体合到一块不就可以了?确实是这样,今天就简单地说一下怎么修改字体,因为修改的过程很像做菜,标题就取作「字体料理」了。

<!--more-->

首先说一下为什么会需要修改字体,大体上我觉得有两类:

1. 可能完全是个人喜好问题,比如你喜欢一款字体里的阿拉伯数字,但是不喜欢这款字体里的西文字母,或者非常中意一款中文字体,但是嫌弃和它搭配的其他西文字母。这个时候一些人就想到了取长补短的方法,把一款字体作为基础字体,剔除里面自己不喜欢的字形,再从别的字体里借一些自己中意的字形过来。
2. 处于可读性的考虑,中文可能这个情况不明显。但是西文字母和一些日文字符就会有这个问题了。比如说数字「1」和字母「l」以及大写字母「I」,还有数字「0」和字母「O」的区别,比如说日文里的片假名「カ」和汉字的「力」,比如字号小的时候不太分得清「つ」和「っ」,甚至有的时候分不清浊点半浊点。到底哪个是哪个?有人就通过一些小修改让这些暧昧不清的字形有自己更明显的特征。

比如说像下面两张图片里这款叫作 [Migu](https://mix-mplus-ipa.osdn.jp/migu/) 的字体就是爱好者合成的,主要特点是在一款叫 M Plus 的基础让文字更可读,比如把半浊点(就是假名右上角的圈圈)放大,片假名的长音符号「ー」前面稍微翘点头,数字的「一」后面翘点儿尾巴等等,另外 M Plus 里没有的字形就从 IPA 字体里引进。

{{< figure src="migu_1c.png" class="center" title="Migu 1C 的可读性" >}}

{{< figure src="migu_1p.png" class="center" title="Migu 1P 对暧昧字形的处理" >}}

有了这款字体之后,又有其他爱好者做出了一款叫作 [Ricty](https://www.rs.tus.ac.jp/yyusa/ricty.html) 的字体,这个字体就更复杂了,Ricty 这五个字母前四个分别是 [Inconsolata](https://fonts.google.com/specimen/Inconsolata) 作者的首字母 R,上面那款 Migu 字体的作者首字母 i,M+ M Type-1 作者的首字母 c,加上 IPA Gothic 字体基于的 TB Gothic 的作者首字母 t。最后加上 Ricty 的作者自己的首字母 y 就得到了这款字体的名字。与上面那款字体不一样的是,这款字体有个明显的特征,就是把西文字形交给一款专门的西文字体,余下的字体交给和文字体,然后再做其他的微调。这个做法其实在合成字体(尤其是程序员编程使用的等宽字体)上非常常见。比如受 Ricty 启发而派生的 [Cica](https://github.com/miiton/Cica) 字体,还有国内爱好者制作的 [Sarasa-Gothic](https://github.com/be5invis/Sarasa-Gothic) 基本都属于这个类型。无非是选用的西文,CJK 字体不一样(有的还会友好地加入各种符号 logo 等,像 Cica 还有自带 emoji 的版本)以及生成字体选用的手段不同而已。据我观察看到大体有两种方案,像 Cica/Ricty 使用的是 fontforge 脚本,像 Sarasa-Gothic 使用的是 otfcc。后面那种我没有仔细研究过,fontforge 我使用了下比较直观,文章最后可以简单说一下。

接下来讨论的一个问题就是合成字体的分发(distribution)问题。为什么有了 Ricty 字体之后,爱好者还要做出 Cica 字体,虽然有一部分原因是 Ricty 的西文字体 Inconsolata 字体可能有爱好者不满意(我是挺喜欢这个字体的),但有一个重要的原因就是许可证(License)的问题。一般来讲,你的字体由多款字体合成,这款新字体需要符合所有这些字体的许可证。基本上,我粗略地理解,在许可证不互相矛盾的情况下,需要遵守最严格的那个许可证。这也就是为什么 Ricty 的作者其实从来没有发布过 Ricty 这款字体(因为 Inconsolata 这款字体要求派生的字体不得再分发),他发布的只有制作这款叫作 Ricty 字体的配方,就是一组指令,你照着执行就能合成出 Ricty 的字体,但是你做了这款字体,你也和 Ricty 的作者一样,不得再次分发这款字体,也就是说你只能教别人怎么合成字体,你不能把字体放在公开的地方供人下载。这显然不太利于这款字体传播,毕竟不是所有人都有兴趣去合成字体的(和料理食物是一个道理吧:D)所以,Cica 也好 Sarasa 也好在选择字体方面可能有这样的考虑,这两款合成字体是可以再分发的,普通用户可以直接下载由作者提供的字体文件而没有法律风险。

如果看到这里的读者,甚至萌生了自己合成字体的想法,我想上面提到的一些关键字也够你展开调查了,比如说安装一下 fontforge 或者其他字体制作、修改软件感受一下。fontforge 自带有一个 Python 的绑定,你可以使用 Python 脚本来批量操作你需要的动作,比如说选择所有的西文字母,把他们换成其他字体的字形,比如说选择所有的假名对它们进行你想要的操作,这些选择,在脚本里可以通过 Unicode 的范围决定,fontforge 的软件里内置了很多常用字符的 Unicode 范围。然后对于字形的变化,fontforge 里是通过一个矩阵函数实现,这个 CSS 里有几乎相同的概念,感兴趣的朋友可以读一读这篇文章 [理解CSS3 transform中的Matrix(矩阵)](https://www.zhangxinxu.com/wordpress/2012/06/css3-transform-matrix-%e7%9f%a9%e9%98%b5/) 就知道我说的 fontforge 里的矩阵变换是什么意思了。想用 Python 合成修改字体的朋友可以看 http://dmtr.org/ff.php 这里的文档,里面主要有两部分组成 psMat 和 fontforge,前者是用来方便生成变换矩阵存在的快捷功能,后者是具体操作字体的部分,一般的手段是先打开字体,然后操作选中的 glyph,如果要更细腻的操控可以操作 glyph 对应的 layer,最后完成所有操作之后 generate 字体就行了。Cica 的脚本提供了一个比较直观的例子可以作为参考。

以下是打开 Cica 字体的时候 fontforge 的样子。

{{< figure src="fontforge_overview.png" class="center" title="Cica 用 fontforge 打开后的一部分字形" >}}

{{< figure src="unicode_reiwa.png" class="center" title="最新加入 Unicode 的日本新年号的合体字形" >}}

最后,我得说字体的知识真的非常复杂,我提两个问题抛砖引玉下:

1. 为什么字体可以跨平台、跨机种使用?在没有 Unicode 之前,或者说不使用 Unicode 字符集的平台,字体是如何找到正确的字形的?
2. 合字效果(Ligature)怎么做到的,比如说有的字体打出 f 和 i 两个字母,会自动合并到一块,甚至有些字体打出 ! 和 = 会自动生成一个不等于号 ≠

因为篇幅的问题我就不展开说明了,一方面我也没有深入研究,万一说错误导了读者就不好了。等我有时间了更有自信的时候再写字体的文章吧。接下来我应该会去读 CJKV Information Processing 这本书更好地了解字符集、字体相关的知识。

以上。
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -18,6 +18,8 @@ url: "/post/learning-japanese-cross-platform"
- 生词本
- 电子阅读

<!--more-->

## 系统语言

这个 Windows 也好 macOS 基本上都可以自己方便的选择,Linux 的情况一般把 `/etc/locale.gen``ja_JP.UTF-8 UTF-8` 前面的注释去掉,再次运行 `locale-gen` 重新生成再重启一下就行了。如果要把日语设成默认语言就把 `/etc/locale.gen` 里日语的优先顺位设成第一个就行了。

0 comments on commit 9b24264

Please sign in to comment.
You can’t perform that action at this time.