Files
ReadViewSDK/Sources/RDReaderView/EPUBUI/RDEPUBReaderController+RenderSupport.swift
T
shenandshen 948004eed1 docs: 补充注释、修正过时文档、清理重复内容
源码注释:
- 为 ~60 个 Swift 文件补充缺失的 doc comment(file header、类型、属性、方法)
- 修正 4 处错误注释:翻页模式数量、搜索行为描述、手势识别器描述、悬空文档块

文档维护:
- 删除重复文档:WXRead/读书EPUB阅读器实现架构.md(与微信读书版完全一致)
- 合并重叠文档:阅读器规划.md → 阅读器功能开发计划.md(单一真值)
- 修正过时内容:所有文档中"四种翻页模式"→"三种",移除 horizontalCoverScroll
- 更新架构图:补齐 EPUBUI/ReaderController、Paging/、Typesetter/ 等子目录
- 更新 index.md 索引:新增开发计划和架构对比文档引用
2026-06-01 09:33:23 +08:00

101 lines
4.3 KiB
Swift

// RDEPUBReaderController+RenderSupport.swift
// EPUB 阅读器渲染支持辅助方法
// 提供获取当前布局上下文、偏好设置、页面尺寸、渲染样式、文本布局配置,
// 以及构建渲染请求、管理分页宿主视图和回退位置查询等功能。
import UIKit
/// RDEPUBReaderController 渲染支持扩展
///
/// 本文件提供阅读器渲染所需的辅助方法,包括获取当前布局上下文、偏好设置、页面尺寸、
/// 渲染样式、文本布局配置,以及构建渲染请求和回退位置查询等功能。
extension RDEPUBReaderController {
/// 获取当前导航器布局上下文(视口尺寸、方向等)
func currentLayoutContext() -> RDEPUBNavigatorLayoutContext {
readerContext.currentLayoutContext()
}
/// 获取当前阅读偏好设置
func currentPreferences() -> RDEPUBPreferences {
readerContext.currentPreferences()
}
/// 获取当前文本页面尺寸
func currentTextPageSize() -> CGSize {
readerContext.currentTextPageSize()
}
/// 获取当前文本渲染样式(字体、行高等)
func currentTextRenderStyle() -> RDEPUBTextRenderStyle {
readerContext.currentTextRenderStyle()
}
/// 获取指定页面尺寸下的文本布局配置
func currentTextLayoutConfig(pageSize: CGSize) -> RDEPUBTextLayoutConfig {
readerContext.currentTextLayoutConfig(pageSize: pageSize)
}
/// 获取已解析的文本渲染器实例
func resolvedTextRenderer() -> RDEPUBTextRenderer {
readerContext.resolvedTextRenderer()
}
/// 确保分页宿主视图已添加到视图层级(位于屏幕外用于预计算分页)
func ensurePaginationHostView() -> UIView {
let viewportSize = currentLayoutContext().viewportSize
let hostFrame = CGRect(x: -viewportSize.width - 32, y: 0, width: viewportSize.width, height: viewportSize.height)
if paginationHostView.superview == nil {
view.addSubview(paginationHostView)
view.sendSubviewToBack(paginationHostView)
}
paginationHostView.frame = hostFrame
return paginationHostView
}
/// 为指定页面索引构建渲染请求(含位置、高亮、搜索状态)
func request(for pageIndex: Int) -> RDEPUBRenderRequest? {
guard let publication, activePages.indices.contains(pageIndex) else {
return nil
}
let page = activePages[pageIndex]
let pendingLocation = readingSession?.pendingLocation(forPageNumber: pageIndex + 1, spineIndex: page.spineIndex)
return currentPreferences().renderRequest(
for: page,
publication: publication,
viewportSize: currentLayoutContext().viewportSize,
targetLocation: pendingLocation,
highlights: highlights(for: page),
searchPresentation: searchPresentation(for: page)
)
}
/// 获取指定页面索引的回退位置(当无法确定精确位置时使用)
func fallbackLocation(for pageIndex: Int) -> RDEPUBLocation? {
guard activePages.indices.contains(pageIndex) else { return nil }
return readingSession?.fallbackLocation(for: activePages[pageIndex], bookIdentifier: currentBookIdentifier)
}
/// 获取指定固定布局页面上的高亮标注列表
private func highlights(for page: EPUBPage) -> [RDEPUBHighlight] {
guard let publication else { return [] }
if let spread = page.fixedSpread {
let hrefs = Set(spread.resources.compactMap { publication.resourceResolver.normalizedHref($0.href) })
return activeHighlights.filter { highlight in
guard let normalizedHref = publication.resourceResolver.normalizedHref(highlight.location.href) else {
return false
}
return hrefs.contains(normalizedHref)
}
}
guard publication.spine.indices.contains(page.spineIndex) else { return [] }
let href = publication.spine[page.spineIndex].href
let normalizedHref = publication.resourceResolver.normalizedHref(href)
return activeHighlights.filter { highlight in
publication.resourceResolver.normalizedHref(highlight.location.href) == normalizedHref
}
}
}