Skip to content

Commit

Permalink
New essay: 中文字库嵌入Web时的分割与裁剪
Browse files Browse the repository at this point in the history
  • Loading branch information
apqx committed Apr 24, 2024
1 parent 334f3d3 commit 35fedfd
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 10 deletions.
78 changes: 74 additions & 4 deletions _archives/url-map.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,27 @@ sitemap: false
"title": "昆曲「西厢记·佳期」折子"
}
},
{
"id": "op17",
"target": {
"path": "{% link _posts/opera/2023-11-04-昆曲「玉簪记·偷诗」折子.md %}",
"title": "昆曲「玉簪记·偷诗」折子"
}
},
{
"id": "op18",
"target": {
"path": "{% link _posts/opera/2023-08-12-昆曲「红梨记·亭会」折子.md %}",
"title": "昆曲「红梨记·亭会」折子"
}
},
{
"id": "op19",
"target": {
"path": "{% link _posts/opera/2022-11-06-昆曲「水浒记·借茶」折子.md %}",
"title": "昆曲「水浒记·借茶」折子"
}
},
{
"id": "og00",
"target": {
Expand Down Expand Up @@ -199,28 +220,77 @@ sitemap: false
"id": "ot00",
"target": {
"path": "https://www.bilibili.com/video/BV1Ch411v7PY",
"title": "【倪润志】昆曲-扈家庄(水仙子)"
"title": "【倪润志】扈家庄(水仙子)"
}
},
{
"id": "ot01",
"target": {
"path": "https://www.bilibili.com/video/BV16f4y187jB",
"title": "【倪润志&张唐逍】昆曲-雷峰塔·水斗(水仙子)"
"title": "【倪润志&张唐逍】雷峰塔·水斗(水仙子)"
}
},
{
"id": "ot02",
"target": {
"path": "https://www.bilibili.com/video/BV1sN4y1P7RM",
"title": "【倪润志】昆曲-青冢记·昭君出塞"
"title": "【倪润志】青冢记·昭君出塞"
}
},
{
"id": "ot03",
"target": {
"path": "https://www.bilibili.com/video/BV1Nf4y1h7ce",
"title": "【倪润志&王恒涛】昆曲-雷峰塔·断桥(金络索)"
"title": "【倪润志&王恒涛】雷峰塔·断桥(金络索)"
}
},
{
"id": "ot04",
"target": {
"path": "https://www.bilibili.com/video/BV1Mz4y1P7Gv",
"title": "【吴心怡】玉簪记·偷诗(绣带儿)"
}
},
{
"id": "ot05",
"target": {
"path": "https://www.bilibili.com/video/BV1qN4y1S76c",
"title": "【王恒涛&吴心怡】玉簪记·偷诗(滴溜子、鲍老催)"
}
},
{
"id": "ot06",
"target": {
"path": "https://www.bilibili.com/video/BV1Vf4y1V7Tb",
"title": "【王文惠&王恒涛】红梨记·亭会(五供养)"
}
},
{
"id": "ot07",
"target": {
"path": "https://www.bilibili.com/video/BV1hN411z7Vn",
"title": "【王文惠&席秉琪】红梨记·亭会(五供养)"
}
},
{
"id": "ot08",
"target": {
"path": "https://www.bilibili.com/video/BV1tz4y1g7V6",
"title": "【席秉琪】红梨记·亭会(桂枝香)"
}
},
{
"id": "ot09",
"target": {
"path": "https://www.bilibili.com/video/BV1x14y1p7CD",
"title": "【高璟玟&杜鸿泽】水浒记·借茶(一封书)"
}
},
{
"id": "ot10",
"target": {
"path": "https://www.bilibili.com/video/BV17G411w7uv",
"title": "【杜鸿泽】水浒记·借茶(醉罗歌)"
}
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 水浒记 借茶 高璟玟 杜

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20221106/shuihuji_jiecha/DSC06280_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="水浒记 借茶 高璟玟 杜鸿泽" }

*那一定是“碧螺春”*
*那一定是“碧螺春”😋*

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20221106/shuihuji_jiecha/DSC06282_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="水浒记 借茶 高璟玟 杜鸿泽" }

Expand All @@ -141,7 +141,7 @@ tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 水浒记 借茶 高璟玟 杜

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20221106/shuihuji_jiecha/DSC06300_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="水浒记 借茶 高璟玟 杜鸿泽" }

