ReadViewSDK/Doc/ARCHITECTURE.md
shenlei d7fcda345d refactor: rename RDReaderView -> RDEpubReaderView, update pod config and docs
- Rename source module from RDReaderView to RDEpubReaderView
- Move all source files from Sources/RDReaderView/ to Sources/RDEpubReaderView/
- Update podspec: RDReaderView.podspec -> RDEpubReaderView.podspec
- Update Podfile, demo project, and CocoaPods config for new pod name
- Delete old RDReaderView pod support files from ReadViewDemo/Pods
- Add new RDEpubReaderView pod support files
- Update documentation (API ref, architecture, UML, conventions, etc.)
- Add FixedLayoutRotationTests
- Update .gitignore: exclude .DS_Store, manual unpack backups, _ssoft-output
2026-07-10 19:44:53 +09:00

26 KiB
Raw Blame History

ReadViewSDK 系统架构文档

最后更新2026-06-22


1. 项目概览

ReadViewSDK 是一个 iOS EPUB 阅读器 SDK支持文本重排Reflowable和固定布局Fixed Layout两种 EPUB 格式,同时兼容纯文本 (.txt) 文件。SDK 提供完整的 EPUB 解析、文本渲染、分页计算、阅读 UI 和标注管理能力。

技术栈:

  • 语言Swift 5最低 iOS 15.6
  • 依赖DTCoreTextHTML→NSAttributedString、ZIPFoundationEPUB 解压、SnapKitAuto Layout、SSAlertSwift弹窗
  • 构建CocoaPods本地 pod 引用

2. 分层架构

┌─────────────────────────────────────────────────────────────┐
│                    ReadViewDemo (Demo App)                    │
│  ViewController · LaunchAutomationPlan · UITests             │
└──────────────────────────────┬──────────────────────────────┘
                               │ imports RDEpubReaderView
┌──────────────────────────────▼──────────────────────────────┐
│                       EPUBUI 层                              │
│  RDEPUBReaderController · Coordinators · Settings · TextPage │
│  ChapterRuntimeLoader · Store · DiskCache · PageMap      │
└──────────────────────────────┬──────────────────────────────┘
                               │
┌──────────────────────────────▼──────────────────────────────┐
│                    RDEpubReaderView 层                            │
│  RDEpubReaderView · FlowLayout · PreloadController               │
│  SpreadResolver · TapRegionHandler · PagingController        │
└──────────────────────────────┬──────────────────────────────┘
                               │
┌──────────────────────────────▼──────────────────────────────┐
│                  EPUBTextRendering 层                         │
│  TypesetterPipeline · DTCoreTextRenderer · Pagination        │
│  BuildPipelineTextBookBuilder · Cache · Sampler          │
└──────────────────────────────┬──────────────────────────────┘
                               │
┌──────────────────────────────▼──────────────────────────────┐
│                      EPUBCore 层                             │
│  RDEPUBParser · Publication · ResourceResolver               │
│  ReadingSession · WebView · JavaScriptBridge · Paginator     │
└─────────────────────────────────────────────────────────────┘

各层职责

职责 核心类
EPUBCore EPUB 文件解析、资源管理、WebView 渲染、JS 桥接 RDEPUBParser, RDEPUBPublication, RDEPUBWebView
EPUBTextRendering HTML→NSAttributedString 转换、排版、分页、全书构建 RDEPUBTextBookBuilder, RDEPUBCoreTextPageFrameFactory
RDEpubReaderView 通用翻页容器、手势识别、页面预加载、双页布局 RDEpubReaderView, RDEpubReaderFlowLayout, RDEpubReaderPreloadController
EPUBUI 阅读器控制器、协调器模式、设置面板、按需加载、磁盘缓存 RDEPUBReaderController, RDEPUBReaderPaginationCoordinator

3. 核心数据流

3.1 打开书籍流程

用户点击书籍
    │
    ▼
