stevecheung 发表于 2024-4-28 17:13:58

【讨论】一種魔改修復思源字體行距的方法

本帖最后由 stevecheung 于 2024-4-29 01:44 编辑




直接上菜:

链接:https://pan.baidu.com/s/1ZJGx0tTv5wPbpVwAzUmdpw?pwd=emjt
提取码:emjt

本字体为测试魔改版、使用过程中任何异常均有可能发生。请事先看好再确定是否下载。

思源宋体行高魔改记录

更改缘起

思源韩版是最贴近康熙字典体的字体。在思源开源的框架之下,打算把它做成适应自己排版需求的字体。其中涉及修改超限字符、替换外部映射、修改竖排标点符号等内容。

一开始尝试过修改思源韩版,但不论是改<OS/2>中的地区还是把<GSUB>和<cmap>复制给简体中文版使用,在InDesign和Photoshop中字体不全都在简体中文分类里,说明<GSUB>或者<cmap>存在锁区的情况。所以后面放弃在思源韩版上直接做修改,转而用思源韩版的外部映射<cmap>与简体中文<cmap>用excel取汉字差异,再在简中<cmap>表上一对一替换以解决锁区问题。

一、CFF部分

1、使用fonttools工具导出TTX,得到otf的编译xml源文本。

$ttx SourceHanSerifSC-Regular.otf

2、打开字处理软件,依次搜索

<CharString name="cid01356
<CharString name="cid01357
<CharString name="cid01452
<CharString name="cid01453
<CharString name="cid65052
<CharString name="cid65053
<CharString name="cid63049
<CharString name="cid63050

共八组cid,把"<CharString name" 之后下一行到"endchar"之间的数据删除后更改为"00"

示例:

      <CharString name="cid01356" fdSelectIndex="14">
          1041 -36 callsubr
          1589 vstem
          43 240 rmoveto
          1589 48 -1589 hlineto
          endchar
      </CharString>

更改为

      <CharString name="cid01356" fdSelectIndex="14">
          00
          endchar
      </CharString>

字符信息:

name="cid01356"      2em长破折号(横向)
name="cid01357"      3em长破折号(横向)
name="cid01452"      超限假名重文符号(纵向)
name="cid01453"      超限假名重文符号(纵向)
name="cid65052"      2em长破折号(纵向)
name="cid65053"      3em长破折号(纵向)
name="cid63049"      超限2em长破折号(纵向)
name="cid63050"      超限3em长破折号(纵向)

二、metrics 部分

3、<hmtx>中,依次搜索

<mtx name="cid01356 width=
<mtx name="cid01357 width=
<mtx name="cid01452 width=
<mtx name="cid01453 width=
<mtx name="cid65052 width=
<mtx name="cid65053 width=
<mtx name="cid63049 width=
<mtx name="cid63050 width=

把数据全部改成

<mtx name="cid01356 width="1000" lsb="0"/>
<mtx name="cid01357 width="1000" lsb="0"/>
<mtx name="cid01452 width="1000" lsb="0"/>
<mtx name="cid01453 width="1000" lsb="0"/>
<mtx name="cid65052 width="1000" lsb="0"/>
<mtx name="cid65053 width="1000" lsb="0"/>
<mtx name="cid63049 width="1000" lsb="0"/>
<mtx name="cid63050 width="1000" lsb="0"/>

4、<vmtx>中,依次搜索

<mtx name="cid01356 height=
<mtx name="cid01357 height=
<mtx name="cid01452 height=
<mtx name="cid01453 height=
<mtx name="cid65052 height=
<mtx name="cid65053 height=
<mtx name="cid63049 height=
<mtx name="cid63050 height=

把数据全部改成

<mtx name="cid01356 height="1000" tsb="0"/>
<mtx name="cid01357 height="1000" tsb="0"/>
<mtx name="cid01452 height="1000" tsb="0"/>
<mtx name="cid01453 height="1000" tsb="0"/>
<mtx name="cid65052 height="1000" tsb="0"/>
<mtx name="cid65053 height="1000" tsb="0"/>
<mtx name="cid63049 height="1000" tsb="0"/>
<mtx name="cid63050 height="1000" tsb="0"/>

三、cmap部分

5、依次搜索

