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

3.5 KiB
Raw Blame History

字体系统实现

字体解析和继承链处理的实现。

职责

  • 字体引用解析
  • 继承链处理
  • 预设类别映射
  • 循环引用检测

PRESET_FONT_MAPPING

预设字体类别映射常量:

PRESET_FONT_MAPPING = {
    'sans': 'Arial',
    'serif': 'Times New Roman',
    'mono': 'Courier New',
    'cjk-sans': 'Microsoft YaHei',
    'cjk-serif': 'SimSun',
}

FontResolver 类

初始化

class FontResolver:
    def __init__(self, fonts, fonts_default, scope="document", template_fonts=None):
        """
        Args:
            fonts: 当前作用域的字体字典
            fonts_default: 当前作用域的默认字体
            scope: 作用域标识 ("document" 或 "template")
            template_fonts: 模板库字体字典(仅文档作用域需要)
        """

resolve_font()

解析字体配置的主入口:

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()

解析字体引用:

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()

解析字体字典:

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 字段中识别预设类别名称:

if family in PRESET_FONT_MAPPING:
    family = PRESET_FONT_MAPPING[family]

相关文档

返回开发文档索引