ADR-0041:目录独立外观与默认派生
- 日期:2026-10-16
- 状态:已实施,阶段三十四本地验收通过
- 范围:组件目录的标题/页码完整排版与标题/条目/页码颜色
背景
TableOfContents 原有一个完整 ParagraphStyle,用于条目。标题字号与行距固定为条目的 1.5 倍;页码复用条目的字号与行距,且固定右对齐。三部分颜色固定为黑色。调用方不能单独调整标题、页码或颜色,无法让目录复用已有的视觉配置。
目录是正文锚点生成的前置显示页。现有布局先以固定 48 pt 页码列计划目录页数,再按最终偏移解析真实页码和链接。独立排版不能让最终页码触发无限重排,也不能提前固化由旧条目样式派生的默认值。
决策
在组件模块新增不可变 ContentsStyle。它保存完整标题样式、完整页码样式和三个独立不透明 sRGB 颜色;只依赖现有 ParagraphStyle 与 RgbColor,不持有字体、资源、后端或文档状态。DEFAULT 没有显式声明,三个颜色为黑色。
Property 的五项是 TITLE_STYLE、PAGE_LABEL_STYLE、TITLE_COLOR、ENTRY_COLOR 和 PAGE_LABEL_COLOR。声明集合不可变;显式设置恰等于默认值时也保留声明。完整值与声明共同参与 equals/hashCode。Builder 的 defaultTitleStyle、defaultPageLabelStyle、defaultTitleColor、defaultEntryColor 和 defaultPageLabelColor 只清除对应声明,并恢复规范默认存值,保留其他覆盖。
ContentsStyle.titleStyle() 和 pageLabelStyle() 使用 Optional 表达覆盖声明。它们未声明时为空,避免把与所属目录条目无关的存储值当作生效样式。TableOfContents.titleStyle() 和 pageLabelStyle() 则返回按当前条目解析的完整值。
TableOfContents 新增第四项 ContentsStyle appearance,保留旧三参数构造。原 style() 的含义仍是条目完整样式。Builder 提供值与同步回调两种 appearance 入口,回调从当前配置的副本编辑,返回前取不可变快照;不保存回调或可变子 Builder。
未声明标题时,严格使用旧五参数 ParagraphStyle 构造:字号/行距乘 1.5、零缩进、LEFT 与 STANDARD 换行。未声明页码时,同样使用旧五参数构造:条目字号/行距、零缩进、RIGHT 与 STANDARD 换行。不能从条目 toBuilder 派生,因为条目的缩进、对齐和严格中文禁则原本不会传播到标题和页码。
toBuilder 保留声明意图,不保存派生后的生效样式。随后修改条目样式会重新派生未声明的标题/页码;显式完整样式保持。defaultX 使对应项恢复按当前条目派生。旧三参数、旧 Builder 和显式 ContentsStyle.DEFAULT 保持完整默认几何、颜色、来源、诊断与交互偏移一致。
兼容范围是旧构造器源调用与未配置外观时的默认行为。TableOfContents 的 record 组件数由三项变为四项,record 解构模式、反射组件信息以及生成的 equals/hashCode/toString 结构随之变化;外观及其声明意图也参与值比较。既有二进制调用方需要重新编译验证,本变更不宣称所有 record 使用方式或二进制兼容性均保持。
两阶段布局
固定页码列 48 pt、层级缩进 14 pt、行后间隔 8 pt 和标题后间隔 12 pt 保持。条目使用原样式,标题使用解析后的完整样式;三种颜色只作用于各自绘制。
目录规划前已知页码样式的固定行距。每项预留高度取条目实际高度、条目行距与页码行距的最大值。共享简单和 OpenType 路径均以 行数 × lineHeight 返回高度,因此不需要用 0 或其他人工数字试排。这样的探测会额外要求实际页码未出现的字形,还可能引入伪缺字诊断。
最终页数确定后布局真实页码。它必须只有一行,且实际高度不超过预留单行高度。超宽、固定行框不足或无法容纳时明确失败;不缩字、不扩大列宽、不裁切、不改变页数,也不引入新的重排循环。较大页码行距在计划阶段就增加行高。
标题、条目和真实页码复用现有显式 FontGroup、共享塑形、缺字策略与诊断。配置不扫描系统字体、不选择字体角色、不合成粗斜体。实际诊断继续归入现有 CONTENTS 上下文;本次不新增目录标题/条目/页码子区。
边界与后果
目录页数仍交由已有最终偏移流程处理,正文 IR、分节显示页号、书签、链接、评论和可编辑字段的解析时点不变。目录仍使用第一节预留后的正文区域及原奇偶页区。外观配置不影响正文、页区、脚注、静态控件或 AcroForm。
本次不增加 DocumentTheme 自动映射、逐属性级联、字体角色、逐层级样式、富文本目录标题或可变页码列。ParagraphFormat 含分页等语义,不能以主题映射无声丢弃。DOCX 直接映射语义模型,本配置不意味着原生 Word TOC 支持;SVG/Raster 对目录链接的拒绝边界保持。
实现只新增一个值类型并调整两处现有目录组件,不引入模块或依赖。外观首批关闭目录的真实硬编码缺口,页区默认入口与完整主题支持继续单独评估,不把本单元标记为整个主题能力完成。
验证要求
- 验证显式默认、五项独立恢复、空值拒绝、不可变集合与同步回调快照;验证改条目样式时未声明项重派生、显式项保持。
- 精确比较旧默认完整绘制列表、目录 traces、正文 IR、页数、锚点、链接、诊断与几何,不更新视觉基线。
- 验证独立字号/颜色、较大页码行距、软换行条目、多页目录、容量/预算失败,以及缺字和复杂文字的共享路径;真实页码只要求其实际字形。
- 验证跨节页号、总页数、目录偏移、原页区与交互目标;取消必须恢复原执行上下文。
- 仓库样例和隔离 Maven 调用方各生成一页目录及一页正文,最多新增四页。独立核对文字、PDF 绘制颜色/字号、跳转坐标并全页渲染;逐页复查。
本记录声明已实施的契约与验收门槛,集成及独立输出结果以阶段三十四验收记录为准。