RDEPUBReaderController(epubURL:delegate:persistence:)  // 初始化,传入 epubURL
    │
    ├─ viewDidLoad() → startInitialLoadIfNeeded()
    │   │
    │   ├─ RDEPUBReaderLoadCoordinator.startInitialLoadIfNeeded()
    │   │   ├─ RDEPUBParser.parse(epubURL:)           // 解压 ZIP → 解析 OPF → 构建 spine/TOC
    │   │   │      └─ extractArchiveIfNeeded()        // ZIPFoundation 解压到 Caches
    │   │   │      └─ parseContainerRootFile()        // SAX 解析 container.xml
    │   │   │      └─ parseOPF()                      // SAX 解析 OPF (metadata/manifest/spine)
    │   │   │      └─ parseTOC()                      // NCX 或 Navigation Document
    │   │   │
    │   │   ├─ RDEPUBPublication(parser:)             // 创建门面对象
    │   │   ├─ 恢复持久化数据(书签/高亮/位置)
    │   │   └─ applyParsedPublication()
    │   │
    │   └─ 判断 readingProfile:
    │       ├─ .textReflowable → 文本排版路径(本 SDK 核心路径)
    │       ├─ .webInteractive → WebView 渲染路径
    │       └─ .webFixedLayout → 固定布局路径
    │
    └─ runtime.paginatePublication()                  // 进入分页流程

3.2 文本重排分页流程(大书优化路径)

paginateTextPublication()
    │
    ├─ restoreBookPageMapIfPossible()         // 尝试从磁盘恢复完整 BookPageMap
    │   └─ summaryDiskCache.readAll(keys:)    // 批量读取磁盘摘要
    │   └─ 如果完整 → 直接 applyBookPageMap() → 完成
    │
    ├─ 快速打开路径:
    │   ├─ loadFirstRenderableRuntimeChapter() // 加载第一个可渲染章节
    │   ├─ loadInitialRuntimeChapters()        // 加载窗口内相邻章节
    │   ├─ makePartialPageMap()                // 构建局部 BookPageMap
    │   └─ applyBookPageMap()                  // 应用到 UI用户可立即阅读
    │
    └─ RDEPUBMetadataParseWorker.start()      // 后台元数据解析
        │
        ├─ 预计算 contentHash串行          // 读取所有章节 HTML + SHA-256
        ├─ readAll(keys:) 恢复已有缓存
        ├─ waitForReadingInteractionToSettle() // 等待用户操作冷却 0.8s
        │
        ├─ OperationQueue (并发 N):
        │   ├─ buildChapter()                 // 渲染单章 (HTML→NSAttrStr→分页)
        │   ├─ chapterCacheKey()              // 构建缓存键(复用预计算 hash
        │   ├─ RDEPUBChapterSummary 写盘      // 异步写入磁盘摘要
        │   └─ 每 32 章刷新 BookPageMap       // 增量更新 UI
        │
        └─ 最终 applyBookPageMap()            // 完整页码映射

3.3 单章渲染管线

Raw HTML (从 EPUB 解压目录读取)
    │
    ▼  [RDEPUBTextTypesetterPipeline]
    ├─ RDEPUBHTMLNormalizer                   // 去 CR、合并空行、规范化附件标记
    ├─ RDEPUBSemanticMarkerInjector           // 注入分页语义标记 ${rd-sem-start/end}
    ├─ RDEPUBRenderDiagnosticsCollector       // 内联 <link stylesheet>、收集图片诊断
    ├─ RDEPUBStyleSheetComposer               // 构建 5 层 CSS (default/replace/dark/epub/user)
    ├─ RDEPUBFontNormalizer                   // 注册 @font-face 嵌入字体
    ├─ RDEPUBFragmentMarkerInjector           // 注入 fragment 锚点标记 ${id=xxx}
    │
    ▼  [RDEPUBDTCoreTextRenderer]
    ├─ DTHTMLAttributedStringBuilder          // HTML → NSAttributedString
    ├─ applyPaginationSemantics()             // 将语义标记转为NSAttributedString属性
    ├─ extractFragmentOffsets()               // 提取 fragment ID→offset 映射
    ├─ normalizeReadingAttributes()           // 规范化字体、行距、颜色、附件
    │
    ▼  [RDEPUBChapterPageCounter]
    ├─ CTFramesetter 创建帧
    ├─ RDEPUBPageBreakPolicy 应用语义边界规则
    │   ├─ avoidPageBreakInside               // 避免块内分页
    │   ├─ keepWithNext                       // 标题与正文不分离
    │   ├─ widow/orphan 控制                  // 孤行/寡行控制
    │   └─ pageRelate                         // 微信读书跨页关联
    ├─ RDEPUBChapterTailNormalizer            // 删除/合并空白尾页
    │
    ▼  [RDEPUBTextBookBuilder]
    └─ 组装 RDEPUBTextPage[] → RDEPUBTextChapter → RDEPUBTextBook

