1
0
Files
PPTX/docs/development/font-system.md
lanyuanxiaoyao 124ef0e5ce refactor: 重构文档结构,采用渐进式信息披露模式
将 README.md 拆分为多个专题文档,减少认知负荷:
- 用户文档迁移到 docs/ (用户指南、元素、模板、参考等)
- 开发文档迁移到 docs/development/ (架构、模块、规范)
- README.md 精简至 ~290 行,仅保留概览和导航
- 删除 README_DEV.md,内容已迁移
- 归档 OpenSpec 变更 refactor-docs-progressive-disclosure
2026-03-06 15:11:36 +08:00

145 lines
3.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 字体系统实现
字体解析和继承链处理的实现。
## 职责
- 字体引用解析
- 继承链处理
- 预设类别映射
- 循环引用检测
## PRESET_FONT_MAPPING
预设字体类别映射常量:
```python
PRESET_FONT_MAPPING = {
'sans': 'Arial',
'serif': 'Times New Roman',
'mono': 'Courier New',
'cjk-sans': 'Microsoft YaHei',
'cjk-serif': 'SimSun',
}
```
## FontResolver 类
### 初始化
```python
class FontResolver:
def __init__(self, fonts, fonts_default, scope="document", template_fonts=None):
"""
Args:
fonts: 当前作用域的字体字典
fonts_default: 当前作用域的默认字体
scope: 作用域标识 ("document""template")
template_fonts: 模板库字体字典(仅文档作用域需要)
"""
```
### resolve_font()
解析字体配置的主入口:
```python
def resolve_font(self, font_config):
"""解析字体配置(主入口)"""
if font_config is None:
return self._get_default_config(set())
if isinstance(font_config, str):
# "@xxx" 格式
return self._resolve_reference(font_config.strip('@'), set())
if isinstance(font_config, dict):
if 'parent' in font_config:
# {parent: "@xxx", ...} 格式
return self._resolve_font_dict(font_config, set())
else:
# 独立定义
return FontConfig(**font_config)
```
### _resolve_reference()
解析字体引用:
```python
def _resolve_reference(self, reference, visited):
"""解析字体引用"""
if reference in visited:
raise ValueError(f"检测到字体引用循环: {' -> '.join(visited + [reference])}")
visited.add(reference)
# 检查作用域
if reference in self.fonts:
font_data = self.fonts[reference]
elif self.template_fonts and reference in self.template_fonts:
font_data = self.template_fonts[reference]
else:
raise ValueError(f"字体配置不存在: @{reference}")
return self._build_font_config(font_data, visited)
```
### _resolve_font_dict()
解析字体字典:
```python
def _resolve_font_dict(self, font_dict, visited):
"""解析字体字典"""
parent_ref = font_dict.get('parent', '').strip('@')
if parent_ref:
# 先解析父级
parent_config = self._resolve_reference(parent_ref, visited.copy())
# 合并当前属性
return self._merge_with_parent(font_dict, parent_config)
# 独立定义
return FontConfig(**font_dict)
```
## 字体引用解析逻辑
1. 如果 `font_config` 为 None使用 `fonts_default`
2. 如果是字符串(`"@xxx"`),解析为整体引用
3. 如果是字典且包含 `parent`,先解析 `parent` 再覆盖当前属性
4. 如果是字典且不包含 `parent`,直接使用字典属性
5. 未定义的属性从 `fonts_default` 继承
6. 如果 `family` 是预设类别,映射到具体字体名称
7. 返回完整的 `FontConfig` 对象
## 继承链
属性继承顺序:
```
parent → 当前属性 → fonts_default → 系统默认
```
## 循环引用检测
- 维护已访问集合 `visited`
- 检测重复引用
- 最大引用深度限制10 层
## 预设类别映射
`family` 字段中识别预设类别名称:
```python
if family in PRESET_FONT_MAPPING:
family = PRESET_FONT_MAPPING[family]
```
## 相关文档
- [作用域系统](scope-system.md) - 字体作用域规则
- [字体主题系统](../../fonts.md) - 用户指南
[返回开发文档索引](../README.md)