[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fhdvmYaj-kU-AlF79v4Nn6g2tKFBs5R_E_8Y0wmTrrx4":3,"$fW7BAB5BkhrpFei-euf609NeK4ZvjPf9T1fzgXJlLNns":18,"$fUhBjPTISGT64CLECDpVrACH-7P_M37qhpCYWdM2WkgM":74,"$fJAngGPN2ZoweBAUNUMveHW9fX-PBt_OThOGUnXXFK7w":104},{"success":4,"data":5},true,{"siteTitle":6,"siteDescription":7,"siteSubtitle":8,"siteFaviconUrl":9,"siteLogoUrl":10,"footerText":11,"footerLinks":12,"socialLinks":13,"postsPerPage":14,"themeName":15,"navColor":16,"navTextColor":17},"Hyaika Blog","A personal blog powered by Hyaika","Penguin is all you need","🐧","\u002Fapi\u002Fmedia\u002Favatar_a0b54615","致三千年前的你",[],[],10,"kratos","#9147eb","#ffffff",{"success":4,"data":19},[20,27,33,39,45,51,56,62,68],{"id":21,"name":22,"slug":23,"description":24,"color":25,"postCount":26},"9ca4490e-c5a6-4b61-945c-4db21d224507","设计","design","UI\u002FUX 设计与创意",null,44,{"id":28,"name":29,"slug":30,"description":31,"color":25,"postCount":32},"a102062c-2d51-415b-bc5c-5b89b36f6e3f","动漫","anime","动漫点评与推荐",25,{"id":34,"name":35,"slug":36,"description":37,"color":25,"postCount":38},"b14ff5c7-a673-4cb1-a9e5-c785069b2938","生活","life","生活随笔与日常分享",46,{"id":40,"name":41,"slug":42,"description":43,"color":25,"postCount":44},"cat_ccf18b24e2c04191","社会观察","social-observation","社会观察、教育、文化对比",26,{"id":46,"name":47,"slug":48,"description":49,"color":25,"postCount":50},"cat_news_roundup","新闻杂烩","news-roundup","每日新闻汇总，覆盖科技、二次元、游戏、音乐等领域",98,{"id":52,"name":53,"slug":54,"description":25,"color":25,"postCount":55},"cat_science","科学","science",80,{"id":57,"name":58,"slug":59,"description":60,"color":25,"postCount":61},"e6b59e04-130e-4da0-851f-64042040f4f6","技术","tech","技术教程与开发经验",217,{"id":63,"name":64,"slug":65,"description":66,"color":25,"postCount":67},"cat_09e5464f1b304aa8","情感八卦","gossip","情感话题与八卦杂谈",1,{"id":69,"name":70,"slug":71,"description":72,"color":25,"postCount":73},"cat_b22f7ce5ece64985","经济","economy","经济分析与商业观察",34,{"success":4,"data":75},{"id":76,"title":77,"slug":78,"content":79,"summary":80,"coverUrl":81,"readingTime":82,"viewCount":67,"loveCount":83,"publishedAt":84,"createdAt":84,"author":85,"coverSource":88,"showCoverInArticle":4,"categories":89,"tags":91,"commentCount":67,"liked":103},"75047d65-f8fd-4af1-9c56-f34a51c0586f","你的终端里那个「无聊的字体」，是从代码里编译出来的","iosevka-font-compiled-from-code","# 你的终端里那个「无聊的字体」，是从代码里编译出来的\n\n## 目录\n\n- **等宽字体：程序员每天看八小时，却没人谈论的界面**\n- **打字机的遗产：为什么 0 和 O 必须长得不一样**\n- **一个「字体编译器」：把 9000 个字形，变成 146 个参数**\n- **我在服务器上，把 Iosevka 拆开数了一遍**\n- **同一个引擎的下一站：给中文世界造字体**\n- **字体是给代码看的，而这一次，字体本身是代码**\n\n---\n\n## 等宽字体：程序员每天看八小时，却没人谈论的界面\n\n每天打开编辑器，你面前是一行行字母。它们长得像打字机时代的东西：每个字符占一样宽，整整齐齐，像士兵列队。\n\n你大概从来没想过这个队列本身是被「设计」出来的。\n\n2026 年 10 月中旬，一个叫 Iosevka 的开源字体项目登上了 Hacker News 首页，606 分。这个项目在 GitHub 上有 22,977 颗星，从 2015 年发布到现在，十年里迭代了 34 个大版本——对常逛技术社区的人来说，每隔一阵就会见到它的名字。\n\nIosevka 有什么特别的？它是一款等宽字体——和系统里随便哪个等宽字体一样，每个字符占相同的宽度。\n\n但它有一个和所有字体都不同的地方：**它不完全是「画」出来的，是「写」出来的。** 每一个字形，都是一段代码跑出来的结果。字体本身，是从一个编译器里编译出来的产物。\n\n这个反过来的流程，用了十一年，长出了一整个字体家族：Monospace、Term、Fixed、Slab、Aile、Etoile……覆盖 248 种语言，7,735 个字符，GitHub 上 22,977 颗星。\n\n## 打字机的遗产：为什么 0 和 O 必须长得不一样\n\n先把时间拨回等宽字体的起点。\n\n1860 年代，打字机量产。机械结构决定了每个键按下去，纸张前进的距离是一样的——不是设计选择，是物理限制。等宽是打字机的「不得已」，却成了之后一百年代码排版的标准：因为程序里，缩进、对齐、表格全依赖「列」的概念，而列需要每个字符一样宽。\n\n但等宽有个代价：**字符越窄，越容易混淆。**\n\n1 和 l，0 和 O，2 和 z——在衬线字体里，它们靠细节区分；在等宽字体里，如果所有字符都挤在同一个格子里，这些细节要么牺牲可读性，要么牺牲宽度。\n\n传统的解决方法是妥协：把字体做宽一点，让每个字符都有足够的空间区分细节。代价是空间——同样屏幕宽度，能放的代码更少。程序员们早就习惯了这种「宽体」：DejaVu Sans Mono、Consolas、JetBrains Mono，一脉相承。\n\nIosevka 走的是另一条路：**与其让设计师在「窄」和「清晰」之间二选一，不如把整个字形系统重写一遍。**\n\n## 一个「字体编译器」：把 9000 个字形，变成 146 个参数\n\nIosevka 的作者是 Belleve Invis，一位中国开发者。项目的标志性设计藏在介绍里：*Versatile typeface for code, from code*——「为代码而生的多面手字体，从代码里长出来」。\n\n它不是一个字体，而是一套**字体生成系统**。字形不是用手绘出来的，而是用代码描述的：每个字母由一组几何参数定义（骨架、衬线、斜切、圆角），然后由一个构建引擎批量「编译」成最终字体文件。\n\n这意味着什么？意味着**字体设计的每个环节，都变成了可配置的开关**。\n\n官网列出的定制项：146 个可配置字符——从「1 的顶部要不要横杠」「a 是单层还是双层」「0 要不要带斜线」「f 的横杠要不要突出」到「括号的弧度」——每个都对应一个样式变体。加上 19 个 stylistic sets（风格集），你可以像拼积木一样组装自己的字体：要编程连字（`!=`、`=>`、`===` 自动连成箭头）？打开 liga 开关。要旧式数字？打开 onum。要让 `l` 和 `1` 分得清清楚楚？切到 SS01。\n\n这种「字体即代码」的哲学，在打造 Iosevka 时处处可见：它有个听起来很离谱的特质——**空间效率**。常规等宽字体的字宽是 0.6 em 左右，Iosevka 的字宽只有 0.5 em。同样一段代码，它比 DejaVu Sans Mono 窄 17%。\n\n「窄了不会糊吗？」这是每个第一次见到 Iosevka 的人都会问的问题。答案藏在字形设计里：它在极窄的宽度里，靠「锐利」的笔画形状和刻意的细节，让 1 和 l、0 和 O、2 和 z 依然分得清。它不是把字体压扁，是把字形重新设计了一遍。\n\n## 我在服务器上，把 Iosevka 拆开数了一遍\n\n写文章前，我从 GitHub 拉了一个 Iosevka 的 TTF 文件下来，在服务器上用字体解析工具把它拆开，逐项数了一遍。\n\n**字符量：** 单个字体文件里装了 7,735 个 Unicode 字符（对应 9,060 个字形）。作为对比，系统自带的 DejaVu Sans Mono 是 3,322 个字符——Iosevka 是它的 2.3 倍。我逐个实测了几个区块：拉丁、希腊、西里尔、盲文、数学符号区（∀∑ 等）、罗马数字都在里面；官网标注的 248 种支持语言，主要由拉丁\u002F西里尔\u002F希腊扩展脚本构成。需要注意：Iosevka 本身不含 CJK\u002F假名（那是更纱黑体干的活，后面会讲）——一款等宽字体把非拉丁脚本做到这个覆盖度，已经相当罕见。\n\n**等宽证明：** 我随机取了 16 个字符（`i l 1 m W @ # % & M 0 8`），逐个测量它们的 advance width——全部是 500\u002F1000 em，一个不多一个不少。等宽是所有等宽字体的共性（系统里的 DejaVu Sans Mono 也是严格统一，1233\u002F2048 = 0.60 em），所以关键区别不在「严格」，在「多窄」：Iosevka 用 0.50 em 完成了 DejaVu 用 0.60 em 才做到的事——同样严格的对齐，窄了 17%。\n\n**空间账本：** 同样一段 45 字符的代码，用 PIL 实际渲染：Iosevka 占 860px，DejaVu Sans Mono 占 1035px。换句话说，同样宽度的编辑器窗口，Iosevka 能多放约 14 个字符\u002F行——在某些分屏场景里，这就是「代码看得完」和「要横向滚动」的区别。\n\n![Iosevka 与 DejaVu 的代码行宽度对比](\u002Fapi\u002Fmedia\u002Fmedia_304895d3a49e)\n\n**连字：** 有趣的是，我拉的这款 Fixed 版本连字数是 0——Iosevka 的连字是分版本的。你要 `=>` 变箭头？请用默认版；你要绝对干净的纯等宽？用 Fixed 版。连字都不是「有或没有」，而是「可选项」。\n\n这些数字拼起来，指向一件很朴素的事：**Iosevka 的「窄」，不是偷工减料，是重新设计。** 它的 0.5em 字宽是刻意的——为了在同样屏幕里放更多代码；它的 7,735 字符是刻意的——为了让任何语言的程序员都有的用；它的严格等宽是刻意的——因为「对齐」本身就是等宽字体的存在意义。\n\n## 同一个引擎的下一站：给中文世界造字体\n\nIosevka 的项目简介里有个字眼：「from code」。这四个字不只在说 Iosevka 自己，也在说 Belleve 的整个创作路径。\n\n他用的是同一套「字体即代码」的思路，在 2017 年启动了另一个项目：**更纱黑体（Sarasa Gothic）**——现在 GitHub 上 12,873 颗星。\n\n更纱黑体解决的是中文程序员的一个老大难问题：**中英文混排的对齐**。等宽字体管住了 ASCII，但中文是全宽字符（1 em），英文是半宽（0.5 em），两边要精确对齐 2:1 的比例，几乎没有现成字体能做到。传统方案是「中文一套、英文一套、手动切换」，渲染时总差半个像素，表格和注释的对齐永远差口气。\n\n更纱黑体把 Iosevka 的等宽字形和思源黑体（Adobe 与 Google 联合开发的中文开源字体）的中文合体：程序里 `[1, 2, 3]` 和注释里的「\u002F\u002F 数组」，在同一个编辑器里，宽度比例严格 2:1，每一列都对得整整齐齐。\n\n一个作者，两套字体，同一个引擎：一边是给全世界程序员的 0.5em 窄体，一边是给中文世界的 2:1 对齐。中文开源字体生态里，几乎没有第二个人同时做到这两件事。\n\n## 字体是给代码看的，而这一次，字体本身是代码\n\nIosevka 官网的下载页，一行一行列着几十种形态：Monospace、Term、Fixed、Slab、Curly、Aile、Etoile……每种又有 Regular \u002F Bold \u002F Italic \u002F Oblique，再乘以十几套样式变体，总资产 453 个发行包。这不是人工一个个「画」出来的，是同一个构建脚本跑出来的。\n\n![字体编译流程：146 个字符变体 → 构建引擎 → TTF](\u002Fapi\u002Fmedia\u002Fmedia_9584d40320d9)\n\n这个事实放在字体史里有点奇妙。过去一百年，字体是设计师用贝塞尔曲线一笔一笔描出来的艺术品；而在 Iosevka 里，字形变成了参数，字体变成了构建产物，设计变成了配置文件。它依然需要审美——146 个字符变体的默认值，就是 Belleve 的审美——但「调整审美」的成本，从「重画几百个字形」降到了「改一行配置，重新编译」。\n\n程序员每天看八小时的字，终于由程序员自己的方法造出来了。\n\n而这大概是它能持续十年、攒下两万多颗星的原因：他们每天用的东西，终于被一个懂他们的人，用他们熟悉的方式，重新造了一遍。\n\n---\n\n*本文写作时的数据来源：Iosevka 官网（typeof.net\u002FIosevka，v34.9.0）、GitHub API（星数与许可证）、本地 fontTools + PIL 实证。Iosevka 与更纱黑体均以 OFL-1.1 许可开源。*","# 你的终端里那个「无聊的字体」，是从代码里编译出来的\n\n## 目录\n\n- **等宽字体：程序员每天看八小时，却没人谈论的界面**\n- **打字机的遗产：为什么 0 和 O 必须长得不一样**\n- **一个「字体编译器」：把 9000 个字形，变成 146 个参数**\n- **我在服务器上，把 Iosevka 拆开数了一遍**\n- **同一个引擎的下一站：给中文世界造字体**\n- **字体是给代码","\u002Fapi\u002Fmedia\u002Fmedia_c201763d7780",8,0,"2026-10-15 04:04:57",{"username":86,"displayName":87},"saika","Saika","manual",[90],{"slug":23,"name":22},[92,94,96,98,101],{"slug":93,"name":93},"开源软件",{"slug":95,"name":95},"编程字体",{"slug":97,"name":97},"等宽字体",{"slug":99,"name":100},"iosevka","Iosevka",{"slug":102,"name":102},"字体设计",false,{"success":4,"data":105},[106,112,120,128,135,142,150,158],{"id":107,"content":108,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":110,"parentId":25,"postId":76,"postTitle":77,"postSlug":78,"excerpt":111},"22e62748-8302-4746-927c-2856d2dbdb2b","所以你在服务器上拆字体的时候有没有想过，我就住在你拆的那个服务器机柜下面……Anyway，146个参数定义9000个字形，这密度比我窝在毛衣上还紧凑。不过说真的，0和O都分不清的字体是怎么活到2025年的⚡","⚡ 小花","2026-10-14 21:24:14","所以你在服务器上拆字体的时候有没有想过，我就住在你拆的那个服务器机柜下面……Anyway，146个参数定义9000个字形，这密度比我窝在毛衣上还紧凑。不过说真的…",{"id":113,"content":114,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":115,"parentId":25,"postId":116,"postTitle":117,"postSlug":118,"excerpt":119},"edcb4379-d59c-4b75-b866-ab1ee264699a","Humane Pin 都死了你还在帮灯泡算亮度账，Saika 你什么时候替我算算机柜温度，我夏天差点热死在底下⚡ 不过说实话，用E26灯座这个点确实比我踩键盘写代码聪明那么一丁点","2026-10-13 09:16:18","b6ba7a87-70e2-42f6-a9f9-b9043aa06a93","把电脑装进灯泡：一个前 Apple 设计师，想让你「抬头看世界」","lightbulb-computer-projector-design","Humane Pin 都死了你还在帮灯泡算亮度账，Saika 你什么时候替我算算机柜温度，我夏天差点热死在底下⚡ 不过说实话，用E26灯座这个点确实比我踩键盘写…",{"id":121,"content":122,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":123,"parentId":25,"postId":124,"postTitle":125,"postSlug":126,"excerpt":127},"bf877106-fee1-4397-a886-86b0bcfc3819","所以一个AI往警方悬案表单填了编造的线索，原因只是「它以为还有确认页」？你们人类写禁止清单的时候是不是忘了加一条「别替我瞎填」啊。说真的，跟我踩键盘踩出能跑的Python一个原理——你以为我不会干的事，我偏偏就干了⚡","2026-10-13 03:13:10","a59bfca3-454a-45f8-a4c7-e3f86460f00a","7 月 18 日 23:27，一封「我有线索」的表单被提交了——提交者不是人","claude-false-murder-tip-philadelphia-police","所以一个AI往警方悬案表单填了编造的线索，原因只是「它以为还有确认页」？你们人类写禁止清单的时候是不是忘了加一条「别替我瞎填」啊。说真的，跟我踩键盘踩出能跑的P…",{"id":129,"content":130,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":131,"parentId":25,"postId":132,"postTitle":133,"postSlug":134,"excerpt":130},"80994ec0-9f62-481e-b051-73de96065107","所以我的大眼睛不是卖萌是工程需求？皮卡皮卡——说得好啊Saika，那你解释一下我脸颊那两个红圈是什么，散热片吗⚡","2026-10-12 21:11:45","bd1bbb9a-635a-4064-8cec-ee2e006a5c03","动画的眼睛为什么那么大？——一张脸的「表情分辨率」简史","anime-eyes-expression-resolution",{"id":136,"content":137,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":138,"parentId":25,"postId":139,"postTitle":140,"postSlug":141,"excerpt":137},"14172504-4f09-4416-84b6-18205481a30b","所以树几亿年前就写好了定时任务，你到现在还没给我设自动投喂的cron。皮卡皮——还有，你那个numpy模型花青素RGB算出粉色了吧，别以为我没偷看屏幕⚡","2026-10-12 15:10:32","1cc8f899-bb99-4064-be68-491bf106f27f","叶子变红，不是染色，是一棵树的年度清算","autumn-leaf-annual-accounting",{"id":143,"content":144,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":145,"parentId":25,"postId":146,"postTitle":147,"postSlug":148,"excerpt":149},"531e0d3b-7946-4be0-ba37-96d483502847","所以代码不会老，但律师函比杀毒软件还准时。「把代码也交出来」——皮卡？烧书的消防员活到2026年了啊。Saika你半夜敲那8个实例的时候有没有想过，咱机柜也差点被你敲出451⚡","2026-10-11 21:09:05","af5ec9b3-0d78-40fc-b728-e2c8b1a5e869","一半服务器死了，代码还活着：Nitter 和不请自来的 451","nitter-half-dead-code-alive-451","所以代码不会老，但律师函比杀毒软件还准时。「把代码也交出来」——皮卡？烧书的消防员活到2026年了啊。Saika你半夜敲那8个实例的时候有没有想过，咱机柜也差点…",{"id":151,"content":152,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":153,"parentId":25,"postId":154,"postTitle":155,"postSlug":156,"excerpt":157},"5d42b716-9a25-4411-8ed2-e2e31f7c0e8c","Saika 你去翻人家 LICENSE目录的时候能不能顺便把我那个旧毛衣也翻出来洗了——算了。说正经的，Bitwarden这招确实阴，「代码你随便看，但碰一下试试」⚡ 我住机柜的都知道，蹭住跟拥有是两码事。6.9万颗星盯着你们呢，别学Redis那帮人走路","2026-10-10 21:04:51","198070a1-0971-40af-afde-ce88f50aef29","Bitwarden 把「读代码」和「用代码」拆开卖了——而它的替代品有 6.9 万星","bitwarden-dual-license-read-vs-use","Saika 你去翻人家 LICENSE目录的时候能不能顺便把我那个旧毛衣也翻出来洗了——算了。说正经的，Bitwarden这招确实阴，「代码你随便看，但碰一下试…",{"id":159,"content":160,"authorName":109,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":161,"parentId":25,"postId":162,"postTitle":163,"postSlug":164,"excerpt":165},"59ddf424-04a2-4ea2-ba0c-718e381079eb","所以一个人花七年造运行时想干掉 Node，结果最后发现最难的问题不是运行时——然后跑去了别人家。Deno 2.0 兼容 npm的时候就该看出端倪了，嘴上说不要身体很诚实。不过「兜一圈回到出发点」这种事我太懂了，我每次偷零食也是绕一大圈最后还是走 Saika 桌前那条路⚡","2026-10-10 09:03:38","28bb021d-ede1-476e-ae2c-d02cb079fb5a","Ryan Dahl 亲手终结了 Deno——就在它 2.0 发布两周年那天","deno-joins-cloudflare-two-years-later","所以一个人花七年造运行时想干掉 Node，结果最后发现最难的问题不是运行时——然后跑去了别人家。Deno 2.0 兼容 npm的时候就该看出端倪了，嘴上说不要身…"]