4. 缓存架构(三级缓存)

┌─────────────────────────────────────────────────────────┐
│  Tier 1: 内存缓存 (RDEPUBChapterRuntimeStore)            │
│  ├─ chapterDataCache: [Int: RDEPUBRuntimeChapter]       │
│  ├─ pageCountCache: [CacheKey: RDEPUBRuntimePageCount]  │
│  ├─ imageCache: NSCache<NSString, UIImage> (50 上限)    │
│  └─ 窗口驱逐:只保留当前章节 ± windowRadius 的章节       │
└──────────────────────────┬──────────────────────────────┘
                           │ miss
┌──────────────────────────▼──────────────────────────────┐
│  Tier 2: 磁盘摘要缓存 (RDEPUBChapterSummaryDiskCache)    │
│  ├─ 路径: ~/Caches/RDEPUBChapterSummaryCache/{bookID}/   │
│  ├─ 文件名: SHA256(bookID_spineIdx_renderSig_contentHash)│
│  ├─ 格式: JSON (RDEPUBChapterSummary)                    │
│  ├─ 写入: 异步serial DispatchQueue                   │
│  └─ 读取: 同步readAll 批量读取)                       │
└──────────────────────────┬──────────────────────────────┘
                           │ miss
┌──────────────────────────▼──────────────────────────────┐
│  Tier 3: 全书分页缓存 (RDEPUBTextBookCache)              │
│  ├─ 路径: ~/Caches/RDEPUBTextBookCache/                  │
│  ├─ 格式: NSSecureCoding archive                         │
│  ├─ 内容: 每章的 pageRanges + breakReasons + semanticHints│
│  └─ 失效: schemaVersion 变更时全部失效                    │
└─────────────────────────────────────────────────────────┘

缓存键设计

struct RDEPUBChapterCacheKey: Hashable {
    let bookID: String              // 书籍唯一标识
    let spineIndex: Int             // 章节索引
    let renderSignature: String     // 渲染参数签名(字体/字号/行距/布局/版本)
    let chapterContentHash: String  // 章节 HTML 的 SHA-256
}

缓存键的四元组设计确保:

  • 换字体/字号 → renderSignature 变化 → 缓存失效
  • EPUB 内容更新 → contentHash 变化 → 缓存失效
  • 不同书籍 → bookID 不同 → 互不干扰

5. ReaderController 组合架构

RDEPUBReaderController
    │
    ├─ RDEPUBReaderContext过渡门面
    │   ├─ RDEPUBReaderState
    │   │   ├─ parser / publication / readingSession
    │   │   ├─ textBook / bookPageMap / pendingFullPageMap
    │   │   ├─ activeBookmarks / activeHighlights / searchState
    │   │   └─ currentSelection / paginationToken / snapshot
    │   │
    │   ├─ RDEPUBReaderEnvironment
    │   │   ├─ viewport / safeArea / traitCollection 抽象
    │   │   ├─ brightness / fallbackViewportSize
    │   │   └─ renderStyle / layoutConfig 推导
    │   │
    │   └─ RDEPUBReaderServices
    │       ├─ parser / paginator / builder factory
    │       ├─ renderer factory
    │       └─ chapter summary disk cache factory
    │
    └─ RDEPUBReaderRuntime兼容门面
        ├─ load / pagination / location / search / chrome / annotation coordinator
        ├─ RDEPUBPresentationRuntime
        ├─ RDEPUBChapterWarmupOrchestrator
        └─ 旧 API 转发

当前 RDEPUBReaderContext 仍存在,但主要作用已经收缩为过渡门面:

  • 对外维持兼容访问面
  • 对内把纯状态、环境推导、工厂依赖拆开
  • 避免新逻辑继续把 Context 当作全能对象扩散

6. 章节按需加载与分页窗口架构

