From 948004eed14e8b423b19ee72c0d0c1260aa3ebfd Mon Sep 17 00:00:00 2001
From: shen <>
Date: Mon, 1 Jun 2026 09:33:23 +0800
Subject: [PATCH] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=E6=B3=A8=E9=87=8A?=
=?UTF-8?q?=E3=80=81=E4=BF=AE=E6=AD=A3=E8=BF=87=E6=97=B6=E6=96=87=E6=A1=A3?=
=?UTF-8?q?=E3=80=81=E6=B8=85=E7=90=86=E9=87=8D=E5=A4=8D=E5=86=85=E5=AE=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
源码注释:
- 为 ~60 个 Swift 文件补充缺失的 doc comment(file header、类型、属性、方法)
- 修正 4 处错误注释:翻页模式数量、搜索行为描述、手势识别器描述、悬空文档块
文档维护:
- 删除重复文档:WXRead/读书EPUB阅读器实现架构.md(与微信读书版完全一致)
- 合并重叠文档:阅读器规划.md → 阅读器功能开发计划.md(单一真值)
- 修正过时内容:所有文档中"四种翻页模式"→"三种",移除 horizontalCoverScroll
- 更新架构图:补齐 EPUBUI/ReaderController、Paging/、Typesetter/ 等子目录
- 更新 index.md 索引:新增开发计划和架构对比文档引用
---
Doc/ARCHITECTURE.md | 130 ++-
Doc/EPUBUI_功能实现逻辑.md | 2 +-
Doc/RDReaderView_功能实现逻辑.md | 19 +-
Doc/WXRead/读书EPUB阅读器实现架构.md | 560 -------------
Doc/index.md | 6 +-
Doc/阅读器功能开发计划.md | 83 +-
Doc/阅读器规划.md | 162 ----
ReadViewDemo/ViewController.swift | 753 ++++++++++++++++++
.../EPUBCore/RDEPUBJavaScriptBridge.swift | 9 +
.../EPUBCore/RDEPUBPublication.swift | 2 +
.../EPUBCore/RDEPUBSearchEngine.swift | 7 +
.../BuildPipeline/RDEPUBTextBookBuilder.swift | 7 +
.../BuildPipeline/RDEPUBTextBookModels.swift | 10 -
.../RDEPUBTextBuildPipelineInterfaces.swift | 20 +
.../RDEPUBTextPaginationInterfaces.swift | 23 +
.../RDEPUBTextPositionConverter.swift | 43 +
.../RDEPUBAttachmentNormalizer.swift | 1 +
.../Typesetter/RDEPUBFontNormalizer.swift | 3 +
.../RDEPUBFragmentMarkerInjector.swift | 8 +
.../Typesetter/RDEPUBHTMLNormalizer.swift | 6 +
.../RDEPUBRenderDiagnosticsCollector.swift | 6 +
.../RDEPUBSemanticMarkerInjector.swift | 9 +
.../Typesetter/RDEPUBStyleSheetComposer.swift | 14 +
.../RDEPUBTypesettingPipeline.swift | 23 +
...PUBReaderController+ContentDelegates.swift | 23 +
.../RDEPUBReaderController+DataSource.swift | 20 +
.../RDEPUBReaderController+PublicAPI.swift | 71 +-
...RDEPUBReaderController+RenderSupport.swift | 20 +
...RDEPUBReaderController+RuntimeBridge.swift | 51 +-
...EPUBReaderController+TableOfContents.swift | 12 +
.../EPUBUI/RDEPUBViewportTypes.swift | 9 +
.../RDEPUBWebDecorationOverlayView.swift | 5 +-
.../RDEPUBReaderAnnotationCoordinator.swift | 27 +
.../RDEPUBReaderAssemblyCoordinator.swift | 8 +
.../RDEPUBReaderChromeCoordinator.swift | 14 +
.../RDEPUBReaderContext.swift | 52 ++
.../RDEPUBReaderDependencies.swift | 23 +
.../RDEPUBReaderLoadCoordinator.swift | 9 +
.../RDEPUBReaderLocationCoordinator.swift | 11 +
.../RDEPUBReaderPaginationCoordinator.swift | 15 +
.../RDEPUBReaderRuntime.swift | 39 +
.../RDEPUBReaderSearchCoordinator.swift | 11 +
.../RDEPUBReaderViewportMonitor.swift | 11 +
.../TextPage/RDEPUBSelectableTextView.swift | 6 +-
.../RDEPUBTextAnnotationOverlay.swift | 21 +-
.../RDEPUBTextPageDecorationView.swift | 3 +-
.../EPUBUI/UIColor+RDEPUBHex.swift | 5 +
.../Paging/RDReaderPreloadController.swift | 19 +
.../Paging/RDReaderSpreadResolver.swift | 15 +
.../Paging/RDReaderTapRegionHandler.swift | 14 +
.../RDReaderView+CollectionView.swift | 7 +
.../RDReaderView+ContentAccess.swift | 7 +
.../ReaderView/RDReaderView+PageCurl.swift | 7 +
.../ReaderView/RDReaderView+ToolView.swift | 16 +-
.../ReaderView/RDReaderView.swift | 6 +-
.../ReaderView/RDReaderViewProtocols.swift | 20 +
56 files changed, 1691 insertions(+), 792 deletions(-)
delete mode 100644 Doc/WXRead/读书EPUB阅读器实现架构.md
delete mode 100644 Doc/阅读器规划.md
create mode 100644 ReadViewDemo/ViewController.swift
diff --git a/Doc/ARCHITECTURE.md b/Doc/ARCHITECTURE.md
index 39a093f..29e35d6 100644
--- a/Doc/ARCHITECTURE.md
+++ b/Doc/ARCHITECTURE.md
@@ -21,70 +21,143 @@ RDReaderView 是一个 iOS 阅读器组件库(CocoaPods),提供开箱即
│
┌───────────────────────────▼─────────────────────────────┐
│ EPUBUI 层(library 级读者 UI) │
-│ RDEPUBReaderController(开箱即用入口,~1995 行) │
-│ RDEPUBReaderConfiguration / Theme / Settings / Persistence│
-│ TopToolView / BottomToolView / ToolView 基类 │
-│ ChapterList / Highlights / Bookmarks / Settings 面板 │
-│ RDEPUBTextContentView / RDEPUBWebContentView │
-│ RDEPUBPageInteractionController / SelectionOverlayView │
-│ RDEPUBPageLayoutSnapshot / RDURLReaderController │
+│ │
+│ 主控制器 │
+│ RDEPUBReaderController(开箱即用入口) │
+│ +ContentDelegates / +DataSource / +PublicAPI │
+│ +RenderSupport / +RuntimeBridge / +TableOfContents │
+│ RDURLReaderController(URL 阅读入口) │
+│ │
+│ ReaderController/(协调器) │
+│ RDEPUBReaderRuntime(中央运行时协调器) │
+│ RDEPUBReaderContext(上下文状态容器) │
+│ RDEPUBReaderDependencies(依赖注入) │
+│ RDEPUBReaderLoadCoordinator(EPUB 加载) │
+│ RDEPUBReaderPaginationCoordinator(分页协调) │
+│ RDEPUBReaderLocationCoordinator(位置持久化) │
+│ RDEPUBReaderAnnotationCoordinator(标注管理) │
+│ RDEPUBReaderSearchCoordinator(搜索) │
+│ RDEPUBReaderChromeCoordinator(工具栏) │
+│ RDEPUBReaderAssemblyCoordinator(UI 组装) │
+│ RDEPUBReaderViewportMonitor(视口变化监听) │
+│ │
+│ Settings/(配置与主题) │
+│ RDEPUBReaderConfiguration / RDEPUBReaderSettings │
+│ RDEPUBReaderSettingsViewController / RDEPUBReaderTheme │
+│ │
+│ TextPage/(文本页面交互) │
+│ RDEPUBTextContentView / RDEPUBTextPageRenderView │
+│ RDEPUBSelectableTextView / RDEPUBTextSelectionController│
+│ RDEPUBSelectionOverlayView / RDEPUBTextAnnotationOverlay│
+│ RDEPUBPageInteractionController / RDEPUBPageLayoutSnapshot│
+│ RDEPUBTextPageDecorationView │
+│ │
+│ 工具栏与面板 │
+│ RDEPUBReaderTopToolView / RDEPUBReaderBottomToolView │
+│ RDEPUBReaderToolView(基类) │
+│ RDEPUBReaderChapterListController(目录面板) │
+│ RDEPUBReaderHighlightsViewController(高亮管理) │
+│ RDEPUBReaderPersistence(位置持久化) │
+│ RDEPUBReaderDelegate / RDEPUBReaderTableOfContentsItem│
+│ RDEPUBWebContentView / RDEPUBWebDecorationOverlayView │
+│ RDEPUBViewportTypes / UIColor+RDEPUBHex │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ 翻页容器层(RDReaderView) │
+│ │
│ RDReaderView(UIView,统一翻页外壳) │
-│ 4 种翻页模式:pageCurl / horizontalScroll / │
-│ verticalScroll / horizontalCoverScroll │
+│ 3 种翻页模式:pageCurl / horizontalScroll / │
+│ verticalScroll │
+│ RDReaderViewProtocols(DataSource / Delegate / DisplayType)│
+│ +CollectionView / +ContentAccess / +PageCurl / +ToolView │
│ RDReaderFlowLayout / RDReaderContentCell │
│ RDReaderPageChildViewController(pageCurl 页包装) │
+│ RDReaderGestureController │
+│ │
+│ Paging/(翻页控制) │
+│ RDReaderPagingController(转场与排队) │
+│ RDReaderPreloadController(预加载与缓存) │
+│ RDReaderSpreadResolver(双页配对) │
+│ RDReaderTapRegionHandler(手势分区) │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ EPUBCore 层(EPUB 引擎) │
│ │
-│ Publication 层 │
+│ 解析与模型 │
│ RDEPUBParser(+Archive / +Package / +TOC / │
│ +ReadingProfile / +Resources) │
│ RDEPUBPublication(出版物聚合对象) │
│ RDEPUBModels(metadata / manifest / spine 模型) │
-│ RDEPUBReadingModels(location / viewport / highlight) │
+│ Models/ │
+│ RDEPUBReadingLocationModels(location 模型) │
+│ RDEPUBPaginationModels(分页模型) │
+│ RDEPUBAnnotationModels(标注模型) │
│ RDEPUBTextAnchor / RDEPUBTextRangeAnchor(文本锚点) │
│ RDEPUBRenderRequest(渲染请求模型) │
│ │
-│ Services 层 │
+│ 服务层 │
│ RDEPUBResourceResolver(资源 URL 统一入口) │
+│ RDEPUBResourceURLSchemeHandler(ss-reader:// 协议) │
│ RDEPUBPreferences(展示参数聚合) │
│ RDEPUBPaginator(离屏分页服务) │
+│ RDEPUBStyleSheetBuilder / RDEPUBJavaScriptBridge │
+│ RDEPUBFixedLayoutTemplate / RDEPUBAssetRepository │
│ │
-│ Navigator 层 │
+│ 会话与导航 │
│ RDEPUBReadingSession(状态机 + 会话协调) │
│ RDEPUBNavigatorState(状态枚举) │
│ RDEPUBNavigatorLayoutContext │
│ │
-│ Resource View 层 │
+│ WebView 渲染 │
│ RDEPUBWebView(+Configuration / +Reflowable / │
│ +FixedLayout / +JavaScriptBridge / │
│ +Search) │
-│ RDEPUBResourceURLSchemeHandler(ss-reader:// 协议) │
-│ RDEPUBStyleSheetBuilder / RDEPUBJavaScriptBridge │
-│ RDEPUBFixedLayoutTemplate / RDEPUBAssetRepository │
│ RDEPUBWebViewDebug(调试日志工具) │
│ │
-│ Search 层 │
+│ 搜索 │
│ RDEPUBSearchEngine(协议)/ RDEPUBHTMLSearchEngine │
│ RDEPUBSearchModels(SearchMatch/Result/State/Presentation)│
└───────────────────────────┬─────────────────────────────┘
-
+ │
┌───────────────────────────▼─────────────────────────────┐
│ EPUBTextRendering 层(文本 EPUB 渲染) │
-│ RDEPUBTextRenderer(协议) │
-│ RDEPUBDTCoreTextRenderer(DTCoreText 实现) │
-│ RDEPUBTextRendererSupport / RDEPUBTextPaginationSupport │
-│ RDEPUBTextBookBuilder / RDPlainTextBookBuilder │
-│ RDEPUBTextLayouter / RDEPUBTextLayoutFrame │
-│ RDEPUBTextBookCache / RDEPUBChapterData │
-│ RDEPUBTextIndexTable / RDEPUBTextPerformanceSampler │
-│ RDEPUBTextSearchEngine │
+│ │
+│ 渲染 │
+│ RDEPUBTextRenderer(协议) │
+│ RDEPUBDTCoreTextRenderer(DTCoreText 实现) │
+│ RDPlainTextBookBuilder(纯文本书籍构建) │
+│ RDEPUBTextPositionConverter(位置转换器) │
+│ RDEPUBTextSearchEngine(文本搜索引擎) │
+│ RDEPUBTextIndexTable / RDEPUBChapterData │
+│ │
+│ BuildPipeline/(构建管线) │
+│ RDEPUBTextBookBuilder(分页书籍构建器) │
+│ RDEPUBTextBookCache / RDEPUBTextBookModels │
+│ RDEPUBTextBuildPipelineInterfaces(管线协议) │
+│ RDEPUBPaginationCacheCoordinator(缓存协调) │
+│ RDEPUBChapterTailNormalizer(章尾规范化) │
+│ RDEPUBBuildDiagnosticsReporter(诊断报告) │
+│ RDEPUBTextPerformanceSampler(性能采样) │
+│ │
+│ Pagination/(分页引擎) │
+│ RDEPUBTextLayouter / RDEPUBTextLayoutFrame │
+│ RDEPUBChapterPageCounter / RDEPUBCoreTextPageFrameFactory│
+│ RDEPUBPageBreakPolicy(断页策略) │
+│ RDEPUBTextPaginationInterfaces(分页协议) │
+│ RDEPUBTextPaginationSupport(分页支持) │
+│ │
+│ Typesetter/(排版管线) │
+│ RDEPUBTypesettingPipeline(排版管线编排) │
+│ RDEPUBHTMLNormalizer(HTML 规范化) │
+│ RDEPUBStyleSheetComposer(CSS 组合) │
+│ RDEPUBFontNormalizer(字体规范化) │
+│ RDEPUBAttachmentNormalizer(附件规范化) │
+│ RDEPUBFragmentMarkerInjector(Fragment 标记注入) │
+│ RDEPUBSemanticMarkerInjector(语义标记注入) │
+│ RDEPUBRenderDiagnosticsCollector(渲染诊断) │
+│ RDEPUBTextRendererSupport(渲染辅助工具) │
└──────────────────────────────────────────────────────────┘
```
@@ -92,14 +165,13 @@ RDReaderView 是一个 iOS 阅读器组件库(CocoaPods),提供开箱即
## 3. 翻页容器层(RDReaderView)
-### 3.1 四种翻页模式
+### 3.1 三种翻页模式
| 模式 | 实现方式 | 特点 |
|------|----------|------|
| `pageCurl` | UIPageViewController | 原生翻书效果,手势由系统提供 |
| `horizontalScroll` | UICollectionView + RDReaderFlowLayout | 每屏显示 2 项,水平分页滚动 |
| `verticalScroll` | UICollectionView + RDReaderFlowLayout | 全宽项目,垂直连续滚动 |
-| `horizontalCoverScroll` | UICollectionView + RDReaderFlowLayout | 覆盖滚动效果,Z 轴动画 |
### 3.2 数据源协议
diff --git a/Doc/EPUBUI_功能实现逻辑.md b/Doc/EPUBUI_功能实现逻辑.md
index d304d06..525022b 100644
--- a/Doc/EPUBUI_功能实现逻辑.md
+++ b/Doc/EPUBUI_功能实现逻辑.md
@@ -249,7 +249,7 @@ RDEPUBReaderSettings (Codable)
└── themePreset: RDEPUBReaderThemePreset?
```
-`RDEPUBReaderDisplayMode`:可序列化的翻页模式枚举(pageCurl / horizontalScroll / verticalScroll / horizontalCoverScroll),与 `RDReaderView.DisplayType` 相互转换。
+`RDEPUBReaderDisplayMode`:可序列化的翻页模式枚举(pageCurl / horizontalScroll / verticalScroll),与 `RDReaderView.DisplayType` 相互转换。注意:历史版本遗留的 `horizontalCoverScroll` 会自动映射为 `horizontalScroll`。
`RDEPUBReaderThemePreset`:可序列化的主题预设枚举(light / yellow / green / pink / blue / dark),与 `RDEPUBReaderTheme` 相互转换。
diff --git a/Doc/RDReaderView_功能实现逻辑.md b/Doc/RDReaderView_功能实现逻辑.md
index fece1f8..30453e0 100644
--- a/Doc/RDReaderView_功能实现逻辑.md
+++ b/Doc/RDReaderView_功能实现逻辑.md
@@ -3,7 +3,7 @@
## 1. 范围与目标
- 代码范围:`Sources/RDReaderView/ReaderView/`(5 个 Swift 文件)
-- 目标:说明分页阅读器容器如何管理四种显示模式、DataSource/Delegate 协议、翻页交互、工具栏动画、双屏适配和 RTL 支持。
+- 目标:说明分页阅读器容器如何管理三种显示模式、DataSource/Delegate 协议、翻页交互、工具栏动画、双屏适配和 RTL 支持。
- 主链路关键词:`RDReaderDataSource -> reloadData -> DisplayType 切换 -> 翻页/滚动 -> RDReaderDelegate.pageNum -> 工具栏显隐`。
## 2. 关键对象职责
@@ -13,7 +13,7 @@
- 文件:`Sources/RDReaderView/ReaderView/RDReaderView.swift`(~1219 行)
- 入口方法:`reloadData()`
- 职责:
- - 管理四种显示模式的视图层级切换
+ - 管理三种显示模式的视图层级切换
- 持有 `UIPageViewController`(pageCurl 模式)或 `UICollectionView`(滚动模式)
- 处理点击手势(左/中/右三区域)
- 管理工具栏(topToolView / bottomToolView)的显示/隐藏动画
@@ -25,10 +25,9 @@
- 文件:`Sources/RDReaderView/ReaderView/RDReaderFlowLayout.swift`(~375 行)
- 职责:
- - 继承 `UICollectionViewFlowLayout`,为三种滚动模式提供布局计算
+ - 继承 `UICollectionViewFlowLayout`,为两种滚动模式提供布局计算
- 水平滚动:全屏宽 item,pagingEnabled
- 垂直滚动:可变高度 item,累加计算
- - 水平覆盖滚动:zIndex 分层 + 阴影效果模拟深度
- 封面感知帧计算:封面页全屏宽,后续页面两两配对半屏宽
### 2.3 内容 Cell `RDReaderContentCell`
@@ -80,7 +79,7 @@ func pageNum(readerView: RDReaderView, pageNum: Int)
3. `reloadData` 内部调用 `switchReaderDisplayType(currentDisplayType)` 重建视图层级。
4. 同时从 `dataSource` 获取 `topToolView` 和 `bottomToolView` 并添加到视图层级。
-### 3.3 四种显示模式切换
+### 3.3 三种显示模式切换
**pageCurl 模式**:
- 创建 `UIPageViewController`(transitionStyle: .pageCurl)
@@ -99,13 +98,6 @@ func pageNum(readerView: RDReaderView, pageNum: Int)
- 页面高度可变,通过 `RDReaderFlowLayoutDataSoure.heigtOfVerticalScrollPage` 查询
- collectionViewContentSize 为所有页面高度之和
-**horizontalCoverScroll 模式**:
-- 水平分页,但带封面滑动动画
-- `layoutAttributesForElements` 中:
- - 仅计算当前页附近的窄窗口内的 item attributes
- - 当前页之前的 item zIndex = -1,当前及之后 zIndex = 1
- - 顶层页面边缘添加阴影效果
-
### 3.4 翻页交互
**点击手势**(`tapAction(tap:)`):
@@ -170,8 +162,7 @@ func pageNum(readerView: RDReaderView, pageNum: Int)
RDReaderView.DisplayType
├── .pageCurl // UIPageViewController 翻页效果
├── .horizontalScroll // UICollectionView 水平滚动
- ├── .verticalScroll // UICollectionView 垂直滚动
- └── .horizontalCoverScroll // UICollectionView 水平覆盖动画
+ └── .verticalScroll // UICollectionView 垂直滚动
```
### 5.2 翻页方向
diff --git a/Doc/WXRead/读书EPUB阅读器实现架构.md b/Doc/WXRead/读书EPUB阅读器实现架构.md
deleted file mode 100644
index 444adfd..0000000
--- a/Doc/WXRead/读书EPUB阅读器实现架构.md
+++ /dev/null
@@ -1,560 +0,0 @@
-# 读书 EPUB 阅读器实现架构分析
-
-> 分析日期: 2026-05-18
-> 基于读书 v10.0.3
-
----
-
-## 核心结论:双渲染引擎架构
-
-读书使用了 **两套渲染引擎**,根据内容类型选择不同的渲染路径:
-
-```
-┌─────────────────────────────────────────────────┐
-│ WRReaderViewController │
-│ (阅读器主控制器, 管理翻页和状态) │
-├─────────────────────────────────────────────────┤
-│ WRPageViewController │
-│ (基于 UIPageViewController) │
-│ 支持 UIPageCurl(仿真翻页) + Scroll(滑动) │
-├──────────────────────┬──────────────────────────┤
-│ 路径A: 原生渲染 │ 路径B: WebView 渲染 │
-│ (EPUB/书籍正文) │ (公众号/文集文章) │
-│ │ │
-│ WREpubTypesetter │ WKWebView + JS Bridge │
-│ DTCoreText │ weread-highlighter.js │
-│ CoreText 排版 │ rangy-*.js │
-│ NSAttributedString │ MediaPlatform.js/css │
-│ WRCoreTextLayouter │ Readability.js │
-│ WRPageView (draw) │ WRMPPageView │
-└──────────────────────┴──────────────────────────┘
-```
-
----
-
-## 路径A:EPUB 正文原生渲染 (核心路径)
-
-这是 EPUB 阅读的**主要渲染方式**,完全用原生 CoreText 实现,不走 WebView。
-
-### 1. EPUB 下载与解密流程
-
-```
-服务器 ZIP 包 (加密)
- │
- ▼
-WRBookNetwork.loadTarForEpubBookId:chapter:isPreload:
- │
- ▼
-WRBookNetwork.handleUnzipWithBookId:zipPath:encryptKey:plainBookDirectory:
- │ - 使用 encryptKey 解密
- │ - 解压到 plainBookDirectory
- │ - 处理解压错误 handleUnzipErrorWithPath:
- ▼
-WRBookNetwork.processEncryptedBookFileAtPath:encryptKey:book:chapterUid:isFromReview:
- │
- ▼
-WREncryptedFileManager.decryptContentsOfFile:forBookId:isFileLost:
- │ - keyForBookId: 获取每本书的密钥
- │ - 解密 EPUB 章节文件
- ▼
-WREncryptedFileManager.encryptFileForBookId:originalEncryptKey:atPath:toPath:
- │ - 本地二次加密存储 (DRM 保护)
- ▼
-本地缓存: epubImage 目录 + 解密后的 XHTML 文件
-```
-
-**密钥管理**:
-- `WRPreloadBookManager.saveEncryptKey:forPath:bookId:` - 预加载章节密钥
-- `WRPreloadBookManager.encryptKeyForPath:bookId:` - 读取密钥
-- `WREncryptedFileManager.keyForBookId:` - 每本书独立密钥
-
-### 2. EPUB 解析与排版流程
-
-```
-XHTML 章节文件
- │
- ▼
-WRBookNetwork.fileContentWithChapter:book:shouldRemoveHtmlTags:filterTranslateContent:
- │ - 读取 XHTML 内容
- │ - 可选去除 HTML 标签
- │ - 过滤翻译内容
- ▼
-WREpubTypesetter.attributeStringWithFilePath:priority:insertArticleToolAttachment:
- insertBookChapterToolAttachment:insertRecommendView:book:chapter:
- pageFlippingStyle:renderErrorReason:isStyleFileNotFound:options:
- │
- │ ┌─────────────────────────────────────────┐
- │ │ DTHTMLAttributedStringBuilder │
- │ │ (HTML -> NSAttributedString 转换器) │
- │ │ │
- │ │ 1. 解析 XHTML DOM 树 │
- │ │ 2. 读取 EPUB 内嵌 CSS (replace.css) │
- │ │ 3. 合并默认样式 (default.css) │
- │ │ 4. 应用用户主题样式 (dark.css) │
- │ │ 5. 转换为 NSAttributedString │
- │ │ - 保留字体、颜色、行高、对齐等属性 │
- │ │ - 处理图片 (NSTextAttachment) │
- │ │ - 处理超链接 │
- │ └─────────────────────────────────────────┘
- ▼
-NSAttributedString (富文本)
- │
- ▼
-WRCoreTextLayouter (CoreText 排版引擎)
- │
- │ ┌─────────────────────────────────────────┐
- │ │ DTCoreText 框架 (自定义修改版) │
- │ │ │
- │ │ DTCoreTextLayouter │
- │ │ └─ CTTypesetter │
- │ │ └─ CTFramesetter │
- │ │ └─ DTCoreTextLayoutFrame │
- │ │ └─ CTFrame (每页) │
- │ │ └─ DTCoreTextLayoutLine │
- │ │ └─ CTLine (每行) │
- │ │ └─ DTCoreTextGlyphRun │
- │ │ └─ CTLine (字形) │
- │ │ │
- │ │ 特殊处理: │
- │ │ - wr-vertical-center-style (图片居中) │
- │ │ - weread-page-relate (分页控制) │
- │ │ - avoidPageBreakInside (避免断页) │
- │ │ - 繁简转换 (convertHansToHant) │
- │ └─────────────────────────────────────────┘
- ▼
-WRChapterData (章节数据模型)
- │
- │ - 包含排版后的 NSAttributedString
- │ - 管理划线/高亮/书评等标注
- │ - addHighlightInRange:key:itemId:color:
- │ - addUnderLineToAttributedString:range:itemId:style:color:
- │ - addReviewUnderlineInRange:itemId:type:
- │ - generateOutlineContents (生成目录)
- │ - freeTrialChapterCutOffStringLocaion (免费试读截断)
- ▼
-分页计算: WRChapterPageCount
- │
- │ - rangeValueWithPageInfo: 计算每页的 NSRange
- │ - rangeOfPage: 获取指定页的文本范围
- ▼
-WRPageView (页面视图, UIView 子类)
- │
- │ - 继承 UIView
- │ - drawRect: 中调用 CoreText 绘制
- │ - WRCoreTextLayoutFrame.drawInContext:image:size:inRect:position:
- │ - 直接用 CGContext 绘制文字和图片
- │ - 不使用 UILabel/UITextView
- ▼
-屏幕显示 (像素级精确渲染)
-```
-
-### 3. 翻页机制
-
-```
-WRPageViewController
- │
- │ 基于 UIPageViewController 封装
- │
- │ 初始化: initWithDelegate:withPageType:pageFlippingStyle:
- │
- │ pageFlippingStyle 支持:
- │ ┌────────────────────────────────────┐
- │ │ UIPageCurl - 仿真翻页 (纸张卷曲) │
- │ │ Scroll - 左右滑动翻页 │
- │ └────────────────────────────────────┘
- │
- │ 核心方法:
- │ - pageViewController:viewControllerBeforeViewController: (上一页)
- │ - pageViewController:viewControllerAfterViewController: (下一页)
- │ - pageViewController:spineLocationForInterfaceOrientation: (书脊位置)
- │ - weread_setViewControllers:withCurlOfType:fromLocation:direction:
- │ animated:notifyDelegate:completion: (自定义设置方法)
- │
- │ 故障修复:
- │ - patchNavigationDirectionFault (导航方向修复)
- │ - patchNoViewControllerManagingPageViewFault (页面管理修复)
- │ - patchUIPageCurlFault (翻页动画修复)
- │ - detectNavigationDirectionCrashWithPageViewController: (崩溃检测)
- │
- ▼
-WRPageView (每个页面的渲染视图)
- │
- │ - 通过 WRChapterData 获取排版结果
- │ - 通过 rangeOfPage: 获取当前页的文本范围
- │ - 使用 CoreText 直接绘制到 CGContext
-```
-
-### 4. 文本选择与标注
-
-```
-用户触摸/长按
- │
- ▼
-WRPageView 手势识别
- │
- ▼
-文本位置计算 (CoreText hit test)
- │ - CTLineGetStringIndexForPosition (坐标->字符索引)
- │ - CTLineGetOffsetForStringIndex (字符索引->坐标)
- ▼
-选择范围确定
- │
- ▼
-弹出操作菜单 (UIMenuController)
- │ - 划线/高亮
- │ - 写想法/书评
- │ - 复制
- │ - 查询/翻译
- │ - 分享
- ▼
-WRChapterData 添加标注
- │ - addHighlightInRange:key:itemId:color:
- │ - addUnderLineToAttributedString:range:itemId:style:color:
- │ - addReviewUnderlineInRange:itemId:type:
- ▼
-保存到服务器
- │ - WRBookNetwork.addReview:shareToWechat:...
- │ - 同步书签: loadBookmarkListWithBookId:syncKey:callback:
- ▼
-重新排版当前页 (recomposeCurrentPageViewWithSource:)
-```
-
----
-
-## 路径B:WebView 渲染 (公众号/文集文章)
-
-用于渲染**微信公众号文章、文集、书评**等富媒体内容。
-
-```
-HTML 内容 (来自服务器)
- │
- ▼
-WRMPReadingManager.composeMPReviewHTMLString:withReview:
- │ - 组装 HTML 模板
- │ - 注入 CSS (MediaPlatform.css, MPExtra.css)
- │ - 注入 JS (MediaPlatform.js, mpForArticle.js)
- ▼
-WKWebView 加载
- │
- │ 注入脚本:
- │
- │
- ▼
-weread-highlighter.js 初始化
- │
- │ 1. rangy.init() - 初始化 Rangy 选择库
- │ 2. 创建 Highlighter (TextRange 模式)
- │ 3. 注册 ClassApplier:
- │ - "highlight" (高亮)
- │ - "review" / "friend-review" (书评)
- │ - "reference" (引用)
- │ - "tts" (语音朗读标记)
- │ 4. 监听 selectionchange 事件
- │ 5. 通过 wereadBridge.execMPReaderMethod 通知原生
- ▼
-JS Bridge 双向通信
- │
- │ 原生 -> JS:
- │ - evaluateJavaScript: 调用 JS 方法
- │ - WKUserScript 注入脚本
- │
- │ JS -> 原生:
- │ - window.webkit.messageHandlers.XXX.postMessage()
- │ - wereadBridge.execMPReaderMethod('MPReader', data)
- ▼
-WRMPReadingViewModel (ViewModel 层)
- │
- │ - addHighlightWithStart:withEnd:withContent:callback:
- │ - addReviewWithRange:content:reference:secretMode:withCallback:
- │ - genJSInfosWithHighlights:refrencedHighlight:
- │ - genJSInfosWithReviews:refrencedReview:
- │ - readReviewsWithLoadCount:maxObj:
- │ - setupTTSAudioList
- ▼
-WRMPPageView (WebView 包装视图)
-```
-
----
-
-## 关键源码路径 (从二进制中提取)
-
-```
-WeRead/Src/Modules/EpubParser/
-├── WREpubTypesetter.m # EPUB 排版器
-├── WREpubPositionConverter.m # 位置转换器
-└── Utils/DTCoreTextFunctions.m # CoreText 工具函数
-
-WeRead/Src/Modules/TypeSetter/
-├── WRCoreTextLayouter.m # CoreText 排版器
-├── WRCoreTextLayoutFrame.m # 排版帧 (管理页面)
-└── DTCoreTextGlyphRun.m # 字形渲染
-
-WeRead/Src/Modules/Reading/
-├── Controller/
-│ ├── WRReaderViewController.m # 阅读器主控制器
-│ └── WRPageViewController.m # 翻页控制器
-├── Model/
-│ ├── WRChapterData.m # 章节数据模型
-│ ├── WRChapterDownloadManger.m # 章节下载管理
-│ ├── WRReaderViewModel.m # 阅读器 ViewModel
-│ └── WRMPReadingManager.m # 公众号阅读管理
-└── View/
- └── WRPageView.m # 页面渲染视图
-
-WeRead/Src/Modules/MediaPlatform/
-├── Controller/
-│ ├── WRMPListViewController.m
-│ └── WRMPSubscribeViewController.m
-└── Model/
- ├── WRMPCoverManager.m
- ├── WRMPCoverPainter.m
- ├── WRMPStore.m
- └── WRMPViewModel.m
-```
-
----
-
-## EPUB CSS 样式系统
-
-```
-加载优先级 (从低到高):
-1. default.css - 基础 HTML 标签样式 (Safari 默认)
-2. replace.css - 读书默认替换样式
- ├── 标题样式 (h1-h6, 使用 Source Han Serif CN 字体)
- ├── 代码块 (pre, 使用 Menlo 字体)
- ├── 图片 (.bodyPic, wr-vertical-center-style: 2)
- ├── 引用 (.conQuot)
- ├── 翻译 (.wr-translation)
- ├── 章节工具 (.book-chapter-tool, .chapter-tool)
- └── 分页控制 (.weread-page-relate)
-3. dark.css - 暗黑主题样式
-4. EPUB 内嵌 CSS - 书籍自带样式
-5. 用户设置 - 字号、行高、主题覆盖
-```
-
-**自定义 CSS 属性** (读书私有):
-- `wr-vertical-center-style: 1|2` - 图片垂直居中方式
-- `weread-page-relate: true` - 控制分页时的内容关联
-
----
-
-## 核心类职责表
-
-| 类名 | 职责 | 渲染路径 |
-|---|---|---|
-| `WRReaderViewController` | 阅读器主控制器,管理阅读状态、进度保存、章节跳转 | 共用 |
-| `WRPageViewController` | 翻页控制器,基于 UIPageViewController 封装 | 共用 |
-| `WRPageView` | 页面渲染视图,CoreText 直接绘制 | 路径A |
-| `WRMPPageView` | 公众号页面视图,WKWebView 包装 | 路径B |
-| `WREpubTypesetter` | EPUB 排版器,HTML->NSAttributedString | 路径A |
-| `WRCoreTextLayouter` | CoreText 排版引擎,管理 CTFrame/CTLine | 路径A |
-| `WRCoreTextLayoutFrame` | 排版帧,管理单页的绘制 | 路径A |
-| `WRChapterData` | 章节数据模型,存储排版结果和标注 | 路径A |
-| `WRChapterPageCount` | 分页计算,管理每页的 NSRange | 路径A |
-| `WREpubPositionConverter` | EPUB 位置转换器 (文件位置<->字符位置) | 路径A |
-| `WRChapterDownloadManger` | 章节下载管理器 | 共用 |
-| `WREncryptedFileManager` | 加密文件管理 (DRM) | 共用 |
-| `WRBookNetwork` | 书籍网络请求 (下载/解密/解压) | 共用 |
-| `WRMPReadingManager` | 公众号阅读管理器 | 路径B |
-| `WRMPReadingViewModel` | 公众号阅读 ViewModel (JS Bridge 交互) | 路径B |
-| `WRReaderViewModel` | 阅读器 ViewModel | 共用 |
-| `DTCoreTextLayouter` | DTCoreText 排版器 (第三方库修改版) | 路径A |
-| `DTHTMLAttributedStringBuilder` | HTML->NSAttributedString 构建器 | 路径A |
-| `WRReaderPencilNoteManager` | Apple Pencil 手写笔记管理 | 共用 |
-| `WRReaderTranslationManager` | 翻译管理 (繁简转换/中英翻译) | 共用 |
-| `WRReaderCht2sManager` | 繁体转简体管理 | 共用 |
-
----
-
-## JavaScript 文件职责
-
-| 文件 | 职责 |
-|---|---|
-| `weread-highlighter.js` | 核心高亮引擎,初始化 Rangy,管理选择和高亮 |
-| `rangy-core.js` | Rangy 核心库,跨浏览器 Range/Selection 封装 |
-| `rangy-highlighter.js` | Rangy 高亮模块,管理高亮的创建/删除/序列化 |
-| `rangy-classapplier.js` | Rangy ClassApplier 模块,CSS 类应用器 |
-| `rangy-textrange.js` | Rangy TextRange 模块,文本范围操作 |
-| `Readability.js` | Arc90 Readability 库,提取文章正文 |
-| `MediaPlatform.js` | 公众号平台 JS,原生-JS 桥接 |
-| `mpForArticle.js` | 文章相关 JS 逻辑 |
-| `MPExtra.css` | 公众号额外样式 |
-| `MediaPlatform.css` | 公众号基础样式 |
-| `WeReadApi.js` | 读书 JS API (供 WebView 调用原生功能) |
-| `rich_display.js` | 富文本显示逻辑 |
-| `cssInjector.js` | CSS 注入器 |
-| `highlight.min.js` | 代码语法高亮 (highlight.js) |
-
----
-
-## DRM 与安全机制
-
-```
-┌─────────────────────────────────────────────┐
-│ DRM 保护链 │
-├─────────────────────────────────────────────┤
-│ │
-│ 1. 传输层: HTTPS + 加密 ZIP │
-│ - 服务器下发加密的 .zip 文件 │
-│ - 文件名格式: {bookId}_DECRYPT.zip │
-│ │
-│ 2. 解密层: 逐章解密 │
-│ - WREncryptedFileManager │
-│ - keyForBookId: (每本书独立密钥) │
-│ - decryptContentsOfFile:forBookId: │
-│ │
-│ 3. 存储层: 本地二次加密 │
-│ - encryptFileForBookId:atPath:toPath: │
-│ - 解密后立即重新加密存储 │
-│ - 防止直接拷贝文件读取 │
-│ │
-│ 4. 密钥管理: │
-│ - WRPreloadBookManager 管理预加载密钥 │
-│ - 密钥与设备绑定 │
-│ - 通过 Keychain 安全存储 │
-│ │
-│ 5. 免费试读控制: │
-│ - freeTrialChapterCutOffStringLocaion │
-│ - 服务端控制试读范围 │
-│ - 客户端截断显示 │
-│ │
-│ 6. 章节付费: │
-│ - isChapterAvailableForBookId:chapterUid │
-│ - getCouponBuyChapterWithBookId: │
-│ - resetChapterPaidIfNeeded │
-│ │
-└─────────────────────────────────────────────┘
-```
-
----
-
-## 字体系统
-
-```
-内嵌字体:
-├── SourceHanSerifCN-Medium.ttf # 思源宋体 (正文默认)
-├── FZJuZhenXinFang.ttf # 方正聚珍新仿
-├── Lora-Regular.ttf / Italic.ttf # Lora 衬线体
-├── PlayfairDisplay-Regular.ttf # Playfair Display
-├── WeReadLS-Regular/Medium/Bold # 读书 LS 系列
-├── WeReadRN-Regular.ttf # RN 专用字体
-├── WeRead-Icon.ttf # 图标字体
-├── WeRead-Rating-Icon.ttf # 评分图标
-├── OpenDyslexic-Regular.otf # 阅读障碍友好字体
-├── WeChatNumber.ttf # 微信数字字体
-├── SharpGroteskTRIAL*.ttf # Sharp Grotesk 系列
-└── icon_font.ttf # 通用图标字体
-
-动态字体:
-├── CDN 下载: cdn.weread.qq.com/app/assets/font/
-│ ├── FZLTHProGBK_B/DB/SB.zip # 方正兰亭黑系列
-│ ├── FZQingKBYSJF-M.zip # 方正清刻本悦宋
-│ ├── FZSKBXKK.zip # 方正书宋
-│ ├── FZYBKSK.zip # 方正中楷
-│ └── SourceHanSansCN-Heavy.zip # 思源黑体
-│
-└── WRFontsManager 管理:
- - unZipFileAndRegisterFont:completionHandler:filePath:lateOverWrite:
- - 动态下载 + 解压 + 注册
-```
-
----
-
-## 预加载与缓存策略
-
-```
-预加载策略:
-├── WRForecastUtils.shouldPreloadChapterUidsForBook:type:bookRank:archiveRank:
-│ - 根据书籍排名和用户行为预测需要预加载的章节
-│
-├── WRChapterDownloadManger._preloadChapterContentWithBook:type:bookRank:
-│ - 后台预下载相邻章节
-│
-├── WRPreloadBookManager
-│ - saveEncryptKey:forPath:bookId: (缓存密钥)
-│ - saveFileNameDict:bookId: (缓存文件名映射)
-│ - clearKV (清理缓存)
-│
-└── SDWebImage 缓存:
- - epubImage 目录缓存书籍图片
- - com.hackemist.SDWebImageCache.epubImage
-
-缓存目录结构:
-├── Documents/
-│ └── {bookId}/
-│ ├── plainBookDirectory/ (解密后的 EPUB 文件)
-│ ├── epubImage/ (书籍图片缓存)
-│ └── _DECRYPT.zip (下载的加密 ZIP)
-└── Library/
- └── {cachePath}/
- ├── epubImage/ (SDWebImage 缓存)
- └── com.hackemist.SDWebImageCache.epubImage
-```
-
----
-
-## 朗读 (TTS) 集成
-
-```
-朗读流程:
-├── WRReadAloudAudio.parseCGIInfos: (解析音频信息)
-├── TTS 引擎: wxtts (微信语音合成)
-│ ├── 离线资源: wxtts_offline_resource5.zip
-│ ├── 在线资源: getWxttsSeginfo / getWxttsVoice
-│ └── VITS/VALL-E 模型 (高保真语音)
-│
-├── 文本分段:
-│ - weread-highlighter.js 中的 "tts" ClassApplier
-│ - 标记当前朗读位置
-│
-└── 进度同步:
- - lastListenedChapterOffset / lastListenedChapterUid
- - MPReading/lastListenedReviewId (公众号朗读进度)
-```
-
----
-
-## Apple Pencil 手写笔记
-
-```
-WRReaderPencilNoteManager:
-├── 数据存储:
-│ - writeDrawingDataToLocal:reviewItemId:reviewId:isDraft:
-│ - drawingFilePathWithReviewItemId:reviewId:isDraft:
-│ - 本地草稿 + 云端同步
-│
-├── 数据上传:
-│ - uploadPencilDrawing:colorStyle:onlyUploadImage:canRetry:
-│ - uploadPencilNoteData:suffix:
-│ - 使用腾讯云 COS 存储
-│ - authCosForPencilDataWithSuffix: (COS 认证)
-│
-├── 数据下载:
-│ - downloadDrawingDataFromCosWithUrl:desPath:callback:
-│ - downloadDrawingWithReviewItemId:reviewId:drawingUrl:dataBlock:
-│
-└── 图片导出:
- - imageFilePathWithReviewItemId:
- - 手绘笔记可导出为图片
-```
-
----
-
-## 总结
-
-| 特性 | 实现方式 |
-|---|---|
-| **EPUB 解析** | 自研 EPUB Parser,解析 OPF/NCX/XHTML |
-| **文字排版** | DTCoreText (CoreText 封装) + 自定义 WRCoreTextLayouter |
-| **页面渲染** | CGContext 直接绘制,不用 UILabel/UITextView |
-| **翻页效果** | UIPageViewController (UIPageCurl + Scroll) |
-| **文本选择** | CoreText hit test + Rangy.js (WebView 场景) |
-| **标注系统** | NSAttributedString 属性注入 + 服务器同步 |
-| **图片处理** | NSTextAttachment + CDN 尺寸优化 + 白底透明化 |
-| **DRM** | 逐章加密 + 逐书密钥 + 本地二次加密 |
-| **公众号文章** | WKWebView + JS Bridge + Rangy 高亮 |
-| **繁简转换** | CoreText 层面的 convertHansToHant |
-| **字体** | 内嵌 Source Han Serif CN + 动态下载字体 |
-| **预加载** | 后台预下载相邻章节 ZIP + 解密缓存 |
-| **TTS 朗读** | wxtts 引擎 + VITS/VALL-E 高保真模型 |
-| **手写笔记** | PencilKit + 腾讯云 COS 存储 |
diff --git a/Doc/index.md b/Doc/index.md
index 6b72b69..dd81530 100644
--- a/Doc/index.md
+++ b/Doc/index.md
@@ -14,13 +14,15 @@
|------|----------|------|
| [EPUBCore_功能实现逻辑.md](EPUBCore_功能实现逻辑.md) | `Sources/RDReaderView/EPUBCore/`(31 Swift + 2 资源) | EPUB 解析全流程(ZIP→container.xml→OPF→spine/TOC)、阅读会话状态机、离屏分页测量、`ss-reader://` 资源协议、JS 桥接(6 种消息)、WebView 渲染管线、文本锚点定位、渲染请求模型、缓存策略 |
| [EPUBTextRendering_功能实现逻辑.md](EPUBTextRendering_功能实现逻辑.md) | `Sources/RDReaderView/EPUBTextRendering/`(13 文件) | DTCoreText HTML→NSAttributedString 渲染管线、片段标记注入/提取、CoreText 分页引擎(含语义边界调整)、文本索引表、Location↔PageNumber 双向转换、分页缓存、性能采样、全文搜索引擎、纯文本构建器 |
-| [RDReaderView_功能实现逻辑.md](RDReaderView_功能实现逻辑.md) | `Sources/RDReaderView/ReaderView/`(5 文件) | 四种显示模式(pageCurl/horizontalScroll/verticalScroll/horizontalCoverScroll)、DataSource/Delegate 协议、点击三区域翻页、工具栏动画、双页配对与哨兵页、横竖屏适配、RTL 支持 |
+| [RDReaderView_功能实现逻辑.md](RDReaderView_功能实现逻辑.md) | `Sources/RDReaderView/ReaderView/`(5 文件) | 三种显示模式(pageCurl/horizontalScroll/verticalScroll)、DataSource/Delegate 协议、点击三区域翻页、工具栏动画、双页配对与哨兵页、横竖屏适配、RTL 支持 |
| [EPUBUI_功能实现逻辑.md](EPUBUI_功能实现逻辑.md) | `Sources/RDReaderView/EPUBUI/`(19 文件) | RDEPUBReaderController 全生命周期、三条渲染路径分发、配置变更检测与响应、工具栏/目录/高亮/书签/搜索/设置面板交互流、阅读位置持久化、主题管理、CoreText 页面交互 |
-## 方案讨论文档
+## 方案讨论与规划文档
| 文档 | 说明 |
|------|------|
+| [阅读器功能开发计划.md](阅读器功能开发计划.md) | 渲染质量三方对比(ReadViewSDK vs WXRead)、功能开发计划与落地状态、优先级路线图 |
+| [架构对比分析_WXRead_vs_ReadViewSDK.md](架构对比分析_WXRead_vs_ReadViewSDK.md) | ReadViewSDK 与 WXRead 的逐项架构核查,确认主链路复刻完成度 |
| [ReflowableEPUB_WXReadRenderer_Design.md](FeatureSolution/ReflowableEPUB_WXReadRenderer_Design.md) | 基于读书的 CoreText 渲染架构,设计 Reflowable EPUB 的增强文本渲染方案(CSS 分层、类型器升级) |
## 测试与质量
diff --git a/Doc/阅读器功能开发计划.md b/Doc/阅读器功能开发计划.md
index 87babd2..3009e04 100644
--- a/Doc/阅读器功能开发计划.md
+++ b/Doc/阅读器功能开发计划.md
@@ -1,7 +1,33 @@
# 阅读器功能开发计划
-基于 [阅读器规划.md](阅读器规划.md) 中的三方对比,本文档给出阅读器功能的开发计划与当前落地状态。
-功能完整度部分(书架、批注导出、阅读统计、TTS、全局搜索、云端同步、夜间定时)暂不展开。
+> 本文档整合了渲染质量三方对比(ReadViewSDK vs WXRead)与功能开发计划,作为阅读器能力演进的单一真值。
+> 基于读书 v10.0.3 逆向分析,与当前 ReadViewSDK 代码核查结果整合。
+
+## 背景
+
+渲染内核的架构对齐解决的是"代码可维护性"问题。本文档梳理从"能用的阅读器"到"能上架的商业阅读器"还需要补齐哪些能力,每项能力标注三方状态和具体实施计划。
+
+### 三方对比总览(渲染质量)
+
+| 缺失项 | 严重度 | ReadViewSDK | WXRead | 差距说明 |
+| --- | --- | --- | --- | --- |
+| **竖排文字** | 高 | ❌ 未实现 | ❌ 未实现 | 双方均无 `writing-mode` 支持 |
+| **Ruby 注音** | 高 | ❌ 未实现 | ❌ 未实现 | 双方均无 ``/`