实现完整的字体主题系统,支持可复用字体配置、预设类别和扩展属性。 同时修复中文字体渲染问题,确保 Source Han Sans 等东亚字体正确显示。 核心功能: - 字体主题配置:metadata.fonts 和 fonts_default - 三种引用方式:整体引用、继承覆盖、独立定义 - 预设字体类别:sans、serif、mono、cjk-sans、cjk-serif - 扩展字体属性:family、underline、strikethrough、line_spacing、 space_before、space_after、baseline、caps - 表格字体字段:font 和 header_font 替代旧的 style.font_size - 引用循环检测和属性继承链 - 模板字体继承支持 东亚字体修复: - 添加 _set_font_with_eastasian() 方法 - 同时设置拉丁字体、东亚字体和复杂脚本字体 - 修复中文字符使用默认字体的问题 测试: - 58 个单元测试覆盖所有字体系统功能 - 3 个集成测试验证端到端场景 - 移除旧语法相关测试 文档: - 更新 README.md 添加字体主题系统使用说明 - 更新 README_DEV.md 添加技术文档 - 创建 4 个示例 YAML 文件 - 同步 delta specs 到主 specs 归档: - 归档 font-theme-system 变更到 openspec/changes/archive/ Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
3.8 KiB
3.8 KiB
Font Preset
Purpose
预设字体类别提供系统内置的字体类别名称,用户可以直接使用这些类别名称引用推荐的字体,无需指定具体字体名称。系统将预设类别映射到跨平台通用的推荐字体。
Requirements
Requirement: 系统必须支持五种预设字体类别
系统 SHALL 支持以下预设字体类别:sans、serif、mono、cjk-sans、cjk-serif。
Scenario: 使用 sans 类别
- WHEN 元素定义 font: {family: "sans"}
- THEN 系统使用 "Arial" 作为字体族
Scenario: 使用 serif 类别
- WHEN 元素定义 font: {family: "serif"}
- THEN 系统使用 "Times New Roman" 作为字体族
Scenario: 使用 mono 类别
- WHEN 元素定义 font: {family: "mono"}
- THEN 系统使用 "Courier New" 作为字体族
Scenario: 使用 cjk-sans 类别
- WHEN 元素定义 font: {family: "cjk-sans"}
- THEN 系统使用 "Microsoft YaHei" 作为字体族
Scenario: 使用 cjk-serif 类别
- WHEN 元素定义 font: {family: "cjk-serif"}
- THEN 系统使用 "SimSun" 作为字体族
Requirement: 预设类别映射必须使用跨平台通用字体
预设字体类别 SHALL 映射到跨平台通用性最高的字体,确保在不同操作系统上都有较好的显示效果。
Scenario: sans 类别映射到 Arial
- WHEN 系统解析 family: "sans"
- THEN 映射到 "Arial"(Windows/macOS/Linux 通用)
Scenario: serif 类别映射到 Times New Roman
- WHEN 系统解析 family: "serif"
- THEN 映射到 "Times New Roman"(Windows/macOS/Linux 通用)
Scenario: mono 类别映射到 Courier New
- WHEN 系统解析 family: "mono"
- THEN 映射到 "Courier New"(Windows/macOS/Linux 通用)
Scenario: cjk-sans 类别映射到微软雅黑
- WHEN 系统解析 family: "cjk-sans"
- THEN 映射到 "Microsoft YaHei"(Windows 常用中文字体)
Scenario: cjk-serif 类别映射到宋体
- WHEN 系统解析 family: "cjk-serif"
- THEN 映射到 "SimSun"(Windows 常用中文字体)
Requirement: 预设类别必须在 family 字段中识别
系统 SHALL 仅在 font 或 header_font 的 family 字段中识别预设类别名称。
Scenario: family 字段使用预设类别
- WHEN 元素定义 font: {family: "sans"}
- THEN 系统识别 "sans" 为预设类别,映射到 "Arial"
Scenario: 其他字段不解析预设类别
- WHEN 元素定义 font: {size: "sans"}
- THEN 系统将 "sans" 作为字符串值,不进行预设类别映射
Scenario: 直接使用字体名称
- WHEN 元素定义 font: {family: "SimSun"}
- THEN 系统使用 "SimSun" 作为字体族,不进行预设类别映射
Requirement: 预设类别不进行字体验证
系统 SHALL 不验证预设类别映射的字体是否在系统中存在。
Scenario: 预设类别字体不存在时行为
- WHEN 系统中不存在 Arial 字体
- THEN 系统仍将 "sans" 映射到 "Arial",不报错
Scenario: PowerPoint 处理字体回退
- WHEN PowerPoint 打开包含不存在字体的 PPTX 文件
- THEN PowerPoint 自动回退到系统默认字体
Requirement: 预设类别可以与 fonts 配置结合使用
用户可以在 fonts 配置中使用预设类别,也可以在元素 font 中直接使用。
Scenario: fonts 配置中使用预设类别
- WHEN metadata 定义 fonts: {body: {family: "sans", size: 18}}
- THEN 系统将 family: "sans" 解析为 "Arial"
Scenario: 元素直接使用预设类别
- WHEN 元素定义 font: {family: "cjk-sans", size: 24}
- THEN 系统将 family: "cjk-sans" 解析为 "Microsoft YaHei"
Scenario: 预设类别与引用结合
- WHEN fonts.title 定义 family: "sans",元素定义 font: "@title"
- THEN 元素使用 family: "Arial"(通过 title 配置)