ReadViewSDK/Doc/WXRead剩余问题修复计划.md

8.9 KiB
Raw Blame History

WXRead 剩余问题修复计划

基于 架构对比分析_WXRead_vs_ReadViewSDK.md 的 2026-05-24 核查结果整理。 目标:把当前已完成的 CoreText 页面直绘继续收口到更接近 WXRead 的页面级排版、命中、装饰和位置模型。


目标概览

当前已经完成的部分:

  • 文本页已经切到页面级 CoreText 直绘。
  • 分页器已经切到 RDEPUBTextLayouter + rd_paginatedFrames
  • 4 级语义断页、avoidPageBreakInside、分页缓存、5 层 CSS、<link> 外部 CSS 内联都已经落地。

当前仍需修复的核心问题:

  1. 选区与命中仍依赖 UITextView 代理层,没有完全走 CoreText 页面几何。
  2. 高亮、下划线、搜索命中仍主要靠 attributedString 属性,不是页面级装饰绘制。
  3. RDEPUBSelectionOverlayView 还是半成品,未形成可用闭环。
  4. inline attachment 虽已大幅收敛,但仍需要对问题书样做专项验书。
  5. 位置模型仍是 href + progression,不是 WXRead 的字符级锚点。
  6. 章节数据模型仍然分散,没有形成 WRChapterData 式内聚模型。

优先级

P1当前渲染链必须补齐

  • CoreText 原生命中测试与选区模型
  • 页面级装饰绘制层
  • RDEPUBSelectionOverlayView 闭环
  • inline attachment 验书与细节修正

P2精度与架构内聚

  • 字符级位置模型
  • 章节数据模型内聚

P3外围能力

  • 翻页 crash patch
  • 多栏
  • 字体系统
  • TTS / DRM / Pencil 等

Phase 1CoreText 命中与选区收口

目标

去掉文本页对 UITextView 选区代理的核心依赖,改成和 WXRead 一样基于页面 layoutFrame / line / run 的命中测试与选区计算。

范围

  • RDEPUBTextContentView
  • RDEPUBSelectionOverlayView
  • 新增页面几何辅助对象或工具类型

主要工作

  1. 基于当前页 DTCoreTextLayoutFrame 建立字符命中入口。
  2. 实现单点命中:CGPoint -> character index
  3. 实现拖拽扩选:起点 index、终点 index、range 归一化。
  4. 输出选区矩形集合:用于高亮、手柄、菜单定位。
  5. RDEPUBSelectionOverlayView 直接消费 CoreText 选区矩形,而不是依赖 UITextView
  6. 保留 UITextView 仅作为兜底或临时兼容层,最终目标是让它不再决定正文选区几何。

产出

  • 页面级命中测试工具
  • 页面级选区 range 计算逻辑
  • 页面级选区 rect 计算逻辑
  • RDEPUBSelectionOverlayView 可实际工作

验收标准

  • 长按正文任意位置,选区起点与落点稳定。
  • 拖动选区不会出现明显错位、跳行、截断。
  • 脚注图标、inline image、跨行高亮附近仍能稳定选中相邻文字。
  • 不再依赖 UITextView.selectedRange 作为主选区真值。

风险

  • DTCoreText 暴露的行/run 几何可能和系统 UITextView 行为不完全一致。
  • inline attachment 附近的 index 映射需要特别小心。

Phase 2页面级装饰绘制层

目标

把高亮、下划线、搜索命中从 attributedString 注入迁到页面级 CGContext 绘制,和 WXRead 的页面装饰层一致。

范围

  • RDEPUBDirectCoreTextPageView
  • RDEPUBTextContentView
  • 可能新增 RDEPUBPageDecorationRenderer

主要工作

  1. 将高亮、下划线、搜索命中从“内容属性”改成“页面装饰数据”。
  2. 基于当前页 range 计算每种装饰的 rect 集合。
  3. 在页面 draw(_:) 或 overlay 中按层次绘制:
    • 搜索命中
    • 高亮背景
    • 下划线
    • 选区高亮
  4. 统一颜色、透明度、绘制顺序,避免正文颜色污染。

产出

  • 页面装饰几何模型
  • 页面装饰绘制实现
  • attributedString 注入逻辑的瘦身或移除

验收标准

  • 搜索高亮不再改变底层排版结果。
  • 高亮和下划线不再依赖正文属性重排。
  • 同一页同时存在搜索命中、标注、选区时,层次稳定、不互相遮挡异常。

风险

  • 需要处理跨行 range 拆分。
  • 需要处理 attachment、段前段后间距、最后一行空白的 rect 裁剪。

Phase 3inline attachment 专项验书与收敛

目标

继续把 inline image、脚注图标、特殊图片在排版指标和页面显示上收紧到更接近 WXRead。