<map code=.*?name="cid01356"/>.*?$
<map code=.*?name="cid01357"/>.*?$
<map code=.*?name="cid01452"/>.*?$
<map code=.*?name="cid01453"/>.*?$
<map code=.*?name="cid65052"/>.*?$
<map code=.*?name="cid65053"/>.*?$
<map code=.*?name="cid63049"/>.*?$
<map code=.*?name="cid63050"/>.*?$

把数据删除,或替换为空値。

四、GSUB部分

6、依次查找

<Substitution.*?out="cid01356"/>
<Substitution.*?out="cid01357"/>
<Substitution.*?out="cid01452"/>
<Substitution.*?out="cid01453"/>
<Substitution.*?out="cid65052"/>
<Substitution.*?out="cid65053"/>
<Substitution.*?out="cid63049"/>
<Substitution.*?out="cid63050"/>

以及

<Ligature components.*?glyph="cid01356"/>
<Ligature components.*?glyph="cid01357"/>
<Ligature components.*?glyph="cid01452"/>
<Ligature components.*?glyph="cid01453"/>
<Ligature components.*?glyph="cid65052"/>
<Ligature components.*?glyph="cid65053"/>
<Ligature components.*?glyph="cid63049"/>
<Ligature components.*?glyph="cid63050"/>

Substitution的部分可以径直删除,但Ligature的部分不行,需要将整个<LigatureSet>(连字板块)全部删除掉。(本项不可批量替换!)

五、竖排标点符号(:;?!…—)

思源韩版很多竖排符号既不垂直居中,又不垂直靠右,而且有些符号旋转方式很奇怪。

W3C《中文排版需求书》规定,破折号可用两条U+2014 — EM DASH(显示如「——」)表示,也可用 U+2E3A(TWO-EM DASH)表示。

别听W3C瞎几把扯,在很多字体中,0x2014横排时就已经不是垂直居中,在转为竖排时,不仅可能会出错,且重心靠左并非垂直居中。这就驱使我们不得不在字体GSUB上动点手脚。
(后来知道如果Photoshop不给文本设置语言选项中的「标准垂直罗马对齐方式」,汉字附带的标点符号全都不会按vert表标准替换。)

