编码与字体

date
Oct 14, 2021
slug
encoding-and-font
status
Published
tags
Font
summary
阅读 《Font and Encoding》的一些笔记
type
Post

什么是字符集

中文,英文,韩语,日语,阿拉伯语,Unicode等等。

什么是字符集编码

字符集到字节数组的映射关系
GB2312、GB18030、ASCII,Shift JIS,UTF-8,UTF-16等等。

常用字符集和字符编码

常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。

1. ASCII字符集&编码

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以勉强显示其他西欧语言。它是现今最通用的单字节编码系统(但是有被Unicode追上的迹象),并等同于国际标准ISO/IEC 646。
ASCII字符集 :主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
ASCII编码 :将ASCII字符集转换为计算机可以接受的数字系统的数的规则。使用7位(bits)表示一个字符,共128字符;但是7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。ASCII字符集映射到数字编码规则如下图所示:
notion image
notion image
图2 扩展ASCII编码表
ASCII的最大缺点是只能显示26个基本拉丁字母、阿拉伯数目字和英式标点符号,因此只能用于显示现代美国英语(而且在处理英语当中的外来词如naïve、café、élite等等时,所有重音符号都不得不去掉,即使这样做会违反拼写规则)。而EASCII虽然解决了部份西欧语言的显示问题,但对更多其他语言依然无能为力。因此现在的苹果电脑已经抛弃ASCII而转用Unicode。
它提供了一种相当天真和无法接受的方法来在字母上加重音: 为了得到一个“ é”,要求输入序列“ e b”,即: “ e”、“ backspace”、“撇号”。这就是为什么在编码中可以找到重音和回旋音以及波浪音。

2. GBXXXX字符集&编码

计算机发明之处及后面很长一段时间,只用应用于美国及西方一些发达国家,ASCII能够很好满足用户的需求。但是当天朝也有了计算机之后,为了显示中文,必须设计一套编码规则用于将汉字转换为计算机可以接受的数字系统的数。
天朝专家把那些127号之后的奇异符号们(即EASCII)取消掉,规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,还把数学符号、罗马希腊的 字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。
上述编码规则就是GB2312。GB2312或GB2312-80是中国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,又称GB0,由中国国家标准总局发布,1981年5月1日实施。GB2312编码通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB2312。GB2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。对于人名、古汉语等方面出现的罕用字,GB2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现。下图是GB2312编码的开始部分(由于其非常庞大,只列举开始部分,具体可查看GB2312简体中文编码表):
notion image
图3 GB2312编码表的开始部分
由于GB 2312-80只收录6763个汉字,有不少汉字,如部分在GB 2312-80推出以后才简化的汉字(如"啰"),部分人名用字(如中国前总理朱镕基的"镕"字),台湾及香港使用的繁体字,日语及朝鲜语汉字等,并未有收录在内。于是厂商微软利用GB 2312-80未使用的编码空间,收录GB 13000.1-93全部字符制定了GBK编码。根据微软资料,GBK是对GB2312-80的扩展,也就是CP936字码表 (Code Page 936)的扩展(之前CP936和GB 2312-80一模一样),最早实现于Windows 95简体中文版。虽然GBK收录GB 13000.1-93的全部字符,但编码方式并不相同。GBK自身并非国家标准,只是曾由国家技术监督局标准化司、电子工业部科技与质量监督司公布为"技术规范指导性文件"。原始GB13000一直未被业界采用,后续国家标准GB18030技术上兼容GBK而非GB13000。
GB 18030,全称:国家标准GB 18030-2005《信息技术 中文编码字符集》,是中华人民共和国现时最新的内码字集,是GB 18030-2000《信息技术 信息交换用汉字编码字符集 基本集的扩充》的修订版。与GB 2312-1980完全兼容,与GBK基本兼容,支持GB 13000及Unicode的全部统一汉字,共收录汉字70244个。GB 18030主要有以下特点:
  • 与UTF-8相同,采用多字节编码,每个字可以由1个、2个或4个字节组成。
  • 编码空间庞大,最多可定义161万个字符。
  • 支持中国国内少数民族的文字,不需要动用造字区。
  • 汉字收录范围包含繁体汉字以及日韩汉字。
notion image
图4 GB18030编码总体结构
本规格的初版使中华人民共和国信息产业部电子工业标准化研究所起草,由国家质量技术监督局于2000年3月17日发布。现行版本为国家质量监督检验总局和中国国家标准化管理委员会于2005年11月8日发布,2006年5月1日实施。此规格为在中国境内所有软件产品支持的强制规格。

3. BIG5字符集&编码

