复制粘贴的「字体」根本不是字体:什么弄坏了我的代码
来源:dev.to — 2026-09-02
📋 概述
作者做了一款叫 Fonti 的免费「字体生成器」,让用户输入文字、套用风格、复制粘贴进 Instagram 简介。折腾几天后他发现自己完全想错了:当你在别处粘贴粗体字时,传送的不是样式信息,而是「形状像粗体字母的、不同的字符」——那些是 Unicode 数学字母数字符号区(U+1D400 到 U+1D7FF)里的真字符,本为数学家区分同一论文里语义不同的符号而生,社交用户却拿来当花哨简介。所以这工具不是字体工具,而是一张查找表。他用偏移量数学实现后,却被 script/fraktur 等风格的空槽(Unicode 为避开旧编码刻意留的洞)坑了一把,学会了先查例外表再回退到数学。
🔑 核心要点
- 复制粘贴粗体不会传送字体,而是把字母替换成数学字母数字符号区里的真字符——这是查找表而非字体工具,也解释了为何站点几乎不用发 JS
- 用偏移量数学转换很优雅:A 在 U+0041,粗体 A 在 U+1D400,算出起始差即可平移;sans-serif、bold 等整段连续无空槽的风格纯数学就能完美工作
- 该块有刻意留的洞:早年在 Letterlike Symbols 区已存在的老符号(如 ℝ、ℋ)不会被重复编码,脚本/哥特体/双线体等与旧数学记号重叠的风格在字母 B/E/F/H/I/R/Z 处会指向空槽,渲染成空框
- 斜体整段字母只有小写 h 一个洞——因为 ℎ 早已作为普朗克常数符号存在于 U+210E;作者实测 24 个例外分布在四种风格里
- 这些字符在 U+FFFF 之上,JavaScript 里一个可见字符占两个 string slot,必须用 [...text] 而非 text.split(""),否则会把字符拦腰截断
- Unicode 官方第 22 章明说这些符号「不应用于非数学文本的样式」,垃圾邮件发送者正用这招绕过关键词过滤——Fonti 因此会在输出旁附警告
💡 金句
整块功能的难点从来不是语言,而是理解问题——我花一小时写代码,却花了三天弄明白根本没涉及字体。
👍 0
👎 0
← 返回 dev.to 首页