*那一定是“井水”喽😜*
*那一定是“泉水”喽😜*

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20221106/shuihuji_jiecha/DSC06302_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="水浒记 借茶 高璟玟 杜鸿泽" }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ actor: 王文惠 席秉琪
mention:
date: 2023-08-12 +0800
location: 杭州大剧院·可变剧场
description: 昆曲之闺门旦特别细腻也特别软,或活泼或恬静,都是自然的莺声燕语,而且“她的眼睛会说话”也是真的,灵动到闪闪发光✨。喜欢小剧场里你侬我侬的生旦戏,美极了,只不过看完会上头,二度「亭会」依然“月悬明镜,好笑我贪杯酩酊”...
description: 昆曲之闺门旦特别细腻也特别软,或活泼或恬静,都是自然的莺声燕语,而且“她的眼睛会说话”也是真的,灵动到闪闪发光✨。喜欢小剧场里你侬我侬的生旦戏,美极了,只不过看完会上头,三度「亭会」依然“月悬明镜,好笑我贪杯酩酊”...
cover: https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20230812/hongliji_tinghui/DSC02290_thumb.jpg
index-cover: https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20230812/hongliji_tinghui/DSC02266_thumb.jpg
tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 红梨记 亭会 王文惠 席秉琪 杭州大剧院·可变剧场
Expand All @@ -24,7 +24,7 @@ tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 红梨记 亭会 王文惠 席

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20230812/hongliji_tinghui/DSC02293_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="红梨记 亭会 王文惠" }

只不过,二度「亭会」依然上头,“月悬明镜,好笑我贪杯酩酊”...
只不过,三度「亭会」依然上头,“月悬明镜,好笑我贪杯酩酊”...

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20230812/hongliji_tinghui/DSC02290_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="红梨记 亭会 王文惠 席秉琪" }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ actor: 吴心怡 王恒涛
mention: 单雯 施夏明
date: 2023-11-04 +0800
location: 杭州大剧院·可变剧场
description: “每次来见你们都会有点紧张,因为你们真的太好看了”👁️,三天前在杭州剧院后台见到她时随口而出,这确实是我的真实感觉。正因为好看,省昆的雯明组合初登舞台就吸引那么多人走进兰苑,二十年后的今天,昆曲已不再式微,但要身处如此快节奏时代的年轻人慢下脚步,去倾听文辞和古典声乐的交响,“好看”是不可或缺的。
description: “每次来见你们都会有点紧张,因为你们真的太好看了👁️”,三天前在杭州剧院后台见到她时随口而出,这确实是我的真实感觉。正因为好看,省昆的雯明组合初登舞台就吸引那么多人走进兰苑,二十年后的今天,昆曲已不再式微,但要让身处如此快节奏时代的年轻人慢下脚步,去倾听文辞和古典声乐的交响,“好看”是不可或缺的。
cover: https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20231104/yuzanji_toushi/DSC07047_thumb.jpg
tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 玉簪记 偷诗 吴心怡 王恒涛 杭州大剧院·可变剧场
---
Expand All @@ -19,7 +19,7 @@ tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 玉簪记 偷诗 吴心怡 王
{: class="surface-block"}
「偷诗」是《玉簪记》常演的「琴挑」「问病」「偷诗」「秋江」第三折,书生`潘必正`寄居在姑母的女贞观中,得遇道姑`陈妙常`,深为爱慕。`妙常`也禁不住对``的思念之情,在卧室中填词一首,流露相思。不料此词被``所得,反以词而责,`妙常`难以掩饰,终于海誓山盟。

“每次来见你们都会有点紧张,因为你们真的太好看了”👁️,三天前在杭州剧院后台见到她时随口而出,这确实是我的真实感觉。正因为好看,省昆的`雯明`组合初登舞台就吸引那么多人走进兰苑,二十年后的今天,昆曲已不再式微,但要身处如此快节奏时代的年轻人慢下脚步,去倾听文辞和古典声乐的交响,“好看”是不可或缺的
“每次来见你们都会有点紧张,因为你们真的太好看了👁️”,三天前在杭州剧院后台见到她时随口而出,这确实是我的真实感觉。正因为好看,省昆的`雯明`组合初登舞台就吸引那么多人走进兰苑,二十年后的今天,昆曲已不再式微,但要让身处如此快节奏时代的年轻人慢下脚步,去倾听文辞和古典声乐的交响,“好看”是不可或缺的。

