# 作用域系统 字体作用域系统实现了文档和模板库之间的字体隔离和跨域引用控制。 ## 作用域定义 系统定义了两个字体作用域: ### 文档作用域(document) - 包含文档的 `metadata.fonts` 中定义的字体 - 文档的 `fonts_default` 只能引用文档作用域的字体 - 文档元素可以引用文档作用域和模板库作用域的字体 ### 模板库作用域(template) - 包含模板库的 `metadata.fonts` 中定义的字体 - 模板库的 `fonts_default` 只能引用模板库作用域的字体 - 模板元素只能引用模板库作用域的字体(不能引用文档字体) ## 跨域引用规则 ### 允许的引用 - 文档元素 → 文档字体 - 文档元素 → 模板库字体(跨域引用) - 模板元素 → 模板库字体 - 文档 fonts_default → 文档字体 - 模板库 fonts_default → 模板库字体 ### 禁止的引用 - 模板元素 → 文档字体(跨域引用被禁止) - 模板库 fonts_default → 文档字体(跨域引用被禁止) - 文档 fonts_default → 模板库字体(跨域引用被禁止) ### 设计理由 - 模板库应该是自包含的,不依赖特定文档的字体配置 - 文档可以引用模板库字体,实现样式复用 - 防止模板库与文档之间的紧耦合 ## FontResolver 实现 ### 初始化 ```python class FontResolver: def __init__(self, fonts, fonts_default, scope="document", template_fonts=None): """ Args: scope: 作用域标识 ("document" 或 "template") template_fonts: 模板库字体字典(仅文档作用域需要) """ ``` ### 跨域引用检测 - 使用作用域标签(`doc.@font-name` 或 `template.@font-name`)追踪引用路径 - 检测跨域循环引用(如 `doc.@a → template.@b → doc.@a`) - 在 `parent` 引用时根据作用域限制跨域访问 ## fonts_default 级联规则 当元素未指定字体时,按以下顺序查找默认字体: ### 模板元素 1. 模板库的 `fonts_default`(如果存在) 2. 文档的 `fonts_default`(如果存在) 3. 系统默认字体 ### 文档元素 1. 文档的 `fonts_default`(如果存在) 2. 系统默认字体 ## 循环引用检测 ### 单域内循环 ```yaml fonts: a: parent: "@b" b: parent: "@a" ``` 错误信息:`检测到字体引用循环: doc.@a -> doc.@b -> doc.@a` ### 跨域循环 ```yaml # 文档 fonts: doc-font: parent: "@template-font" # 模板库 fonts: template-font: parent: "@doc-font" # 这会被禁止 ``` 错误信息:`检测到跨域字体引用循环: doc.@doc-font -> template.@template-font -> doc.@doc-font` ## 错误代码 ### 模板库 metadata 相关 - `TEMPLATE_LIBRARY_MISSING_METADATA` - 模板库缺少 metadata 字段 - `TEMPLATE_LIBRARY_METADATA_MISSING_SIZE` - 模板库 metadata 缺少 size 字段 - `TEMPLATE_LIBRARY_METADATA_INVALID_SIZE` - 模板库 metadata.size 值无效 ### Size 一致性 - `SIZE_MISMATCH` - 文档和模板库的 size 不一致 ### 字体引用相关 - `TEMPLATE_FONT_REF_DOC_FORBIDDEN` - 模板元素引用文档字体 - `TEMPLATE_PARENT_REF_DOC_FORBIDDEN` - 模板库字体的 parent 引用文档字体 - `FONT_NOT_FOUND` - 字体配置不存在 - `CIRCULAR_REFERENCE` - 检测到字体引用循环 - `FONT_DEFAULT_INVALID` - fonts_default 引用无效 ## 使用示例 ### 正确的跨域引用 ```yaml # templates.yaml(模板库) metadata: size: "16:9" fonts: template-title: family: "cjk-sans" size: 44 bold: true # presentation.yaml(文档) metadata: size: "16:9" slides: - elements: - type: text content: "正文" font: "@template-title" # 文档元素可以引用模板库字体 ``` ### 错误的跨域引用 ```yaml # templates.yaml(模板库) metadata: size: "16:9" fonts_default: "@doc-body" # 模板库 fonts_default 不能引用文档字体 templates: title-slide: elements: - type: text content: "{title}" font: "@doc-body" # 模板元素不能引用文档字体 ``` ## 相关文档 - [字体系统实现](font-system.md) - FontResolver 实现 - [字体主题系统](../../fonts.md) - 用户指南 [返回开发文档索引](../README.md)