谷歌浏览器中出现部分字体乱码问题

项目中使用的字体:

css 复制代码
@font-face { 
    font-family: 'simsun3'; /**宋体常规**/;
    src: url('./SimSun-Regular.ttf); 
    font-weight: normal; 
    font-style: normal; 
}

hiprint标签使用该字体,预览效果乱码:

页面缩放后有些乱码的文本恢复正常,而部分正常的文本出现乱码。

Chrome @font‑face SimSun‑Regular.ttf 缩放乱码(hiprint 打印场景)

现象:缩放(浏览器缩放 /transform scale)时,一部分文字乱码方块,一部分正常;缩放比例一变,乱码位置发生切换。

这是 Chrome Skia 渲染引擎 + TTF 宋体 hinting 提示信息 + GPU 合成层 的经典 bug,尤其 hiprint 大量使用 transform:scale 做打印缩放时极易复现。

修复后的 @font‑face(优先复制使用)

css 复制代码
@font-face {
  font-family: 'simsun3';
  src: url('./SimSun-Regular.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
  unicode-range: U+4E00-9FFF, U+3000-303F, U+FF00-FFEF; /* 中文、中文标点、全角符号 */
}

根因

  1. 原始宋体 ttf hinting(字形微调)对小数缩放极不友好:当 transform scale / 浏览器页面缩放产生非整数设备像素,SimSun 的 hinting 会部分字形解析错乱,缩放一变,乱码文字就切换。
  2. hiprint 内部大量使用 transform: scale(),元素进入 GPU 合成图层,文本光栅化为位图再缩放,进一步放大该缺陷。
  3. 只用 ttf,没有 woff2;缺少font-display会加剧字体加载时序异常。
  4. OSS 跨域:确认oss.shuixing.cn返回字体资源携带 CORS 头 Access‑Control‑Allow‑Origin,Chrome 跨域 webfont 校验严格,CORS 缺失会随机渲染异常。

分步骤解决方案(按优先级从上到下)

方案 1:把 TTF 转成 WOFF2(最有效,强烈建议)

TTF 用于网页打印渲染缺陷多,转 woff2,去除 / 弱化 hinting,绝大多数缩放乱码直接消失。

  • 工具:Font Squirrel Webfont Generator,上传 SimSun‑Regular.ttf,勾选:

    • 输出格式:WOFF2 + WOFF
    • Disable Hinting(关闭 hinting) 关键!宋体 hinting 是祸源 上传转换后,把 woff2 放到 oss,修改 css:
css 复制代码
@font-face {
  font-family: 'simsun3';
  src: url('./SimSun‑Regular.woff2') format('woff2'),
       url('./SimSun‑Regular.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
  unicode-range: U+4E00‑9FFF, U+3000‑303F, U+FF00‑FFEF;
}

方案 2:CSS 渲染属性缓解(不替代 woff2,作为辅助)

打印模板外层容器加上,抑制亚像素渲染 bug:

css 复制代码
.print-template {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: geometricPrecision;
}

text‑rendering:geometricPrecision 会关闭 hinting,牺牲一点小字锐利,消除缩放抖动乱码。

方案 3:hiprint 业务层特殊处理(如果你使用 hiprint)

  1. 等待字体完全加载完成后再初始化打印模板,不要 DOM 渲染完立刻渲染打印:
js 复制代码
// 等待全部web字体就绪
document.fonts.ready.then(()=>{
  // 在这里执行hiprint初始化、渲染模板
})
  1. hiprint 预览用 scale 缩放会触发 bug;导出 PDF / 打印时尽量避免依靠 transform scale 做缩放,优先调整元素真实 font‑size、宽高,而不是 scale。

方案 4:服务端 OSS 检查(必查)

打开 network 面板,看 ttf/woff2 请求响应头:

  1. 必须存在 Access‑Control‑Allow‑Origin,允许你的页面域名;
  2. Content‑Type 应为 font/ttf / font/woff2,不要返回 application/octet‑stream

CORS 不通过会出现随机字体渲染异常,时好时坏,缩放后变化。

排查定位手段

  1. 关闭 Chrome 硬件加速,重启浏览器复现:设置‑系统‑关闭【使用硬件加速模式】。如果乱码消失,确认是 GPU 合成层渲染 bug。
  2. 测试:把 transform scale 去掉,直接修改真实 font‑size,看乱码是否消失。消失则确认是 scale+hinting 组合问题。
  3. 控制台看是否有 OTS parsing errorFailed to decode downloaded font,代表字体文件损坏或者 CORS 拦截。

降级兜底

font-family 务必带上系统宋体兜底,字体栈示例:

css 复制代码
font-family: 'simsun3', SimSun, serif;

总结建议

  1. 优先把 SimSun‑Regular.ttf 转换为关闭 hinting 的 woff2 格式上传 OSS,这是根治方案
  2. 加上font-display:swapunicode‑range
  3. OSS 配置字体 CORS 跨域头。
  4. hiprint 务必等待document.fonts.ready再渲染打印模板。
  5. 尽量少用transform:scale缩放打印内容,优先修改真实尺寸。

如果你需要,我可以给你一份可直接复制的完整 hiprint 打印页面最小 demo

相关推荐
+VX:Fegn08957 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·课程设计
Nicander9 小时前
我给 Excalidraw 做了一个本地工作区:DrawSpace
前端·开源
linux_cfan10 小时前
17 · 引擎适配器全景:HLS/DASH/Vimeo/Mux/Cast
前端·javascript·音视频
计算机魔术师11 小时前
烧掉2780亿美元还不够?OpenAI的资本豪赌让人头皮发麻
前端
IT_陈寒12 小时前
Java线程池用错参数,我的服务居然悄悄崩溃了
前端·人工智能·后端
卡布鲁12 小时前
React useMemo 与 useCallback 完全指南:原理、场景与避坑
前端·react.js
碳基修炼12 小时前
排查记:本地 devServer 是 http,浏览器却把 302 重定向升级成了 https
前端·http
步行cgn12 小时前
Spring p 命名空间注入详解
java·前端·spring
何何____12 小时前
Vue 生命周期详解
前端·javascript
江米小枣tonylua13 小时前
TypeScript 全面の拥抱 !Prisma 8 + Electron 升级实战
前端