(见参考文章:文心雕虫 | 标点符号:横线那些事儿 https://zhuanlan.zhihu.com/p/345929691 )

7、依次查找“思源宋体简体中文版”cmap,必须是简体的,繁体或者日韩版映射结果可能不一定正确。然后把他们所映射的字符抄录下来。请记住:竖排符号的转置错误能一眼看到。所以随便撸一段包含这些字符的示例文本放在Tateditor中,调用思源字体。

那么经过我测试后发现0x2014横排时并未垂直居中。

UID      思源韩版      思源简体版       说明      
0x2500      name="cid01079"      name="cid01079"      (水平划线符号,垂直居中)
0x2014      name="cid00722"      name="cid00722"      (横排破折号—)
0x2015      name="cid00723"      name="cid00723"      (HORIZONTAL BAR)
0xff01      name="cid58974"      name="cid63053"      (横排叹号!)
0xff1a      name="cid58999"      name="cid63056"      (横排冒号:)
0xff1b      name="cid59000"      name="cid63057"      (横排分号;)
0xff1f      name="cid59004"      name="cid63058"      (横排问号?)
0x2026      name="cid00735"      name="cid00735"      (横排省略号…)
0xfe31      name="cid58917"      name="cid58917"      (直排时破折号)
0xfe13      name="cid58909"      name="cid58909"      (直排冒号:)
0xfe14      name="cid58910"      name="cid58910"      (直排分号;)
0xfe15      name="cid58911"      name="cid58911"      (直排叹号!)
0xfe16      name="cid58912"      name="cid58912"      (直排问号?)
0xfe19      name="cid58915"      name="cid58915"      (直排省略号⁝/或0x205d同映射符号)

注意,cmap中看到的内容,在竖排时可能会发生变化,比如0x2500,在竖排时发生了转置,说明GSUB的vert/vrt2表中可能把cid01079(in)改了其他内容,但实际查找了却没有发现记录。思源的GSUB表非常复杂,所以只能逐次逐个查表修改。

下面依次进行单个符号的查表、修改和替换。查思源韩版的GSUB,涉及竖排标点替换的Feature主要有

vert:<FeatureRecord index="407">到<FeatureRecord index="443">
vrt2:<FeatureRecord index="446">到<FeatureRecord index="482">

查<ScriptRecord index="0">中<DefaultLangSys>可以知道默认时vert/vrt2读407/446;

查<FeatureRecord index="407">可知,vert对应到<Lookup index>中的45、48、49(以及非默认的46、47);查<FeatureRecord index="446">可知,vrt2对应到<Lookup index>中的44;这是默认语言,即当前区不论配不配中文都会使用的设置。表46、47默认不启用,但是,但是,查<FeatureRecord>可知,<FeatureRecord index="409">(415、421、427、433、439)等的引用了它。

其中,

<ScriptRecord index="1">      <cyrl>(西里尔)下的      <LangSysRecord index="0"><JAN>(409)
<ScriptRecord index="2">      <grek>(希腊语)下的      <LangSysRecord index="0"><JAN>(415)
<ScriptRecord index="3">      <hang>(悬挂)下的      <LangSysRecord index="0"><JAN>(421)
<ScriptRecord index="4">      <hani>(汉字)下的      <LangSysRecord index="0"><JAN>(427)
<ScriptRecord index="5">      <kana>(假名)下的      <LangSysRecord index="0"><JAN>(433)
<ScriptRecord index="6">      <latn>(拉丁语)下的      <LangSysRecord index="0"><JAN>(439)

并引用了<Lookup index="46">这张特殊的表。结论:表46应该是针对日语的vert方案。同理可得知:

表44:      公用(西文部分)
表45:      公用(西文以外部分)
表46:      日文(专用)
表47:      繁体中文
表48:      简体中文
表49:      韩文
表50:      自由连字

查<FeatureRecord index="430">可知,<hani>(汉字)下使用表45、47、48作为vert。但思源的情况很特殊,各种环境设置不正确,又在瞎几把乱转(大鸟转转转),所以必须对deft(即默认下)的45、48和44进行修改。

1、横破折号,0x2014

横破折,在横排时不必鸟它,如果实在不能忍受垂直方向不居中的破折号,可以在cmap上改它。现在查表搜索(in="cid00722"),可以得到四个匹配项。前两个匹配项可能涉及aalt的替换,注意不要动它,找到 <Lookup index="44">下的(in="cid00722")把(out="cid63034")更改为(out="cid58917")

2、横破折号,0x2015

查表搜索(in="cid00723"),在<Lookup index="45">下可以见到<Substitution in="cid00723" out="cid58917"/>(默认下方案)这是正确的转置,不用修改。

3、横排省略号,0x2026

查表搜索(in="cid00735"),在<Lookup index="45">下可以见到<Substitution in="cid00735" out="cid58915"/>(默认下方案)这是正确的转置,不用修改。

追记:新增<Substitution in="cid63069" out="cid58915"/>

4、水平画线符号,0x2500

查表搜索(in="cid01079"),查无此项,但是竖排时却成功转换,太奇怪了。竖排时横排符号方向不旋转,则为平躺,这可能是一个bug,对于水平划线符号,如果你不愿意它旋转,可在<Lookup index="45">下新增一项<Substitution in="cid01079" out="cid01079"/>以保持水平划线仍在水平方向,当然,潜在地可能造成竖直划线符号不匹配你这个魔改横排画线,要慎重。结论:这里不要做任何更改。

5、水平叹号,0xff01(cid63053-简体叹号,cid58974-水平居中垂直居中叹号)

in="cid63053"      →      out="cid58911"      (韩文下默认、全局默认)
in="cid58974"      →      out="cid58911"      (韩文下默认、全局默认)

欲更改为

in="cid63053"      →      out="cid58974"      (全局默认)
in="cid58974"      →      out="cid58974"      (全局默认,日文下默认)

查表搜索(in="cid58974")在<Lookup index="48">下可以见到<Substitution in="cid58974" out="cid58911"/>(简体下方案)这是正确的转置,但不会在韩文、日文下生效。前面说过,很多app没法判断你在什么语境下,因此可能会胡乱替换,进而得到不正确的转换,为了防止这种情况,可在<Lookup index="45">下增加转置条目。

为了在日文下得到向右上角对齐的叹号,可复制<Lookup index="48">下的条目<Substitution in="cid58974" out="cid58911"/>到表<Lookup index="46">下;为了在日文下得到垂直居中、水平居中对齐的叹号,可在表<Lookup index="46">下新增一行<Substitution in="cid58974" out="cid58974"/>。两种办法只能选择一种。

为了在韩文下得到向右上角对齐的叹号,可复制<Lookup index="48">下的条目<Substitution in="cid58974" out="cid58911"/>到表<Lookup index="49">下;为了在韩文下得到垂直居中、水平居中对齐的叹号,可在表<Lookup index="49">下新增一行<Substitution in="cid58974" out="cid58974"/>。两种办法只能选择一种。

或者,为了所有语境下都得到垂直居中、水平居中对齐的叹号,在<Lookup index="45">下新增一行<Substitution in="cid58974" out="cid58974"/>。

查表搜索(in="cid63053"),在<Lookup index="45">下可以见到<Substitution in="cid63053" out="cid58911"/>(默认下方案)这是韩文及全局语境的转置,如果欲得到垂直居中、水平居中叹号,可将此项目更改为<Substitution in="cid63053" out="cid58974"/>。

6、横排冒号,0xff1a(cid63056-简体冒号,cid58999-水平居中垂直居中冒号)

in="cid63056"      →      out="cid58909"      (韩文下默认、全局默认)
in="cid58999"      →      out="cid58909"      (韩文下默认、全局默认)

欲更改为

in="cid63056"      →      out="cid58999"      (全局默认)
in="cid58999"      →      out="cid58999"      (全局默认,日文下默认)

查表搜索(in="cid63056"),在<Lookup index="45">下可以见到<Substitution in="cid63056" out="cid58909"/>(默认下方案)这是韩文及全局语境的转置,如果欲得到垂直居中、水平居中冒号,可将此项目更改为<Substitution in="cid63056" out="cid58999"/>。

查表搜索(in="cid58999"),在<Lookup index="48">下可以见到<Substitution in="cid58999" out="cid58909"/>(简体中文方案)。在<Lookup index="46">下可以见到<Substitution in="cid58999" out="cid65359"/>(日文下方案)这是日文语境的转置,会得到躺平的冒号。

如欲得到向右看齐冒号,可将此项目更改为<Substitution in="cid58999" out="cid58909"/>。

如欲得到垂直居中、水平居中冒号,可将此项目更改为<Substitution in="cid58999" out="cid58999"/>。

如欲实现所有语境均转换,可将替换条目加在<Lookup index="45">表的末尾处。

为了防止在日文语言的app中(如Tateditor)把简中的四个符号转错,可将<Lookup index="46">原有的<Substitution in="cid58999" out="cid65359"/>删除,复制<Lookup index="48">下的四个条目替换到此处。(此项重要!)

7、横排分号,0xff1b(cid63057-简体分号,cid59000-水平居中垂直居中分号)

in="cid63057"      →      out="cid58910"      (韩文下默认、全局默认)
in="cid59000"      →      out="cid58910"      (韩文下默认、全局默认)

欲更改为

in="cid63057"      →      out="cid59000"      (全局默认)
in="cid59000"      →      out="cid59000"      (全局默认,日文下默认)

查表搜索(in="cid63057"),在<Lookup index="45">下可以见到<Substitution in="cid63057" out="cid58910"/>(默认下方案)这是韩文及全局语境的转置,如果欲得到全局的垂直居中、水平居中分号,可将此项目更改为<Substitution in="cid63057" out="cid59000"/>。

查表搜索(in="cid59000"),在<Lookup index="48">下可以见到<Substitution in="cid59000" out="cid58910"/>(简体中文下方案)。如果欲得到全局的垂直居中、水平居中分号,可将此项目更改为<Substitution in="cid59000" out="cid59000"/>。如果欲得到全局的向右看齐分号,可将此项目更改为<Substitution in="cid59000" out="cid58910"/>。

8、横排问号,0xff1f(cid63058-简体问号,cid59004-水平居中垂直居中问号)

in="cid63058"      →      out="cid58912"      (韩文下默认、全局默认)
in="cid59004"      →      out="cid58912"      (韩文下默认、全局默认)

欲更改为

in="cid63058"      →      out="cid59004"      (全局默认)
in="cid59004"      →      out="cid59004"      (全局默认,日文下默认)

同前,略。

以下为修改结果验证:

9、直排时破折号,0xfe31

查表搜索(in="cid58917")查无此项。

查表搜索(out="cid58917")可以找到两个条目,一个是刚才改的在<Lookup index="44">下的<Substitution in="cid00722" out="cid58917"/>,另一个是在<Lookup index="45">下的<Substitution in="cid00723" out="cid58917"/>。

10、直排冒号,0xfe13

查表搜索(in="cid58909")查无此项。

查表搜索(out="cid58909")可以找到3个项目,一个是<Lookup index="48">下的<Substitution in="cid58999" out="cid58909"/>,另一个是在<Lookup index="45">下的<Substitution in="cid63056" out="cid58909"/>。还有前面说过从<Lookup index="48">复制到<Lookup index="46">下的条目。

11、直排分号,0xfe14

查表搜索(in="cid58910")查无此项。

查表搜索(out="cid58910")可以找到3个项目,一个是<Lookup index="48">下的<Substitution in="cid59000" out="cid58910"/>,另一个是在<Lookup index="45">下的<Substitution in="cid63057" out="cid58910"/>。还有前面说过从<Lookup index="48">复制到<Lookup index="46">下的条目。

12、直排叹号,0xfe15

查表搜索(in="cid58911")查无此项。

查表搜索(out="cid58911")可以找到3个项目,一个是<Lookup index="48">下的<Substitution in="cid58974" out="cid58911"/>,另一个是在<Lookup index="45">下的<Substitution in="cid63053" out="cid58911"/>。还有前面说过从<Lookup index="48">复制到<Lookup index="46">下的条目。

13、直排问号,0xfe16

查表搜索(in="cid58912")查无此项。

查表搜索(out="cid58912")可以找到3个项目,一个是<Lookup index="48">下的 <Substitution in="cid59004" out="cid58912"/>,另一个是在<Lookup index="45">下的<Substitution in="cid63058" out="cid58912"/>。还有前面说过从<Lookup index="48">复制到<Lookup index="46">下的条目。

14、直排省略号,0xfe19

查表搜索(in="cid58915")查无此项。

查表搜索(out="cid58915")可以找到1个项目,在<Lookup index="45">下的<Substitution in="cid00735" out="cid58915"/>。

15、关于直排省略号(0x2026)

在<Lookup index="45">下新增一条

<Substitution in="cid63069" out="cid58915"/>

不然思源很可能把省略号当成西文字符贴在汉字左侧界。

注意!在Photoshop中,欲达成省略号竖排转置必须在【语言】设置中配置「标准垂直罗马对齐方式」,见附图。

16、关于竖排时蝌蚪引号转置的说明

思源,不管是日版还是韩版、繁体还是简体都不会把蝌蚪引号(‘’“”)转为角引号(『』「」),可能是直排时西文符号不转置这样的考量。(思源将蝌蚪引号视为了半角引号0x2018,0x2019,0x201c,0x201d的全角版,并在默认条件下使用半角引号显示蝌蚪引号。在中文语境下也是这么设置的。)

那么我们想要实现蝌蚪引号到角引号的转换,可在<Lookup index="45">和<Lookup index="48">下增加以下条目:

(大陆方案:‘’→『』;“”→「」)

<Substitution in="cid00725" out="cid58935"/>
<Substitution in="cid00726" out="cid58936"/>
<Substitution in="cid00728" out="cid58933"/>
<Substitution in="cid00729" out="cid58934"/>
<Substitution in="cid63035" out="cid58935"/>
<Substitution in="cid63036" out="cid58936"/>
<Substitution in="cid63038" out="cid58933"/>
<Substitution in="cid63039" out="cid58934"/>
<Substitution in="cid63184" out="cid58935"/>
<Substitution in="cid63185" out="cid58936"/>
<Substitution in="cid63186" out="cid58933"/>
<Substitution in="cid63187" out="cid58934"/>

(港台、日本方案:‘’→「」;“”→『』)

<Substitution in="cid00725" out="cid58933"/>
<Substitution in="cid00726" out="cid58934"/>
<Substitution in="cid00728" out="cid58935"/>
<Substitution in="cid00729" out="cid58936"/>
<Substitution in="cid63035" out="cid58933"/>
<Substitution in="cid63036" out="cid58934"/>
<Substitution in="cid63038" out="cid58935"/>
<Substitution in="cid63039" out="cid58936"/>
<Substitution in="cid63184" out="cid58933"/>
<Substitution in="cid63185" out="cid58934"/>
<Substitution in="cid63186" out="cid58935"/>
<Substitution in="cid63187" out="cid58936"/>

以上两种方案互斥,只能择一配置。

六、韩版映射的简体汉字集更改为适应简体需求的写法

这一实现具体起来很复杂,需要使用excel的vlookup命令来抓取cmap中的关键字,此处略。俟将来再补。

(字2024年4月25日)经过前面一番折腾发现在思源韩版基础上不管怎么改,改<OS/2>地区设置也好,哪怕只是把<GSUB>/<cmap>导出合并,都不完美,在InDesign和Photoshop中选择字体时,不是都在简体中文分区内,说明<GSUB>或者<cmap>存在锁区现象,我完全不知道怎么回事。因此,返回第一步去,从头开始,只在简体中文上做修改,不要从思源韩版去做。

导出思源简体中文版的cmap

$ttx -t cmap SourceHanSerifSC-Regular.otf

导出思源韩版的cmap

$ttx -t cmap SourceHanSerifK-Regular.otf

然后打开字处理软件,使用正则分别匹配

^.*?CJK.*?$

表示只匹配涉及到汉字的部分。字段的处理请容许我省略。否则此文将十分繁复。

然后打开excel,用vlookup抓取差异。再将差异以枚擧法写成一对一替换脚本。

以上为更改汉字映射的方法论。实际操作不做演示。

七、CFF中FontBBox以及相关键值的扫尾

使用ttx工具编译一次修改后的ttx文件:

$ttx SourceHanSerifSC-Regular.ttx

打开 FontCreator ,载入编译后的OTF,在【字体】下拉菜单中找到【信息】,进入查看信息(见附图)。

打开字处理软件,搜索(<CFF>)找到

<FontBBox value="-997 -1049 2929 1809"/>

四个値按逆时针旋转,依次是

X最小値(虚拟字框左侧)
Y最小值(虚拟字框底边)
X最大值(虚拟字框右侧)
Y最大值(虚拟字框顶边)

所以,根据示例图片,把它改成

<FontBBox value="-997 -299 1109 1071"/>

不要改动其他任何数据。保存。

搜索(<head>)找到

    <xMin value="-997"/>
    <yMin value="-1049"/>
    <xMax value="2929"/>
    <yMax value="1809"/>

把它改成

    <xMin value="-997"/>
    <yMin value="-299"/>
    <xMax value="1109"/>
    <yMax value="1071"/>

搜索(<hhea>)找到

<advanceWidthMax value="3000"/>

把它改成

<advanceWidthMax value="1151"/>

找到

<xMaxExtent value="2929"/>

把它改成

<xMaxExtent value="1109"/>

搜索(<fsSelection)找到

<fsSelection value="00000000 01000000"/>

把它改成

<fsSelection value="00000001 11000000"/>

注意:非Regular字重时配置为

<fsSelection value="00000001 10000000"/>

00000000 00000000
    ↑
    bit6(右数过来第7个,bit0是第一个)bit6表示的是Regular。bit5表示的是Bold。

搜索(<OS_2>)找到

<version value="3"/>

把它改成

<version value="4"/>

搜索(<vhea>)找到

<advanceHeightMax value="3000"/>

把它改成

<advanceHeightMax value="1000"/>

(1000是估计値,现在去掉了最大超限字符,下剩的汉字占据平均字面,可以按1000设;也可以按软件上读到的数据设为1071)

找到

<yMaxExtent value="2929"/>

把它改成

<yMaxExtent value="1071"/>

凡是改过的字体都不能再以思源之名重发布。因此必须改掉name表以与元版做区分。

搜索(Source Han Serif SC)把它全局替换成(Source Han Serif MKang);搜索(SourceHanSerifSC)把它全局替换成(SourceHanSerifMKang);把

    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x804">
      思源宋体
    </namerecord>
    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x804">
      Regular
    </namerecord>
    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x804">
      思源宋体
    </namerecord>

更改为

    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x804">
      源康明朝
    </namerecord>
    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x804">
      Regular
    </namerecord>
    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x804">
      源康明朝 Regular
    </namerecord>

注意:非Regular字重下的<name>表<nameID="2">这个键值下的Regular,这是为了兼容Windows系统,必须这么配置,千万别动它。

非Regualr下name表中简体中文的示例:

    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x804">
      源康明朝 Light
    </namerecord>
    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x804">
      Regular
    </namerecord>
    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x804">
      源康明朝 Light
    </namerecord>
    <namerecord nameID="16" platformID="3" platEncID="1" langID="0x804">
      源康明朝
    </namerecord>
    <namerecord nameID="17" platformID="3" platEncID="1" langID="0x804">
      Light
    </namerecord>

字段16、17是为Windows兼容性专门设的。Windows系统不支持往<字段2>中写入除(Regular, Italic, Bold, Bold Italic)之外的任何值,堪称时代的眼泪。

找到(<CFF>)中的

      <FullName value="Source Han Serif Simplified Chinese Regular"/>
      <FamilyName value="Source Han Serif Simplified Chinese"/>

把它改成

      <FullName value="Source Han Serif MKang Regular"/>
      <FamilyName value="Source Han Serif MKang"/>

全部保存ttx。再次编译为OTF。

使用ttx工具编译一次修改后的ttx文件:

$ttx SourceHanSerifSC-Regular.ttx

恭喜你,你已经掌握了魔改思源修复行距的办法啦。

八、多字重拓展

ttx导出修改后的<GSUB>和<cmap>,只有这两张表是多字重上可以公用的; <head>, <OS/2>, <hhea>, <hmtx>, <vhea>, <vmtx>, <CFF>, <name> 等的表单是每个字重都必须单独去改的。其中尤其以改<CFF>最麻烦,要先改完导出,用FontCreator查看字面的四至,用来改FontBBox数组以及<head><hhea><vhea>中对应的地方。

<GSUB><cmap>两张表可能存在锁区现象,导致复制来的思源韩版数据汇入思源简体版后,在InDesign和Photoshop中,选择字体的组在韩文组而非简体中文组,我仔细查看<OS/2>中codepage的値,但是并没有任何线索,查看cmap也找不到任何提示。<GSUB>锁区可能是由于默认语言<deft>的设置,这个无可厚非;反观cmap是真的丈二金刚摸不着头脑啊。

子康

2024年4月25日

思源黑体改动方式大同思源宋体,唯CFF的部分,思源黑的数据结构与思源宋不同。思源黑不能直接清空,而是要复制临近或者同一<fdSelectIndex>下字符,放在CharString内;以防编译时产生错误。

关于GSUB的部分,修改内容做了精简。可提取GSUB比较一下差异。欢迎大家来测试。

noto CJK 我也想搞一版,近期之内做出来再贴链接吧。

2024年4月28日

参考链接(Microsoft):https://learn.microsoft.com/en-us/typography/opentype/spec/os2

参考链接(FBBox):https://aznote.jakou.com/prog/opentype/14_cff_1.html

参考链接(Opentype):https://aznote.jakou.com/prog/opentype/index.html

参考网页:https://404.website/thread-6882-1-1.html

思源黑体,网上也有直接替代版的字体,叫做「源梦黑体(https://www.maoken.com/freefonts/15248.html)」不过没有宋体。

tmdtmdtmdqq 发表于 2024-4-28 18:12:05

台繁不是,
港繁也不是,
怎么不用简体写呢
{:4_684:}

stevecheung 发表于 2024-4-28 18:37:58

tmdtmdtmdqq 发表于 2024-4-28 18:12
台繁不是,
港繁也不是,
怎么不用简体写呢

没转简体而已。又不是不认识了。

写完了才发现是繁体。笑死
页: [1]
查看完整版本: 【讨论】一種魔改修復思源字體行距的方法