*`单雯``施夏明`,图源[笠原May的新浪博客](http://blog.sina.com.cn/s/blog_4aed27970100cwz6.html){: target="_blank" }*

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
layout: post
categories: original
title: "中文字库嵌入Web时的分割与裁剪"
author: 立泉
mention: 霞鹜文楷 CnFontSplit
date: 2024-04-24 +0800
description: 可能注意到这个博客站点的字体有点奇怪,并不是常见的无衬线黑体,而是一种接近宋体但又像手写楷书的字体。其实是一款兼顾排版和中文美感的霞鹜文楷开源字体,但要将它嵌入博客中,需要解决一些应用中文字库的典型问题。
cover:
tags: Code Blog Font 霞鹜文楷 CnFontSplit TTF WOFF2
---

可能注意到这个博客站点的字体有点奇怪,并不是常见的无衬线`黑体`,而是一种接近`宋体`但又像手写`楷书`的字体。其实是一款兼顾排版和中文美感的[霞鹜文楷](https://github.com/lxgw/LxgwWenKai){: target="_blank" }开源字体,但要将它嵌入博客中,需要解决一些应用中文字库的典型问题。

## 分割

其中最大的问题是中文字库的庞大体积,英文字库无非是字母和符号,如[JetBrains Mono](https://www.jetbrains.com/lp/mono/){: target="_blank" }的`WOFF2`文件体积仅为92KB,可以非常方便的在`Web`中无感加载。但中文字库收录的汉字数以千计,而且笔画复杂,以8000字的`霞鹜文楷GB`为例,`Regular`字重的`TTF`文件为18.3MB,如果加上常用的`Bold`字重,体积就已经超过36MB,这么大的单体资源对网页加载是不可接受的。

所以中文字库必须分割,按常用字顺序以百KB为单位分割为多个`WOFF2`文件,再由页面按需加载。

```css
/* CSS支持为字体文件指定其包含的字符编码范围 */
@font-face {
font-family: "LXGW WenKai GB";
src: url("https://hosturl.com/01.woff2") format("woff2");
font-style: normal;
font-weight: 400;
font-display: swap;
/* 字符编码范围 */
unicode-range: U+305e3, U+305f6, U+3067d ...;
}
@font-face {
font-family: "LXGW WenKai GB";
src: url("https://hosturl.com/02.woff2") format("woff2");
font-style: normal;
font-weight: 400;
font-display: swap;
/* 字符编码范围 */
unicode-range: U+2ce29-2ce2a, U+2ce31, U+2ce7c ...;
}
```

其实用过[Google Fonts](https://fonts.google.com/specimen/Ma+Shan+Zheng?subset=chinese-simplified){: target="_blank" }就会知道它对中文字库也是这么处理的,所以现在问题就变成了如何分割字库。

网上冲浪发现[中文网字计划](https://chinese-font.netlify.app){: target="_blank" }的[cn-font-split](https://github.com/KonghaYao/cn-font-split){: target="_blank" }项目很不错,一个简单命令就可以把`TTF`文件分割为数百个60KB的`WOFF2`文件并生成`CSS`代码,而且也支持指定要裁剪的字符编码范围,只生成包含所需字符的字库文件。

```sh
# 执行分割,指定输入TTF文件和输出目录
cn-font-split -i=/Users/apqx/Downloads/Input.ttf -o=/Users/apqx/Downloads/Output
```

配合浏览器缓存策略,每个页面加载的字体资源至多也不过几百KB,已属正常范围。这个问题解决后,选择字体就再不用为此纠结,放心使用喜欢的中文字库。

## 裁剪

我的博文中会经常嵌入代码块,之前一直使用等宽的`JetBrains Mono`字体,但应用`霞鹜文楷`后发现英文`黑体`和中文`楷体`混在一起总感觉怪怪的...所幸`霞鹜文楷`也提供等宽版本,但却是包含完整8000汉字的`TTF`字库,这些汉字与已有字库重叠,而我所需只是其中的英文和符号。

借助`cn-font-split`的裁剪功能,可以从`TTF`中提取出指定范围的字符,生成独立的`WOFF2`文件。

```ts
import {fontSplit} from 'cn-font-split';

await fontSplit({
// 要分割的字体文件
FontPath: `/Users/apqx/Downloads/Input.ttf`,
// 输出目录
destFold: `/Users/apqx/Downloads/Output`,
// 输出格式 woff2
targetType: 'woff2',
// 分包大小 70KB
chunkSize: 70 * 1024,
// 关闭自动分包,只打包 subsets 中指定的字符
autoChunk: false,
// 指定要打包的字符
subsets: [
// 数字、字母、符号
'1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()-_=+\\|{}[];:\'"<>,.?/ '
.split('')
.filter(Boolean)
.map((i) => i.charCodeAt(0))
],
testHTML: true,
threads: {},
previewImage: {},
});
```

同理我的博客中还存在一些使用手写字体的中文片段,没必要为它们引入整个字库,也是裁剪处理。

0 comments on commit 35fedfd

Please sign in to comment.