实现完整的字体主题系统,支持可复用字体配置、预设类别和扩展属性。 同时修复中文字体渲染问题,确保 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>
6.5 KiB
6.5 KiB
Font Extended
Purpose
扩展字体属性在现有 size、bold、italic、color、align 基础上,新增 family、underline、strikethrough、line_spacing、space_before、space_after、baseline、caps 等属性,提供更完整的字体样式控制能力。
ADDED Requirements
Requirement: 元素 font 必须支持 family 属性
font 字段 SHALL 支持 family 属性,用于指定字体族名称。
Scenario: 设置字体族
- WHEN 元素定义 font: {family: "Arial"}
- THEN 系统将字体族设置为 Arial
Scenario: family 字段为 None
- WHEN 元素定义 font: {size: 18}(未定义 family)
- THEN 系统使用继承或默认的字体族
Requirement: 元素 font 必须支持 underline 属性
font 字段 SHALL 支持 underline 属性,控制文本是否带下划线。
Scenario: 启用下划线
- WHEN 元素定义 font: {underline: true}
- THEN 系统为文本添加下划线
Scenario: 禁用下划线
- WHEN 元素定义 font: {underline: false}
- THEN 系统不为文本添加下划线
Scenario: underline 未定义
- WHEN 元素定义 font: {size: 18}(未定义 underline)
- THEN 系统使用继承或默认的下划线设置
Requirement: 元素 font 必须支持 strikethrough 属性
font 字段 SHALL 支持 strikethrough 属性,控制文本是否带删除线。
Scenario: 启用删除线
- WHEN 元素定义 font: {strikethrough: true}
- THEN 系统为文本添加删除线
Scenario: 禁用删除线
- WHEN 元素定义 font: {strikethrough: false}
- THEN 系统不为文本添加删除线
Scenario: strikethrough 未定义
- WHEN 元素定义 font: {size: 18}(未定义 strikethrough)
- THEN 系统使用继承或默认的删除线设置
Requirement: 元素 font 必须支持 line_spacing 属性
font 字段 SHALL 支持 line_spacing 属性,控制行距倍数。
Scenario: 设置行距倍数
- WHEN 元素定义 font: {line_spacing: 1.5}
- THEN 系统将行距设置为 1.5 倍
Scenario: line_spacing 为 1.0
- WHEN 元素定义 font: {line_spacing: 1.0}
- THEN 系统使用单倍行距
Scenario: line_spacing 未定义
- WHEN 元素定义 font: {size: 18}(未定义 line_spacing)
- THEN 系统使用继承或默认的行距设置
Requirement: 元素 font 必须支持 space_before 属性
font 字段 SHALL 支持 space_before 属性,控制段前间距(单位:磅)。
Scenario: 设置段前间距
- WHEN 元素定义 font: {space_before: 12}
- THEN 系统将段前间距设置为 12 磅
Scenario: space_before 为 0
- WHEN 元素定义 font: {space_before: 0}
- THEN 系统不添加段前间距
Scenario: space_before 未定义
- WHEN 元素定义 font: {size: 18}(未定义 space_before)
- THEN 系统使用继承或默认的段前间距
Requirement: 元素 font 必须支持 space_after 属性
font 字段 SHALL 支持 space_after 属性,控制段后间距(单位:磅)。
Scenario: 设置段后间距
- WHEN 元素定义 font: {space_after: 12}
- THEN 系统将段后间距设置为 12 磅
Scenario: space_after 为 0
- WHEN 元素定义 font: {space_after: 0}
- THEN 系统不添加段后间距
Scenario: space_after 未定义
- WHEN 元素定义 font: {size: 18}(未定义 space_after)
- THEN 系统使用继承或默认的段后间距
Requirement: 元素 font 必须支持 baseline 属性
font 字段 SHALL 支持 baseline 属性,控制文本基线位置(normal、superscript、subscript)。
Scenario: 设置为上标
- WHEN 元素定义 font: {baseline: "superscript"}
- THEN 系统将文本设置为上标
Scenario: 设置为下标
- WHEN 元素定义 font: {baseline: "subscript"}
- THEN 系统将文本设置为下标
Scenario: 设置为正常基线
- WHEN 元素定义 font: {baseline: "normal"}
- THEN 系统使用正常基线位置
Scenario: baseline 未定义
- WHEN 元素定义 font: {size: 18}(未定义 baseline)
- THEN 系统使用正常基线位置
Scenario: baseline 值无效
- WHEN 元素定义 font: {baseline: "invalid"}
- THEN 系统抛出 ERROR,提示 baseline 必须是 normal、superscript 或 subscript
Requirement: 元素 font 必须支持 caps 属性
font 字段 SHALL 支持 caps 属性,控制文本大小写转换(normal、allcaps、smallcaps)。
Scenario: 设置为全大写
- WHEN 元素定义 font: {caps: "allcaps"}
- THEN 系统将文本转换为大写
Scenario: 设置为小型大写
- WHEN 元素定义 font: {caps: "smallcaps"}
- THEN 系统将文本转换为小型大写字母
Scenario: 设置为正常大小写
- WHEN 元素定义 font: {caps: "normal"}
- THEN 系统保持文本原始大小写
Scenario: caps 未定义
- WHEN 元素定义 font: {size: 18}(未定义 caps)
- THEN 系统保持文本原始大小写
Scenario: caps 值无效
- WHEN 元素定义 font: {caps: "invalid"}
- THEN 系统抛出 ERROR,提示 caps 必须是 normal、allcaps 或 smallcaps
Requirement: 多行文本必须将所有属性应用到每个段落
当文本内容包含换行符时,系统 SHALL 将所有字体属性(包括扩展属性)应用到文本框中的每个段落。
Scenario: 多行文本应用扩展属性
- WHEN 文本内容包含换行符且定义 font: {size: 12, underline: true, line_spacing: 1.5}
- THEN 系统将所有属性(size、underline、line_spacing)应用到所有段落
Scenario: 多行文本每个段落样式一致
- WHEN 文本包含多个换行符且定义了 font 属性
- THEN 每个段落的字体样式都应一致
Requirement: 扩展属性必须支持继承机制
扩展属性 SHALL 遵循与基础属性相同的继承机制:parent → 当前定义 → fonts_default → 系统默认。
Scenario: 扩展属性从 parent 继承
- WHEN parent 定义 underline: true,当前定义未指定 underline
- THEN 元素使用 underline: true(从 parent 继承)
Scenario: 扩展属性从 fonts_default 继承
- WHEN fonts_default 定义 line_spacing: 1.5,元素未指定 line_spacing
- THEN 元素使用 line_spacing: 1.5(从 fonts_default 继承)
Scenario: 当前定义覆盖继承的扩展属性
- WHEN parent 定义 space_before: 12,当前定义 space_before: 24
- THEN 元素使用 space_before: 24(当前定义覆盖)