【office2pdf】PPTX 字体解析与文本样式继承(PPTX_FONT_RESOLUTION.md)

摘要

本文档记录了 PPTX 保真度问题,该问题最初看起来像是布局错误,

但实际上是由不完整的字体和文本样式解析引起的。

可见的症状是多个幻灯片上的文本块,尤其是幻灯片 4 的"SKILLS"区域,

与 PowerPoint 不匹配:

  • 窄标签换行方式不同
  • 标题徽章的大小和粗细不同
  • 即使文本框坐标正确,某些文本在视觉上也会发生偏移

根本原因不是硬编码的幻灯片几何形状。真正的问题是
office2pdf 没有像 PowerPoint 那样解析 PPTX 文本样式。

问题

PowerPoint 文本格式不仅仅由直接的 run 属性决定。

对于文本框,有效的样式可能来自多个 OOXML 层级:

  1. a:rPr 中的直接 run 属性
  2. a:pPr 中的段落属性
  3. a:lstStyle 中的文本主体默认值
  4. a:defPPr 中的默认段落属性
  5. a:lvlNpPr 中特定级别的段落属性
  6. a:defRPr 中的默认 run 属性
  7. 主题字体引用,如 +mj-lt / +mn-lt

在修复之前,PPTX 解析器主要使用直接的 a:rPr 和 run 上直接的
a:latin 值。这是不完整的。

结果如下:

  • 缺少直接字体设置的 run 丢失了继承的字体族、大小、颜色和粗细
  • 使用 lstStyle 默认值的文本框渲染的样式比 PowerPoint 弱
  • 由于有效的字体度量错误,换行出现差异

在回退选择方面还存在第二个问题:

  • 回退顺序过于激进地优先考虑"字体源排名"
  • 这导致 Office 管理的字体(如 Malgun Gothic)的优先级高于
    Pretendard 的度量首选替代列表
  • 在这台机器上,这比使用 Apple SD Gothic Neo 产生的换行效果更差

为什么 PowerPoint 看起来正确

受影响的演示文稿不仅仅依赖主题字体。它在幻灯片 XML 中包含显式的

字体信息,如 Pretendard、Pretendard SemiBold 及相关变体。

PowerPoint 应用:

  • 直接的 run 格式
  • 继承的 lstStyle 默认值
  • 跨 latin、ea 和 cs 的脚本感知字体解析
  • 当确切字体不可用时的本地回退行为

office2pdf 缺少了部分继承链,因此生成的 PDF 出现了差异,

尽管原始 PPTX 在 PowerPoint 中渲染正确。

修复方案

1. 解析文本主体样式继承

在 PPTX 解析器中添加了文本主体默认模型,使文本框能够从
a:lstStyle 继承样式。

实现:

  • 引入 PptxTextBodyStyleDefaults
  • 引入 PptxTextLevelStyle
  • 解析 a:lstStyle、a:defPPr、a:lvlNpPr 和嵌套的 a:defRPr
  • 在应用直接的段落/run 覆盖之前,合并继承的段落和 run 样式
  • 从 a:latin、a:ea 和 a:cs 应用字体,而不仅仅是直接的 a:latin

这使得文本框的行为更接近 PowerPoint 的有效样式模型。

2. 保留度量回退顺序

对于 Pretendard 等已知字体族的回退选择,现在优先保留替换表中

与度量兼容的顺序,仅将源排名用作次要的判定因素。

这意味着:

  • 首选的替代字体族顺序是稳定的
  • Office 管理的字体不再仅仅因为是从 Office 路径发现而自动优先于
    更好的度量匹配项
  • 实际的演示文稿现在回退到 Apple SD Gothic Neo 而不是 Malgun Gothic

涉及的文件

  • crates/office2pdf/src/parser/pptx.rs
  • crates/office2pdf/src/render/font_subst.rs
  • crates/office2pdf/src/render/typst_gen.rs

验证

修复通过三种方式进行了验证:

  1. 对 lstStyle 默认 run 继承进行单元测试
  2. 在 Office/系统字体混合环境下对回退顺序进行单元测试
  3. 重新转换实际的 PPTX 演示文稿并进行手动视觉检查

修复后的观察结果:

  • 幻灯片 4 的"SKILLS"标签不再像之前那样换行
  • 徽章/标题样式更接近 PowerPoint
  • 重新生成的 PDF 为 Pretendard 回退嵌入了 Apple SD Gothic Neo 变体,
    而不是 Malgun Gothic

剩余已知差距与文本继承无关:

  • 幻灯片 17 仍然会警告不支持的 hdphoto1.wdp

关键经验

当 PPTX 渲染不匹配看起来像文本框位置问题时,不要首先假设坐标错误。

在 PowerPoint 中,不正确的字体解析通常会变成布局问题:

  • 不同的字体族
  • 不同的粗细
  • 不同的继承大小
  • 不同的行距

即使文本框几何形状正确,这些差异也会改变换行和视觉对齐。

相关推荐
niyongsheng4 小时前
多智能体连续时间内路径规划:AA-SIPP(m) 的 Rust 实现与算法
算法·rust·机器人
NetX行者8 小时前
Rust 初体验:一个全栈工程师的编译器“毒打“笔记
开发语言·笔记·rust
Amos_Web11 小时前
Rspack 源码解析(二十七):AsyncWasmParserAndGenerator 如何把二进制变成异步模块
前端·rust
敲代码的玉米C11 小时前
菜单栏做出来了,内存预算却没过:Hostwatch 开发手记(二)
rust
敲代码的玉米C11 小时前
电脑卡了,然后呢?我想用 Rust 做一个 Mac 诊断小工具
rust
GeminiJM13 小时前
从 0 到 1 学 Codex 源码:Rust 基础(一)
rust·源码阅读·cargo·编程入门·codex
恋喵大鲤鱼14 小时前
Rust 依赖包管理
rust
znnnk15 小时前
2026 前端工程化新纪元:Rust 重塑工具链,AI Agent 接管流水线
前端·人工智能·rust
gopher95112 天前
RUST:序列化与反序列化 serde + derive 详解
开发语言·后端·rust
遇码2 天前
流式调用中途断连别直接报错:瞬态故障识别、退避重试与中文根因诊断的搭建方法
大数据·人工智能·ai·rust·数据分析·大模型·agent