Big5,又称为大五码或五大码,是使用繁体中文(正体中文)社区中最常用的电脑汉字字符集标准,共收录13,060个汉字。中文码分为内码及交换码两类,Big5属中文内码,知名的中文交换码有CCCII、CNS11643。Big5虽普及于台湾、香港与澳门等繁体中文通行区,但长期以来并非当地的国家标准,而只是业界标准。倚天中文系统、Windows等主要系统的字符集都是以Big5为基准,但厂商又各自增加不同的造字与造字区,派生成多种不同版本。2003年,Big5被收录到CNS11643中文标准交换码的附录当中,取得了较正式的地位。这个最新版本被称为Big5-2003。
Big5码是一套双字节字符集,使用了双八码存储方法,以两个字节来安放一个字。第一个字节称为"高位字节",第二个字节称为"低位字节"。"高位字节"使用了0x81-0xFE,"低位字节"使用了0x40-0x7E,及0xA1-0xFE。在Big5的分区中:
0x8140-0xA0FE
保留给用户自定义字符(造字区)。
标点符号、希腊字母及特殊符号,包括在0xA259-0xA261,安放了九个计量用汉字:兙兛兞兝兡兣嗧瓩糎。
保留。此区没有开放作造字区用。
常用汉字,先按笔划再按部首排序。
保留给用户自定义字符(造字区)。
次常用汉字,亦是先按笔划再按部首排序。
保留给用户自定义字符(造字区)。

3.Unicode字符集&UTF编码

伟大的创想Unicode——不得不单独说Unicode
像天朝一样,当计算机传到世界各个国家时,为了适合当地语言和字符,设计和实现类似GB232/GBK/GB18030/BIG5的编码方案。这样各搞一套,在本地使用没有问题,一旦出现在网络中,由于不兼容,互相访问就出现了乱码现象。
为了解决这个问题,一个伟大的创想产生了——Unicode。Unicode编码系统为表达任意语言的任意字符而设计。它使用4字节的数字来表达每个字母、符号,或者表意文字(ideograph)。每个数字代表唯一的至少在某种语言中使用的符号。(并不是所有的数字都用上了,但是总数已经超过了65535,所以2个字节的数字是不够用的。)被几种语言共用的字符通常使用相同的数字来编码,除非存在一个在理的语源学(etymological)理由使不这样做。不考虑这种情况的话,每个字符对应一个数字,每个数字对应一个字符。即不存在二义性。不再需要记录"模式"了。U+0041总是代表'A',即使这种语言没有'A'这个字符。
在计算机科学领域中,Unicode(统一码、万国码、单一码、标准万国码)是业界的一种标准,它可以使电脑得以体现世界上数十种文字的系统。Unicode 是基于通用字符集(Universal Character Set)的标准来发展,并且同时也以书本的形式[1]对外发表。Unicode 还不断在扩增, 每个新版本插入更多新的字符。直至目前为止的第六版,Unicode 就已经包含了超过十万个字符(在2005年,Unicode 的第十万个字符被采纳且认可成为标准之一)、一组可用以作为视觉参考的代码图表、一套编码方法与一组标准字符编码、一套包含了上标字、下标字等字符特性的枚举等。Unicode 组织(The Unicode Consortium)是由一个非营利性的机构所运作,并主导 Unicode 的后续发展,其目标在于:将既有的字符编码方案以Unicode 编码方案来加以取代,特别是既有的方案在多语环境下,皆仅有有限的空间以及不兼容的问题。
可以这样理解:Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三种字符编码方案。

1.UCS & UNICODE

通用字符集 (Universal Character Set, UCS )是由ISO制定的 ISO 10646 (或称 ISO/IEC 10646 )标准所定义的标准字符集。历史上存在两个独立的尝试创立单一字符集的组织,即国际标准化组织(ISO)和多语言软件制造商组成的统一码联盟。前者开发的 ISO/IEC 10646 项目,后者开发的统一码项目。因此最初制定了不同的标准。
1991年前后,两个项目的参与者都认识到,世界不需要两个不兼容的字符集。于是,它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出U+10FFFF的UCS-4编码赋值,以使得两者保持一致。两个项目仍都存在,并独立地公布各自的标准。但统一码联盟和ISO/IEC JTC1/SC2都同意保持两者标准的码表兼容,并紧密地共同调整任何未来的扩展。在发布的时候,Unicode一般都会采用有关字码最常见的字型,但ISO 10646一般都尽可能采用Century字型。

2.UTF-32