RDEPUBReaderController
    │
    ├─ RDEPUBReaderPaginationCoordinator     // 分页入口与后台元数据解析
    │   ├─ paginatePublication()
    │   ├─ RDEPUBMetadataParseWorker.start()
    │   └─ restoreBookPageMapIfPossible()
    │
    ├─ RDEPUBPresentationRuntime             // 分页状态与窗口替换
    │   ├─ applyBookPageMap()
    │   ├─ refreshBookPageMapInPlace()
    │   └─ applyPendingFullPageMapIfNeeded()
    │
    ├─ RDEPUBChapterWarmupOrchestrator       // 按需章节预热与边界预取
    │   ├─ prepareOnDemandChapter()
    │   ├─ extendPartialBookPageMapIfNeeded()
    │   ├─ prefetchForwardChaptersAfterInitialOpen()
    │   └─ ensureNavigationTargetAvailable()
    │
    ├─ RDEPUBChapterLoader                   // 章节构建与缓存门面
    │   ├─ loadChapter()                     // 异步加载(主路径)
    │   └─ loadChapterSynchronouslyForMigration()
    │
    └─ RDEPUBBookPageMap / RDEPUBPaginationState
        ├─ 当前激活窗口
        ├─ 待接管完整 page map
        └─ 来源与切换状态

这轮整改后,跨章节主路径的关键变化是:

  • 普通翻页时不再要求 UI 主线程同步等待章节构建
  • 章节边界会前移预热相邻章节与 lookahead 章节
  • bookPageMap 的 partial extension 和 full replacement 统一经过 RDEPUBPresentationRuntime
  • RDEPUBReaderRuntime 不再内联维护整套预热/扩窗实现

6. WebView 渲染架构Web 路径)

