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

项目中使用的字体:

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 error、Failed to decode downloaded font,代表字体文件损坏或者 CORS 拦截。

降级兜底

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

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

总结建议

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

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

相关推荐
IT_陈寒10 分钟前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
Acro25 分钟前
快给macOS 上的Grok Bot换一套皮肤
前端
flash俊杰27 分钟前
双引擎 OCR 编排:逐页判定、视觉优先、partial 语义与三层超时
前端
计算机魔术师27 分钟前
Reddit 每周被 Google 偷走 100 万次点击,CEO 摊牌了
前端
前端繁华如梦29 分钟前
用 React Three Fiber 做一栋能编辑的教学楼数字孪生
前端
前端繁华如梦34 分钟前
用 React Three Fiber 做一套智慧医院数字孪生:编辑器、大屏和 BIM 浏览器
前端
俊昭喜喜里2 小时前
理解全局跨域CORS配置
前端
锋行天下5 小时前
DeepSeek写Langgraph就是个大傻逼,一本正经胡说八道
前端·人工智能·后端
jktantan5 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
计算机魔术师5 小时前
Anthropic官方插件被「寄生」,背后是同一类攻击又来了
前端