上述使用4字节的数字来表达每个字母、符号,或者表意文字(ideograph),每个数字代表唯一的至少在某种语言中使用的符号的编码方案,称为UTF-32。UTF-32又称UCS-4是一种将Unicode字符编码的协定,对每个字符都使用4字节。就空间而言,是非常没有效率的。
这种方法有其优点,最重要的一点就是可以在常数时间内定位字符串里的第N个字符,因为第N个字符从第4×Nth个字节开始。虽然每一个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得广泛。

3.UTF-16

尽管有Unicode字符非常多,但是实际上大多数人不会用到超过前65535个以外的字符。因此,就有了另外一种Unicode编码方式,叫做UTF-16(因为16位 = 2字节)。UTF-16将0–65535范围内的字符编码成2个字节,如果真的需要表达那些很少使用的"星芒层(astral plane)"内超过这65535范围的Unicode字符,则需要使用一些诡异的技巧来实现。UTF-16编码最明显的优点是它在空间效率上比UTF-32高两倍,因为每个字符只需要2个字节来存储(除去65535范围以外的),而不是UTF-32中的4个字节。并且,如果我们假设某个字符串不包含任何星芒层中的字符,那么我们依然可以在常数时间内找到其中的第N个字符,直到它不成立为止这总是一个不错的推断。其编码方法是:
  • 如果字符编码U小于0x10000,也就是十进制的0到65535之内,则直接使用两字节表示;
  • 如果字符编码U大于0x10000,由于UNICODE编码范围最大为0x10FFFF,从0x10000到0x10FFFF之间 共有0xFFFFF个编码,也就是需要20个bit就可以标示这些编码。用U'表示从0-0xFFFFF之间的值,将其前 10 bit作为高位和16 bit的数值0xD800进行 逻辑or 操作,将后10 bit作为低位和0xDC00做 逻辑or 操作,这样组成的 4个byte就构成了U的编码。
对于UTF-32和UTF-16编码方式还有一些其他不明显的缺点。不同的计算机系统会以不同的顺序保存字节。这意味着字符U+4E2D在UTF-16编码方式下可能被保存为4E 2D或者2D 4E,这取决于该系统使用的是大尾端(big-endian)还是小尾端(little-endian)。(对于UTF-32编码方式,则有更多种可能的字节排列。)只要文档没有离开你的计算机,它还是安全的——同一台电脑上的不同程序使用相同的字节顺序(byte order)。但是当我们需要在系统之间传输这个文档的时候,也许在万维网中,我们就需要一种方法来指示当前我们的字节是怎样存储的。不然的话,接收文档的计算机就无法知道这两个字节4E 2D表达的到底是U+4E2D还是U+2D4E。
为了解决这个问题,多字节的Unicode编码方式定义了一个"字节顺序标记(Byte Order Mark)",它是一个特殊的非打印字符,你可以把它包含在文档的开头来指示你所使用的字节顺序。对于UTF-16,字节顺序标记是U+FEFF。如果收到一个以字节FF FE开头的UTF-16编码的文档,你就能确定它的字节顺序是单向的(one way)的了;如果它以FE FF开头,则可以确定字节顺序反向了。

4.UTF-8

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码(定长码),也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。
UTF-8使用一至四个字节为每个字符编码:
  1. 128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
  1. 2.带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要二个字节编码(Unicode范围由U+0080至U+07FF)。
  1. 其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码。
  1. 其他极少使用的Unicode辅助平面的字符使用四字节编码。
在处理经常会用到的ASCII字符方面非常有效。在处理扩展的拉丁字符集方面也不比UTF-16差。对于中文字符来说,比UTF-32要好。同时,(在这一条上你得相信我,因为我不打算给你展示它的数学原理。)由位操作的天性使然,使用UTF-8不再存在字节顺序的问题了。一份以utf-8编码的文档在不同的计算机之间是一样的比特流。
总体来说,在Unicode字符串中不可能由码点数量决定显示它所需要的长度,或者显示字符串之后在文本缓冲区中光标应该放置的位置;组合字符、变宽字体、不可打印字符和从右至左的文字都是其归因。所以尽管在UTF-8字符串中字符数量与码点数量的关系比UTF-32更为复杂,在实际中很少会遇到有不同的情形。
优点
  • UTF-8是ASCII的一个超集。因为一个纯ASCII字符串也是一个合法的UTF-8字符串,所以现存的ASCII文本不需要转换。为传统的扩展ASCII字符集设计的软件通常可以不经修改或很少修改就能与UTF-8一起使用。
  • 使用标准的面向字节的排序例程对UTF-8排序将产生与基于Unicode代码点排序相同的结果。(尽管这只有有限的有用性,因为在任何特定语言或文化下都不太可能有仍可接受的文字排列顺序。)
  • UTF-8和UTF-16都是可扩展标记语言文档的标准编码。所有其它编码都必须通过显式或文本声明来指定。
  • 任何面向字节的字符串搜索算法都可以用于UTF-8的数据(只要输入仅由完整的UTF-8字符组成)。但是,对于包含字符记数的正则表达式或其它结构必须小心。
  • UTF-8字符串可以由一个简单的算法可靠地识别出来。就是,一个字符串在任何其它编码中表现为合法的UTF-8的可能性很低,并随字符串长度增长而减小。举例说,字符值C0,C1,F5至FF从来没有出现。为了更好的可靠性,可以使用正则表达式来统计非法过长和替代值(可以查看W3 FAQ: Multilingual Forms上的验证UTF-8字符串的正则表达式)。