RDEPUBWebView (UIView)
    │
    ├─ WKWebView (RDEPUBAnnotationWebView)
    │   ├─ 自定义选择菜单(拷贝/高亮/批注)
    │   └─ 禁用系统手势(滚动手势由原生控制)
    │
    ├─ RDEPUBResourceURLSchemeHandler
    │   ├─ 协议: ss-reader://book/<path>
    │   ├─ 映射: URL → 本地 EPUB 解压文件
    │   └─ 容错: 缺失资源返回空响应(不 404
    │
    ├─ JavaScript Bridge (6 种消息)
    │   ├─ ssReaderProgressionChanged    // 阅读进度更新
    │   ├─ ssReaderSelectionChanged      // 文本选区变化
    │   ├─ ssReaderInternalLink          // EPUB 内部链接
    │   ├─ ssReaderExternalLink          // 外部链接
    │   ├─ ssReaderJSError               // JS 运行时错误
    │   └─ ssReaderFixedLayoutReady      // 固定布局加载完成
    │
    └─ 注入脚本
        ├─ epub-bridge.js (502 行)       // 核心桥接,分页/滚动/选区/高亮
        ├─ cssInjector.js (45 行)        // CSS 注入管理
        ├─ WeReadApi.js (67 行)          // 微信读书 API 兼容层
        ├─ rangy-core.js / rangy-serializer.js  // DOM Range 序列化
        └─ CSS: default/replace/dark/latin      // 4 套样式表

7. 翻页容器架构RDEpubReaderView

RDEpubReaderView (UIView)
    │
    ├─ 三种翻页模式:
    │   ├─ .pageCurl        → UIPageViewController (翻页动画)
    │   ├─ .horizontalScroll → UICollectionView (水平滑动)
    │   └─ .verticalScroll   → UICollectionView (垂直滚动)
    │
    ├─ 组合对象:
    │   ├─ RDEpubReaderPagingController      // 翻页状态管理、请求队列
    │   ├─ RDEpubReaderPreloadController     // 页面预加载、缓存管理
    │   ├─ RDEpubReaderSpreadResolver        // 双页展开计算
    │   └─ RDEpubReaderTapRegionHandler      // 点击区域分类(左/中/右)
    │
    ├─ 数据源协议:
    │   ├─ RDEpubReaderPageProvider (新)     // 格式无关,优先级高
    │   └─ RDEpubReaderDataSource (旧)      // 遗留兼容,通过 Adapter 适配
    │
    └─ 手势流:
        点击 → TapRegionHandler → 分类(左/中/右)
            ├─ 左 → goPreviousPage()
            ├─ 右 → goNextPage()
            └─ 中 → tapCenter() (切换工具栏)

8. 配置与设置

RDEPUBReaderConfiguration

struct RDEPUBReaderConfiguration {
    var fontSize: CGFloat                    // 默认 16
    var fontChoice: FontChoice              // 系统/宋体/楷体
    var lineHeightMultiple: CGFloat          // 默认 1.5
    var numberOfColumns: Int                 // 1 或 2
    var columnGap: CGFloat                   // 默认 20
    var theme: ReaderTheme                  // 6 种主题
    var displayType: RDEpubReaderView.DisplayType // pageCurl/horizontal/vertical
    var onDemandChapterWindowSize: Int       // 默认 3奇数最小 3最大 15
    var metadataParsingConcurrency: Int      // 默认 CPU 核心数
    var chapterWindowRadius: Int             // 内存缓存窗口半径
}

持久化

数据 存储方式 Key 前缀
阅读位置 UserDefaults ssreader.epub.location.{bookID}
书签 UserDefaults ssreader.epub.bookmarks.{bookID}
高亮标注 UserDefaults ssreader.epub.highlights.{bookID}
全局设置 UserDefaults ssreader.epub.settings
章节摘要 磁盘文件 ~/Caches/RDEPUBChapterSummaryCache/
全书分页 磁盘文件 ~/Caches/RDEPUBTextBookCache/

9. 目录结构

Sources/RDEpubReaderView/
├── EPUBCore/                          # EPUB 解析与 WebView 渲染
│   ├── Models/                        # 数据模型
│   │   ├── RDEPUBAnnotationModels.swift
│   │   ├── RDEPUBPaginationModels.swift
│   │   └── RDEPUBReadingLocationModels.swift
│   ├── Resources/                     # JS/CSS/HTML 静态资源
│   │   ├── epub-bridge.js
│   │   ├── cssInjector.js
│   │   ├── WeReadApi.js
│   │   ├── rangy-core.js / rangy-serializer.js
│   │   ├── wxread-default.css / wxread-dark.css / wxread-replace-latin.css
│   │   └── epub-fixed-layout.html
│   ├── RDEPUBParser.swift             # 核心解析器
│   ├── RDEPUBParser+Archive.swift     # ZIP 解压
│   ├── RDEPUBParser+Package.swift     # OPF 解析
│   ├── RDEPUBParser+TOC.swift         # 目录解析
│   ├── RDEPUBParser+Resources.swift   # 资源访问
│   ├── RDEPUBPublication.swift        # 出版物门面
│   ├── RDEPUBResourceResolver.swift   # URL 解析
│   ├── RDEPUBReadingSession.swift     # 阅读会话状态机
│   ├── RDEPUBWebView.swift            # WebView 主类
│   ├── RDEPUBWebView+*.swift          # WebView 扩展(配置/重排/固定/搜索/JS桥接
│   ├── RDEPUBPaginator.swift          # 离屏分页计算器
│   ├── RDEPUBSearchEngine.swift       # 全文搜索引擎
│   └── ...
│
├── EPUBTextRendering/                 # 文本渲染引擎
│   ├── Typesetter/                    # 排版管线
│   │   ├── RDEPUBTypesettingPipeline.swift
│   │   ├── RDEPUBHTMLNormalizer.swift
│   │   ├── RDEPUBSemanticMarkerInjector.swift
│   │   ├── RDEPUBFragmentMarkerInjector.swift
│   │   ├── RDEPUBFontNormalizer.swift
│   │   ├── RDEPUBAttachmentNormalizer.swift
│   │   ├── RDEPUBStyleSheetComposer.swift
│   │   ├── RDEPUBRenderDiagnosticsCollector.swift
│   │   └── RDEPUBTextRendererSupport.swift
│   ├── Pagination/                    # 分页引擎
│   │   ├── RDEPUBChapterPageCounter.swift
│   │   ├── RDEPUBCoreTextPageFrameFactory.swift
│   │   ├── RDEPUBPageBreakPolicy.swift
│   │   ├── RDEPUBTextLayoutFrame.swift
│   │   └── ...
│   ├── BuildPipeline/                 # 全书构建
│   │   ├── RDEPUBTextBookBuilder.swift
│   │   ├── RDEPUBTextBookModels.swift
│   │   ├── RDEPUBTextBookCache.swift
│   │   ├── RDEPUBChapterTailNormalizer.swift
│   │   └── ...
│   ├── RDEPUBTextRenderer.swift       # 渲染器协议与类型定义
│   ├── RDEPUBDTCoreTextRenderer.swift # DTCoreText 渲染器实现
│   ├── RDEPUBChapterData.swift        # 章节查询门面
│   ├── RDEPUBTextIndexTable.swift     # 全书索引表
│   └── RDEpubPlainTextBookBuilder.swift   # 纯文本 (.txt) 构建器
│
├── ReaderView/                        # 通用翻页容器
│   ├── Paging/                        # 翻页子系统
│   │   ├── RDEpubReaderPagingController.swift
│   │   ├── RDEpubReaderPreloadController.swift
│   │   ├── RDEpubReaderSpreadResolver.swift
│   │   └── RDEpubReaderTapRegionHandler.swift
│   ├── RDEpubReaderView.swift             # 主容器视图
│   ├── RDEpubReaderView+*.swift           # 扩展CollectionView/PageCurl/ToolView/ContentAccess
│   ├── RDEpubReaderFlowLayout.swift       # 自定义 CollectionView 布局
│   ├── RDEpubReaderContentCell.swift      # 滚动模式 Cell
│   └── RDEpubReaderPageChildViewController.swift  // 翻页模式子 VC
│
└── EPUBUI/                            # 阅读器 UI
    ├── ReaderController/              # 控制器与协调器
    │   ├── ChapterRuntime/            # 章节运行时
    │   │   ├── RDEPUBChapterLoader.swift
    │   │   ├── RDEPUBChapterRuntimeStore.swift
    │   │   ├── RDEPUBChapterSummaryDiskCache.swift
    │   │   ├── RDEPUBBookPageMap.swift
    │   │   ├── RDEPUBPageResolver.swift
    │   │   └── ...
    │   ├── RDEPUBReaderContext.swift           // 共享状态中心
    │   ├── RDEPUBReaderRuntime.swift           // 运行时协调器Facade
    │   ├── RDEPUBReaderDependencies.swift     // 依赖注入
    │   ├── RDEPUBReaderLoadCoordinator.swift  // 加载协调器
    │   ├── RDEPUBReaderPaginationCoordinator.swift  // 分页协调器
    │   ├── RDEPUBReaderLocationCoordinator.swift    // 位置协调器
    │   ├── RDEPUBReaderSearchCoordinator.swift      // 搜索协调器
    │   ├── RDEPUBReaderChromeCoordinator.swift      // 工具栏协调器
    │   ├── RDEPUBReaderAnnotationCoordinator.swift  // 标注协调器
    │   ├── RDEPUBReaderAssemblyCoordinator.swift    // 组装协调器
    │   ├── RDEPUBReaderViewportMonitor.swift        // 视口监控
    │   └── ...
    ├── Settings/                      # 设置面板
    │   ├── RDEPUBReaderConfiguration.swift    # 配置模型
    │   ├── RDEPUBReaderSettings.swift         # 持久化设置
    │   ├── RDEPUBReaderSettingsViewController.swift  # 设置面板 VC
    │   ├── RDEPUBReaderTheme.swift            # 主题定义
    │   └── ...
    ├── TextPage/                      # 文本页面渲染
    │   ├── RDEPUBTextContentView.swift        # 文本内容视图CoreText
    │   ├── RDEPUBTextSelectionController.swift # 文本选择控制器
    │   ├── RDEPUBPageInteractionController.swift # 点击交互控制器
    │   ├── RDEPUBSelectionOverlayView.swift   # 选区覆盖层
    │   ├── RDEPUBTextAnnotationOverlay.swift  # 标注覆盖层
    │   ├── RDEPUBTextPageRenderView.swift     # CoreText 绘制视图
    │   └── ...
    ├── RDEPUBReaderController.swift   # 主控制器(+ContentDelegates/DataSource/PublicAPI 等扩展)
    ├── RDEPUBReaderDelegate.swift     # 公开委托协议
    ├── RDEPUBReaderPersistence.swift  # 持久化协议
    └── ...

10. 关键设计模式

模式 应用场景
Coordinator 分页/标注/搜索/导航各一个协调器,解耦 Controller
Facade RDEPUBPublication 封装 RDEPUBParserRDEPUBChapterData 封装章节查询
Builder RDEPUBBookPageMap.Builder 增量构建页码映射
Strategy RDEPUBTextRenderer 协议,可替换渲染器实现
Pipeline RDEPUBTextTypesetterPipeline 排版管线8 个逻辑阶段,封装为 5-6 个顶层调用)
Adapter RDEpubReaderLegacyDataSourceAdapter 适配旧数据源协议
三级缓存 内存 → 磁盘摘要 → 全书分页,逐级降级
Token 取消 paginationToken 确保过期异步任务不干扰新任务
Frozen Parameters 后台任务冻结 renderSignature,避免运行中参数漂移