ADR-0024:合并网格中的语义表格续排
问题
GridTable 的长合并格只准备普通文字流。SemanticTable 落入固定组件回退,不能根据每次分配给合并格的实际高度续排。网格缓存并重复表头时,又会把表头中的语义表格识别为重复完整来源。放宽全局 ID 校验会掩盖误插入、缺片和乱序。
决策
核心提供 DocumentLayouter.prepareTable(Table, ComponentContext) 和布局局部、非线程安全的 TableCursor。固定宽度下一次测量,take(height) 接受不超过准备视口的可变非负高度,输出完整行或显式允许的完整文字行片段;空结果不消费来源或输出预算。remainingHeight() 是剩余原文加一次表头和内边距的高度,后续分页仍可能增加重复表头和内边距。原 layoutTableRegions 复用这个游标,顶层拆行与游标共用纯行分配器。
拆行网格的 PreparedCellFlow 为 SemanticTable 创建游标,递归保留 FontScope、StyleScope 和 FlowColumn。外网格的 allowRowSplit(true) 允许分配合并格;内语义表格的 allowRowSplit(true) 独立控制超长语义行。既有表格字段、富文本、图片、来源和最终链接继续走同一语义 IR,不在准备阶段绘制或解析。
新增布局局部 GridSemanticStreams。每个独立准备的语义来源 ID 只注册一次。记录各次游标输出的片段引用、字体和原序号;固定子组件先通过严格的完整流校验。最终只为已准备片段的实际呈现确定完整连续序号。网格表头可以重复其完整缓存序列,正文只能恰好输出一次;片段引用、顺序或配置改变均失败。内部临时序号不逃逸到最终组件结果。原子与拆行两条网格路径使用相同规则。
全局 SemanticSourceRegistry 保持严格校验,不做 ID 去重放行。不同格、不同网格或同一列中的独立重复源仍失败。源预算只计一次,重复表头、输出行、字段和交互按实际呈现计入。最终页码与分栏逻辑区域号分离。
网格行 Builder 增加 .semanticTable(table, cell -> ...) 及无回调重载。跨度与内边距仍由具名格设置表达,表格内容保持独立的语义 Table 模型。
边界
单元格行列、firstLineIndex 和 UTF-16 指向内层语义 Table 原文,不冒充外层网格格坐标。外网格重复的整张表不改变内表自身的行角色;内表头的 repeatedHeader 仍仅表示其自身游标续排。
普通自定义组件和嵌套 GridTable 在格内仍为原子内容,不由此获得任意递归网格拆分。默认合并组整块移动、内表默认整行保持、固定视口单片段、完整行框及平移限制保持。不增加合并语义 Table 模型、DOCX 嵌套、页区语义、流式数据源或逐属性样式级联。
默认单表限额先执行,随后检查全局更小限额。网格内部语义原型和实际呈现分别最多 100,000,另保留原网格工作/区域预算。同步检查取消,不创建后台线程。全部模型和输出仍驻留内存。
许可与兼容
自主组合已有测量与分页算法,没有新增依赖、字体或第三方素材。现有构造器、固定 layout 调用和严格来源契约保持;新增核心游标与网格便利入口。此前明确拒绝的合法网格表头重复和长合并格语义续排成为受支持组合,见API和阶段二十验收。