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

项目中使用的字体:

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

相关推荐
To_OC3 小时前
绕开层层 props 搬运:我把 useContext 和自定义 Hook 跑通了
前端·react.js·前端框架
北凉温华3 小时前
Vue3 可视化打印设计插件|拖拽生成票据/标签打印模板(开源体验版)
前端
程序员黑豆3 小时前
Java变量详解:从入门到精通
java·前端·ai编程
andr_gale4 小时前
02_uniapp自定义上凸效果的底部TabBar
前端·javascript·uni-app·移动端
一心只读圣贤书4 小时前
AI 驱动前端测试实战:从需求文档到 Playwright 自动化用例
前端·人工智能
拖孩4 小时前
用 AI 重解千年观音灵签,做了一个微信小程序,每天摇一摇,命运给你回应
前端·后端·微信小程序
難釋懷4 小时前
Nginx日志
前端·网络·nginx
Web极客码5 小时前
用 Python 搭建工具调用 Agent 的调试过程
java·服务器·前端
2401_881828325 小时前
简易文本处理网页工具|AI 通识课第三次作业
前端·javascript·html