zhixi-document-runtime/docs/pdf-strategy.md
wangdl bae6ef5726 feat: M3 completion — event buffer, FFI search/anchor, PDF strategy, quality fixes
Rust Core:
- events: global Mutex-buffered event queue (push/export/clear/update_position)
- image_meta: use ImageReader::format() for real decoded format instead of extension
- search: change match_start/match_end usize→u64 for FFI compatibility
- epub/pdf: module-level placeholder comments

FFI (UDL exposed, 12 total functions):
- Added: search_markdown_blocks, search_text_content, create_note_anchor
- Added: push_reading_event, update_reading_position, export_pending_events,
  clear_exported_events

Docs:
- README: synced DocumentBlock model (Table.headers + HorizontalRule),
  simplified dependency recommendations, removed nonexistent doc references
- docs/pdf-strategy.md: PDFKit vs PDFium vs MuPDF evaluation, 5 decisions,
  platform strategy matrix, roadmap

Build:
- .cargo/config.toml: cargo xtask alias
- xtask: CLI implementation (test/build-ios/fixtures commands)
- fixtures: markdown/sample.md (9 block types), text/sample.txt
- XCFramework rebuilt, Swift bindings regenerated (1977 lines)

58 tests pass, zero warnings.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 21:23:26 +08:00

5.7 KiB
Raw Permalink Blame History

PDF 阅读方案评估

概述

PDF 是知习支持的核心文件格式之一。本文档明确 PDF 在各平台的处理策略、技术选型边界和后续路线图。

核心结论

  1. iOS 第一版继续使用 PDFKit / QuickLook — 系统内置,无需额外依赖
  2. Rust 暂不接入 PDFium — 增加包体但不创造足够价值
  3. 文本选择由平台能力承担 — PDFKitiOS、PdfRendererAndroid
  4. PDF 搜索后置 — 待文本提取方案确定后再做
  5. 扫描 PDF / OCR 暂缓 — 明确不在第一版范围

方案对比

候选方案

方案 二进制大小 平台支持 文本提取 搜索 标注 成熟度
QuickLook (iOS/macOS) 0系统内置 Apple only
PDFKit (iOS/macOS) 0系统内置 Apple only
Android PdfRenderer 0系统内置 Android only 部分
pdfium-render (Rust) ~15MB/平台 全平台 可自建
MuPDF (C) ~8MB/平台 全平台 可自建 部分

评估维度

维度 QuickLook (iOS) PDFKit (iOS) pdfium-render (Rust)
集成成本 极低QLPreviewController 低(原生 API 交叉编译、binding
包体影响 0 0 ~15MB × 平台数
页面渲染 (需要 bitmap pipeline
文本提取
文本选择 (只能看不选) 需自建 UI
搜索 可自建
阅读位置 App 侧维护 App 侧 + delegate Rust 侧统一
统一数据模型
跨平台复用

各平台策略

iOS / macOS

当前M3-M4PDFKit

MaterialReaderView
  → PreviewMode.platformPreview
  → QuickLook sheet (QLPreviewController)
  → App 侧监听页码变化
  → 生成 ReadingPosition::Pdf { pageNumber, pageProgress, overallProgress }
  → pushReadingEvent

优势:

  • 零依赖,系统自带
  • 渲染质量高
  • 支持系统级文本选择、搜索
  • 用户熟悉的交互

局限:

  • QuickLook 不暴露页码变化回调(需要 PDFKit 的 PDFView 才能精确跟踪)
  • 无法提取文本传给 Rust 做统一搜索
  • App 侧需用 PDFView delegate 替代 QLPreviewController 以获得页码回调

后续增强:如果需要文本提取/搜索,把 QuickLook sheet 替换为 PDFView + PDFDocument通过 PDFDocument.string 提取全文传给 Rust search_text

Android

当前策略:系统预览 / 外部 App

Android 有 PdfRendererAPI 21+),可渲染页面为 Bitmap。但第一版不做内置 PDF 阅读器。

MaterialReaderView (Android)
  → PreviewMode.platformPreview
  → Intent.ACTION_VIEW + content:// URI
  → 系统 PDF 阅读器 / Chrome
  → 回到 App 后手动记录阅读时长

后续可选:PdfRenderer + RecyclerView 自建阅读器,用 Rust ReadingPosition::Pdf 统一位置模型。

鸿蒙 / Windows / Web

均优先走系统预览或浏览器内置 PDF 阅读器。Rust 只统一 ReadingPosition::Pdf 模型。


阅读位置模型

Rust 已定义统一的 ReadingPosition::Pdf

ReadingPosition::Pdf {
    page_number: u32,        // 1-based 页码
    page_progress: f32,      // 0.0 ~ 1.0,该页内滚动比例
    overall_progress: f32,   // 0.0 ~ 1.0,全书进度
}

App 侧职责:

  • iOSPDFView.pageChange delegate → 更新位置
  • Android监听页面变化 → 更新位置
  • 所有平台:用同一套 ReadingPosition::Pdf 模型,不重复造轮子

Rust 侧职责边界

当前M3-M4

  • MaterialType::Pdf — 文件类型识别
  • ReadingPosition::Pdf — 统一位置模型
  • PreviewMode::PlatformPreview — 预览模式映射
  • pdf.rs — 模块占位(注释说明走平台预览)

不做的

  • 不集成 PDFium
  • 不做 PDF 渲染bitmap 生成)
  • 不做 PDF 文本提取
  • 不做 PDF 标注
  • 不做 OCR

后续评估M5+

如果以下条件满足 3 项以上,重新评估 PDFium 集成:

  1. Android 需要内置 PDF 阅读器
  2. 搜索需要在 PDF 中定位
  3. 需要跨平台统一的文本提取
  4. 用户量大到平台差异成为维护负担
  5. PDFium 交叉编译经验积累充分

搜索策略

阶段 方案 能力
M3-M4 不搜索 PDF 用户在平台预览器中手动使用系统搜索
M5+ 平台提取 + Rust 搜索 PDFKit.string / PdfRenderer → 传给 Rust search_text
远期 PDFium 提取 + Tantivy 全文索引,支持 PDF 内定位

扫描 PDF / OCR

明确不进入知习范围。理由:

  • OCR 是独立技术领域,与"阅读内核"定位不符
  • 高精度 OCR 需要专门模型Tesseract / Apple Vision / ML Kit
  • 绝大多数学习资料是原生电子文档,非扫描件
  • 扫描件场景可由用户自行 OCR 后导入

后续路线图

M3 ✅ — QuickLook sheet + ReadingPosition::Pdf
M4  ● — pdf-strategy.md本文档
M5  ○ — iOS 迁移至 PDFView获得文本提取和页码回调
      — Rust 接收 PDF 全文做 search_text
M6+ ○ — 评估 PDFiumAndroid 自建阅读器需求驱动)
      — 如集成 PDFium文本提取 + bitmap 渲染 + 搜索定位

验收确认

  • iOS 第一版继续使用 PDFKit / QuickLook
  • Rust 暂不接 PDFium
  • PDF 文本选择由平台能力承担
  • PDF 搜索后置
  • 扫描 PDF / OCR 暂缓
  • 文档存在,方案决策明确,有后续路线图