范围

  • RDEPUBTextRendererSupport.normalizeAttachmentLayoutForWXRead
  • RDEPUBTextContentView.normalizeInlineAttachments
  • 问题 EPUB 样本专项验证

主要工作

  1. 建立 attachment 分类表:
    • 脚注图标
    • 普通 inline image
    • block image
    • cover image
  2. 逐类校正:
    • displaySize
    • verticalAlignment
    • 基线占位
    • 页内/跨页表现
  3. 对问题书样做页对页比对,记录剩余差异。
  4. 去掉重复、冲突的 attachment 二次归一化逻辑,保证“同一类 attachment 只走一套规则”。

产出

  • attachment 规则矩阵
  • 书样问题清单
  • 附件归一化逻辑收口

验收标准

  • .qqreader-footnote 与正文基线对齐稳定。
  • 普通内容图片不再出现页内漂移、倒置、重复绘制、页尾大空白。
  • 同一 EPUB 在分页和显示阶段不会再出现 attachment 指标不一致。

风险

  • 不同 EPUB 资源命名习惯不同,分类可能需要结合 class、src、style 多维判断。

Phase 4字符级位置模型

目标

从当前 href + progression 提升到更接近 WXRead 的字符级位置锚点,减少重排后的标注漂移。

范围

  • RDEPUBLocation
  • RDEPUBTextBook
  • RDEPUBHighlight / RDEPUBBookmark
  • 选区序列化与恢复

主要工作

  1. 设计新的文本位置载体:
    • 章节索引
    • 章节内字符偏移
    • 可选 fragment / 行列辅助信息
  2. 建立双向转换:
    • 页面 → 字符 range
    • 字符 range → 页面
  3. 保留对旧 progression 数据的兼容读取。
  4. 更新标注恢复、搜索跳转、书签跳转逻辑。

产出

  • 新位置模型
  • 兼容迁移策略
  • 标注恢复精度提升

验收标准

  • 改字号、改行距后重新分页,已有标注仍能落回正确正文范围。
  • 多次翻页、重建 RDEPUBTextBook 后,范围恢复稳定。

风险

  • 旧数据兼容与迁移策略需要谨慎。
  • attachment、fragment marker、语义 marker 会影响纯字符 offset 映射。

Phase 5章节数据模型内聚

目标

把分散在 RDEPUBTextChapterRDEPUBHighlight、目录、分页诊断里的数据逐步收敛成更像 WRChapterData 的一体化章节模型。

范围

  • RDEPUBTextChapter
  • RDEPUBTextBook
  • 标注、目录、分页诊断承载方式

主要工作

  1. 定义章节聚合对象,统一承载:
    • attributedContent
    • page frames / page ranges
    • fragment offsets
    • highlights / bookmarks
    • outline / TOC mapping
    • pagination diagnostics
  2. 让控制器层从“自己拼数据”改成“消费章节聚合对象”。
  3. 为后续位置模型、装饰绘制、选区恢复提供统一数据入口。

产出

  • 新章节聚合模型
  • 控制器简化
  • 数据流收口

验收标准

  • 阅读器控制器中的章节相关派生逻辑明显减少。
  • 标注、分页、目录不再分散在多个不一致的数据结构里。

Phase 6外围能力补齐

目标

处理不影响当前正文质量但和 WXRead 存在差距的外围能力。

包含项

  • UIPageViewController crash patch
  • 多栏排版
  • 字体动态加载
  • TTS / DRM / Pencil / 预加载

建议

  • 这批能力不要和当前正文排版修复混在一个阶段。
  • 先把正文页面链路闭环,再独立立项。

执行顺序建议

  1. Phase 1CoreText 命中与选区收口
  2. Phase 2页面级装饰绘制层
  3. Phase 3inline attachment 专项验书与收敛
  4. Phase 4字符级位置模型
  5. Phase 5章节数据模型内聚
  6. Phase 6外围能力补齐

原因:

  • Phase 1 和 Phase 2 会直接决定“页面几何模型”是否真正闭环。
  • Phase 3 需要建立在前两步的页面几何一致性之上,否则 attachment 还会被多套逻辑干扰。
  • Phase 4 和 Phase 5 更偏位置与架构内聚,适合在页面几何稳定后推进。

每阶段验证方式

功能验证

  • 问题 EPUB 书样页对页比对
  • 翻页前后位置恢复
  • 高亮、搜索、选区、脚注图标组合场景验证

构建验证

  • RDReaderView scheme 构建
  • ReadViewDemo scheme 构建

回归关注点

  • 页尾空白是否回归
  • 图片是否重复绘制
  • 内容是否倒置
  • 搜索高亮是否影响分页
  • 标注恢复是否漂移

建议的文档联动

  • 本文档用于排期和实施顺序。
  • 架构对比分析_WXRead_vs_ReadViewSDK.md 继续作为“差距现状”文档。
  • 每完成一个阶段,回写一份“已完成/剩余风险”更新到对比分析文档中。