refactor(reader): 重构高亮选区绘制架构,对齐 WXRead 实现方案

- 移除 RDEPUBSelectableTextView,改用原生 UITextView
- 新增 NSAttributedString 自定义属性(com.rdreader.highlight/underline)注入高亮
- RDEPUBTextPageRenderView 统一绘制高亮背景、文字和选区
- RDEPUBTextSelectionController 精简,选区矩形传递给 RenderView 绘制
- 新增高亮选区复刻 WXRead 实现方案文档
- UI 测试适配新架构

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-06-01 20:57:27 +08:00
co-authored by Claude Opus 4.7
parent 948004eed1
commit 70133e4e6e
13 changed files with 801 additions and 510 deletions
@@ -297,6 +297,33 @@ public final class RDEPUBChapterData {
tableOfContentsItems(from: items, normalizer: normalizer).first
}
// MARK: - WXRead WRChapterData.addHighlightInRange:key:itemId:color:
/// /线 NSAttributedString
/// CoreText WXRead com.weread.highlight / com.weread.underline
public func applyHighlights(
to content: NSMutableAttributedString,
page: RDEPUBTextPage,
highlights: [RDEPUBHighlight]
) {
for highlight in highlights {
guard highlight.location.href == chapter.href else { continue }
guard let range = absoluteRange(for: highlight) else { continue }
let overlap = NSIntersectionRange(range, page.contentRange)
guard overlap.length > 0 else { continue }
let relativeRange = NSRange(location: overlap.location - page.pageStartOffset, length: overlap.length)
guard relativeRange.location >= 0,
relativeRange.location + relativeRange.length <= content.length else { continue }
switch highlight.style {
case .highlight:
content.addAttribute(kRDEPUBHighlightAttributeName, value: highlight.uiColor, range: relativeRange)
case .underline:
content.addAttribute(kRDEPUBUnderlineAttributeName, value: highlight.uiColor, range: relativeRange)
}
}
}
// MARK: -
/// [start, end+1)