refactor: 添加中文注释 + 优化模块结构

- 给全部 78 个 Swift 源文件添加详细的中文注释(文件级、类级、方法级)
- 删除 LegacyRDReaderController/ 死代码目录(16 文件 4592 行)
- 根目录翻页容器文件移入 ReaderView/ 目录
- Resources/ 移入 EPUBCore/Resources/(与使用者归属一致)
- RDEPUBTextIndexTable.swift 移入 EPUBTextRendering/(消除反向依赖)
- RDURLReaderController.swift 移入 EPUBUI/(入口控制器归入 UI 层)
- 更新 podspec 资源路径
This commit is contained in:
shen
2026-05-25 10:19:14 +08:00
parent 5af90c1148
commit 54798ba578
88 changed files with 2492 additions and 4469 deletions
@@ -1,7 +1,14 @@
import UIKit
/// 访便
///
/// `RDEPUBTextChapter` `indexTable`
/// fragment API
/// `RDEPUBTextBook.chapterData(for:)` `chapterData(atChapterIndex:)`
public final class RDEPUBChapterData {
///
public let chapter: RDEPUBTextChapter
/// fileIndex/row/column
public let indexTable: RDEPUBTextIndexTable
public init(chapter: RDEPUBTextChapter, indexTable: RDEPUBTextIndexTable) {
@@ -9,36 +16,61 @@ public final class RDEPUBChapterData {
self.indexTable = indexTable
}
// MARK: - 便 chapter
///
public var chapterIndex: Int { chapter.chapterIndex }
/// spine
public var spineIndex: Int { chapter.spineIndex }
/// "OEBPS/chapter1.xhtml"
public var href: String { chapter.href }
///
public var title: String { chapter.title }
///
public var attributedContent: NSAttributedString { chapter.attributedContent }
///
public var pages: [RDEPUBTextPage] { chapter.pages }
/// fragment ID
public var fragmentOffsets: [String: Int] { chapter.fragmentOffsets }
// MARK: -
///
/// - Parameter absoluteOffset:
/// - Returns: nil
public func page(containing absoluteOffset: Int) -> RDEPUBTextPage? {
chapter.pages.first { NSLocationInRange(absoluteOffset, $0.contentRange) }
}
/// 0
public func pageNumber(containing absoluteOffset: Int) -> Int? {
page(containing: absoluteOffset)?.absolutePageIndex
}
///
public func page(atAbsolutePageIndex absolutePageIndex: Int) -> RDEPUBTextPage? {
chapter.pages.first { $0.absolutePageIndex == absolutePageIndex }
}
// MARK: -
/// fileIndex/row/column
public func anchor(forAbsoluteIndex index: Int) -> RDEPUBTextAnchor {
indexTable.anchor(forAbsoluteIndex: index, in: chapter)
}
///
public func rangeAnchor(for absoluteRange: NSRange) -> RDEPUBTextRangeAnchor {
let start = anchor(forAbsoluteIndex: absoluteRange.location)
let end = anchor(forAbsoluteIndex: absoluteRange.location + absoluteRange.length)
return RDEPUBTextRangeAnchor(start: start, end: end)
}
/// /
/// - Parameters:
/// - absoluteRange:
/// - bookIdentifier:
/// - Returns: nil
public func selection(from absoluteRange: NSRange, bookIdentifier: String?) -> RDEPUBSelection? {
guard page(containing: absoluteRange.location) != nil else { return nil }
let location = self.location(for: absoluteRange, bookIdentifier: bookIdentifier)
@@ -56,6 +88,7 @@ public final class RDEPUBChapterData {
)
}
/// RDEPUBLocation
public func location(for absoluteRange: NSRange, bookIdentifier: String?) -> RDEPUBLocation {
indexTable.location(
for: rangeAnchor(for: absoluteRange),
@@ -64,10 +97,19 @@ public final class RDEPUBChapterData {
)
}
/// RDEPUBLocation
public func location(forPage page: RDEPUBTextPage, bookIdentifier: String?) -> RDEPUBLocation {
location(for: page.contentRange, bookIdentifier: bookIdentifier)
}
// MARK: - Location
///
///
///
/// 1. rangeAnchor
/// 2. fragment ID
/// 3. navigationProgression退
public func absoluteRange(for location: RDEPUBLocation) -> NSRange? {
if let rangeAnchor = location.rangeAnchor {
return indexTable.absoluteRange(for: rangeAnchor)
@@ -83,6 +125,7 @@ public final class RDEPUBChapterData {
return NSRange(location: offset, length: 1)
}
///
public func absoluteRange(for highlight: RDEPUBHighlight) -> NSRange? {
if let rangeAnchor = highlight.location.rangeAnchor {
return indexTable.absoluteRange(for: rangeAnchor)
@@ -90,6 +133,7 @@ public final class RDEPUBChapterData {
return RDEPUBTextOffsetRangeInfo.decode(from: highlight.rangeInfo)?.nsRange
}
///
public func absoluteRange(for searchMatch: RDEPUBSearchMatch) -> NSRange? {
if let rangeAnchor = searchMatch.rangeAnchor {
return indexTable.absoluteRange(for: rangeAnchor)
@@ -100,6 +144,9 @@ public final class RDEPUBChapterData {
return nil
}
// MARK: - /
///
public func highlights(on page: RDEPUBTextPage, from allHighlights: [RDEPUBHighlight]) -> [RDEPUBHighlight] {
let pageRange = absoluteOffsetRange(for: page)
return allHighlights.filter { highlight in
@@ -114,6 +161,7 @@ public final class RDEPUBChapterData {
}
}
///
public func searchMatches(on page: RDEPUBTextPage, from matches: [RDEPUBSearchMatch]) -> [RDEPUBSearchMatch] {
let pageRange = absoluteOffsetRange(for: page)
return matches.filter { match in
@@ -125,6 +173,7 @@ public final class RDEPUBChapterData {
}
}
/// 1
public func pageNumber(for location: RDEPUBLocation) -> Int? {
if let range = absoluteRange(for: location) {
return pageNumber(containing: range.location).map { $0 + 1 }
@@ -132,12 +181,16 @@ public final class RDEPUBChapterData {
return nil
}
// MARK: -
/// [start, end+1)
private func absoluteOffsetRange(for page: RDEPUBTextPage) -> Range<Int> {
let lowerBound = page.pageStartOffset
let upperBound = page.pageEndOffset + 1
return lowerBound..<max(upperBound, lowerBound)
}
/// 退 chapterOffset
private func absoluteOffset(for anchor: RDEPUBTextAnchor) -> Int {
indexTable.absoluteIndex(
fileIndex: anchor.fileIndex,