缺点
因为每个字符使用不同数量的字节编码,所以寻找串中第N个字符是一个O(N)复杂度的操作 — 即,串越长,则需要更多的时间来定位特定的字符。同时,还需要位变换来把字符编码成字节,把字节解码成字符。

字体

活字印刷术

毕昇发明泥活字,是活字的开端。以后又发展了锡活字、木活字、铜活字、铅活字等。其中木活字对后世影响较大,仅次于雕版。朝鲜古代曾有过铁活字。现代铅合金活字是德国人J.谷登堡于15世纪50年代所创制。
汉字活字字体主要有宋体正楷仿宋、黑体4种。并有长扁变形体,另有隶书魏碑、美术体等不同风格的字体多种。宋体又称老宋体,横细直粗,整齐清晰,容易辨认,阅读效果好,为中国书刊报纸正文的基本用字,字面有粗体、细体等三四种,日本人称为“明朝体”。正楷字体端庄方正,笔法和手写相仿,有几种不同风格的活字,适用面广,小学课本和儿童读物更多使用。仿宋体是仿照宋刻本的正楷字设计的活字,横直笔画粗细相近,横画略向右上倾斜,秀丽清健悦目,书刊的正文、标题、图版说明文,商品包装广告等均适用。字体有方形、长形2种。黑体,视觉上横直笔画粗细相同,方正粗黑,又名方体字、等线体字,字体也有粗体细体的不同,一般作标题和重点文句用。
外文活字,有拉丁文希腊文俄文日文阿拉伯文、印地文、缅文、泰文等多种,都设计有多种字体。拉丁文活字字体种类最多,按不同风格,可分为哥特体罗马体、无装饰线黑体 (又称等线体)、方装饰线黑体(又称埃及体)、斜体(又称意大利体)、手写体美术体7大类,每一类中都有不同风格的字体,少则十多种,多则几十种,各国有自己的使用习惯。

字体种类

notion image
  1. Serif(衬线体)
  1. Sans Serif(五衬线体)
  1. Monospace(等宽字体)

字体类型

点阵字体(Bitmap Font)

点阵字体通过点阵表现字形,其本质上只是一组图片。每一种字体变体都包括一组完整的字符,一个字符占一张图片。假设总字符数量为3,即包括三个字符,提供粗体和斜体的组合(即无、粗体、斜体、粗斜体四种变体),该字体总共有12张图片。
由于受到容量和绘图速度的限制,早期电脑多采用点阵字体,而现在已不再被广泛使用,原因是其他字体编码方法在视觉效果和功能都超过了它。但它在某些场合(特别是在显示小字号的汉字字符的时候)还是很有用的,因为可缩放字体缩小过多笔画的字时,容易挤成一片导致无法辨认,因此小号字体仍使用点阵格式。
点阵字体被用于Linux终端,Windows修复控制台和嵌入式系统。

轮廓字体

轮廓字体又称描边字体。这类字体使用贝兹曲线描述轮廓,可以通过简单的数学变形放大或缩小。但是很小的字体经常需要额外的信息(hints)指导笔画取舍进行润算,不然容易漆黑一团。

PostScript字体

PostScript字体由Adobe公司为专业数字排版开发。它使用PostScript,字形以3次贝兹曲线描述。其下又分为Type1, Type3,OCF, CID等类型。
Type 1字体只有1字节,因此只能容纳256个字符。它使用Adobe私有的hinting系统,价格昂贵。需要注意的是,很多被称为Type1的字体实际上是Type3或Type5。 Type 3字体完全支持PostScript描述性语言,可以勾画出较复杂的字体,如:渐变。 OCF字体:中文日文等双字节语言可以使用的字体。按照PostScript类型,它属于Type0 (也就是Type1或3的组合形式) CID字体:OCF字体的改良。具有异体字切换功能。按照PostScript类型,多数字体属于Type9(基于TrueType的CID字体等除外)

TrueType字体

TrueType是一种最初由苹果电脑公司开发的字体技术。考虑到Type 1字体太昂贵,有意用TrueType字体取代Type 1字体。像Type1字体一样,贝兹曲线用于描述字体,并可以内置点阵字体。现在它十分普及,在所有主要的操作系统上都有使用。能用PostScript打印机处理的TrueType字体称为Type42。
TrueType使用2次贝塞尔曲线,其hint方式也与PostScript不同,使用的是小进程字节码的形式。TrueType可以包含点阵字体。

OpenType字体

OpenType字体是为了实现Windows和Macintosh系统兼容,而产生的一种新字体格式。OpenType文档格式由TrueType发展而成,因此具有TrueType的全部功能。
和TrueType相比,OpenType可以使用PostScript的3次曲线描述字形。OpenType支持CID,具有高度的异体字切换功能。OpenType可以动态下载到打印机中,无需打印机内置字体。若按照PostScript的类型分类,它属于Type2型,可以控制字体文档数据大小。

OpenType Variable Fonts

OpenType可变字体是字体格式 OpenType 在1.8版规范中引入的扩展规范,由苹果、微软、谷歌和Adobe联合开发,于2016年9月14日正式发布。支持这一规范的计算机字体可以储存轮廓变化数据,在初始字形轮廓的基础上自动生成丰富的变化造型,使用户可以自由调整文本的外观。
一个可变字体文档可以储存一个设计的多个变体,相当于是包含了一个含有无数个字体的字体。| DEMO1| DEMO2

笔画字体

笔画字体(Stroke-based font)字形的轮廓由分离的笔画顶点和笔画外形(profile)定义。它优于轮廓字体之处在于:减少了定义字形的顶点数,允许同一组顶点生成不同的字体(不同的粗细,不同大小或不同衬线规则)所以节省大小。对于字体开发者,编辑笔画要比编辑轮廓容易而且不易出错。笔画系统也允许改变字形比例而不修改基本字形的笔画粗细。笔画字体用于嵌入式设备在东亚有很大的市场,但这项技术不只用于表意字符。
商业开发者包括Agfa Monotype(iType)Type Solutions Inc。(拥有Bitstream Inc.)(Font Fusion (FFS). btX2),Fontworks(Gaiji Master),台湾文鼎科技都独立开发出了笔画字体和字体引擎。
尽管Monotype和Bitstream都曾声称东亚字符集使用笔画字体显示系统可以极大的节约空间,但是大部分节省源于构造合成字形,这也是TrueType标准一部分。

字体微调(Hinting)

字体微调是指使用数学指令来调整轮廓字体的显示,使其与光栅化网格对齐。在低屏幕分辨率下,微调对于生成清晰易读的文本至关重要。反锯齿和液晶显示器的子像素渲染技术可让已微调的字体进行进一步清晰化
微调可以在字体设计过程中通过字体编辑器来创建,并将其嵌入字体中。可以通过基于字符轮廓的处理算法自动微调,但也可以进行手动设置。大多数的字体编辑器都可以执行自动微调,并且这种方法适用于许多字体,但是,高质量的商业字体通常会进行手动微调来最大化计算机显示器上的清晰度。Verdana是包含大量微调数据的字体的一个示例,这一字体的大部分字体由字体工程师托马斯·里克纳手动完成微调。
notion image

字体绘制

Advance

notion image

结构

每个字体会定义5条度量线来控制字符的位置,其中包括 ascender、descender、capital height、x-height,baseline 这5条度量线,这些度量的刻度是基于1000这个相对单位(不同字体相对单位可能不一样)来设置的,如下图所示:
notion image
  • Baseline: 就是我们常说的基线,所有字母放置的水平线。它是文本中一条稳定的轴线,是校准文本与图片,文本与文本的一条重要的参考线。其他度量线都是相对基线来计算的。
  • X-Height: 是主要的小写字母高度(或者说是“x”字母的高度),除去上延和下延部分
  • Cap Height: Capcapital(大写字母)的简称,有时也用capital height全称,是指H或E等直线型大写字母从基线到字母顶部的高度(大写字母高度)。而H或E等顶部这条对齐线叫作都大写线(cap line
  • Ascender: 升部线,某些小写字母(例如h、l)会有一个升部(也叫上延),高度超出x-height,这是升部的对齐线
  • Descender: 降部线,某些小写字母(例如p、y)会有一个降部(也叫下延),沿基线往下延长的部分,这是降部的对齐线
其中,AscenderDescender之差决定了字体渲染的高度(不考虑行高)

灰度抗锯齿与次像素抗锯齿

notion image
放大来看:
notion image

参考

 

© yooyi 2020 - 2021