- 新增字体选择(系统/宋体/圆体/等宽)与暗色图片柔化配置 - 文本选择改为自定义手势+操作栏(拷贝/高亮/批注) - 添加 accessibilityIdentifier 支持自动化 UI 测试 - 新增 UITests 覆盖阅读器打开/关闭、工具栏、设置面板、批注等 - 添加 Demo 测试用 EPUB 书源(宝山辽墓材料与释读) - 新增文档:UI 自动化测试、功能开发计划、阅读器规划
196 lines
7.9 KiB
Swift
196 lines
7.9 KiB
Swift
import UIKit
|
||
|
||
// MARK: - 文本渲染引擎
|
||
|
||
/// EPUB 文本渲染引擎枚举
|
||
/// 定义了当前支持的文本渲染方式,未来可扩展为多引擎选择
|
||
public enum RDEPUBTextRenderingEngine: Equatable {
|
||
/// 基于 DTCoreText 的渲染引擎,将 HTML/CSS 转换为 NSAttributedString
|
||
case dtCoreText
|
||
}
|
||
|
||
// MARK: - 阅读字体
|
||
|
||
/// 阅读器内置字体选项。
|
||
/// 第一版优先使用系统授权字体,后续可扩展为 bundle 内置字体注册。
|
||
public enum RDEPUBReaderFontChoice: String, Codable, CaseIterable, Equatable {
|
||
/// 系统默认无衬线字体
|
||
case system
|
||
/// 系统衬线字体
|
||
case serif
|
||
/// 系统圆体字体
|
||
case rounded
|
||
/// 系统等宽字体
|
||
case monospaced
|
||
|
||
public var displayName: String {
|
||
switch self {
|
||
case .system:
|
||
return "系统"
|
||
case .serif:
|
||
return "宋体"
|
||
case .rounded:
|
||
return "圆体"
|
||
case .monospaced:
|
||
return "等宽"
|
||
}
|
||
}
|
||
|
||
public func font(ofSize size: CGFloat) -> UIFont {
|
||
switch self {
|
||
case .system:
|
||
return UIFont.systemFont(ofSize: size)
|
||
case .serif:
|
||
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
|
||
.withDesign(.serif) ?? UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
|
||
return UIFont(descriptor: descriptor, size: size)
|
||
case .rounded:
|
||
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
|
||
.withDesign(.rounded) ?? UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
|
||
return UIFont(descriptor: descriptor, size: size)
|
||
case .monospaced:
|
||
return UIFont.monospacedSystemFont(ofSize: size, weight: .regular)
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - 阅读器配置
|
||
|
||
/// EPUB 阅读器的完整配置结构体
|
||
/// 作为 EPUBUI 层的入口配置,控制阅读器的外观、行为和功能开关
|
||
/// 调用方在创建 RDEPUBReaderController 前可自定义此配置
|
||
public struct RDEPUBReaderConfiguration: Equatable {
|
||
// MARK: 阅读排版参数
|
||
|
||
/// 正文字号(单位:pt),默认 15
|
||
public var fontSize: CGFloat
|
||
/// 行距倍数,默认 1.6(即行距为字号的 1.6 倍)
|
||
public var lineHeightMultiple: CGFloat
|
||
/// 正文字体,默认系统字体
|
||
public var fontChoice: RDEPUBReaderFontChoice
|
||
/// 栏数,默认单栏
|
||
public var numberOfColumns: Int
|
||
/// 栏间距,默认 20pt
|
||
public var columnGap: CGFloat
|
||
/// 翻页显示模式:.pageCurl(仿真翻页)或 .scroll(滚动阅读)
|
||
public var displayType: RDReaderView.DisplayType
|
||
/// 横屏时是否启用双页显示,默认开启
|
||
public var landscapeDualPageEnabled: Bool
|
||
|
||
// MARK: UI 功能开关
|
||
|
||
/// 是否显示目录入口,默认开启
|
||
public var showsTableOfContents: Bool
|
||
/// 是否允许文本高亮功能,默认开启
|
||
public var allowsHighlights: Bool
|
||
/// 是否显示设置面板入口,默认开启
|
||
public var showsSettingsPanel: Bool
|
||
|
||
// MARK: 内容内边距
|
||
|
||
/// 流式排版(reflowable)内容的内边距,上下 40pt、左右 16pt
|
||
public var reflowableContentInsets: UIEdgeInsets
|
||
/// 固定布局(fixed layout)内容的内边距,默认为零
|
||
public var fixedContentInset: UIEdgeInsets
|
||
|
||
// MARK: 主题与布局
|
||
|
||
/// 当前阅读主题(浅色/深色/护眼等),默认 .light
|
||
public var theme: RDEPUBReaderTheme
|
||
/// 暗色主题下是否柔化正文图片,降低夜间阅读刺眼感
|
||
public var darkImageAdjustmentEnabled: Bool
|
||
/// 暗色主题图片柔化混合比例,0 表示不处理,推荐 0.12 ~ 0.2
|
||
public var darkImageBlendRatio: CGFloat
|
||
/// 固定布局的适配模式:按页适配或按宽度适配
|
||
public var fixedLayoutFit: RDEPUBFixedLayoutFit
|
||
/// 固定布局的跨页模式:自动/单页/双页
|
||
public var fixedLayoutSpreadMode: RDEPUBFixedLayoutSpreadMode
|
||
/// 文本渲染引擎,默认使用 DTCoreText
|
||
public var textRenderingEngine: RDEPUBTextRenderingEngine
|
||
|
||
// MARK: 初始化
|
||
|
||
/// 创建阅读器配置,所有参数均提供合理的默认值
|
||
/// - Parameters:
|
||
/// - fontSize: 正文字号,默认 15pt
|
||
/// - lineHeightMultiple: 行距倍数,默认 1.6
|
||
/// - fontChoice: 正文字体,默认系统字体
|
||
/// - displayType: 翻页模式,默认 .pageCurl
|
||
/// - landscapeDualPageEnabled: 横屏双页,默认 true
|
||
/// - showsTableOfContents: 显示目录入口,默认 true
|
||
/// - allowsHighlights: 允许高亮,默认 true
|
||
/// - showsSettingsPanel: 显示设置面板,默认 true
|
||
/// - reflowableContentInsets: 流式排版内边距
|
||
/// - fixedContentInset: 固定布局内边距
|
||
/// - theme: 阅读主题,默认 .light
|
||
/// - darkImageAdjustmentEnabled: 暗色主题下是否柔化正文图片
|
||
/// - darkImageBlendRatio: 暗色主题图片柔化混合比例
|
||
/// - fixedLayoutFit: 固定布局适配模式
|
||
/// - fixedLayoutSpreadMode: 固定布局跨页模式
|
||
/// - textRenderingEngine: 文本渲染引擎
|
||
public init(
|
||
fontSize: CGFloat = 15,
|
||
lineHeightMultiple: CGFloat = 1.6,
|
||
fontChoice: RDEPUBReaderFontChoice = .system,
|
||
numberOfColumns: Int = 1,
|
||
columnGap: CGFloat = 20,
|
||
displayType: RDReaderView.DisplayType = .pageCurl,
|
||
landscapeDualPageEnabled: Bool = true,
|
||
showsTableOfContents: Bool = true,
|
||
allowsHighlights: Bool = true,
|
||
showsSettingsPanel: Bool = true,
|
||
reflowableContentInsets: UIEdgeInsets = UIEdgeInsets(top: 40, left: 16, bottom: 40, right: 16),
|
||
fixedContentInset: UIEdgeInsets = .zero,
|
||
theme: RDEPUBReaderTheme = .light,
|
||
darkImageAdjustmentEnabled: Bool = true,
|
||
darkImageBlendRatio: CGFloat = 0.15,
|
||
fixedLayoutFit: RDEPUBFixedLayoutFit = .page,
|
||
fixedLayoutSpreadMode: RDEPUBFixedLayoutSpreadMode = .automatic,
|
||
textRenderingEngine: RDEPUBTextRenderingEngine = .dtCoreText
|
||
) {
|
||
self.fontSize = fontSize
|
||
self.lineHeightMultiple = lineHeightMultiple
|
||
self.fontChoice = fontChoice
|
||
self.numberOfColumns = max(1, numberOfColumns)
|
||
self.columnGap = max(0, columnGap)
|
||
self.displayType = displayType
|
||
self.landscapeDualPageEnabled = landscapeDualPageEnabled
|
||
self.showsTableOfContents = showsTableOfContents
|
||
self.allowsHighlights = allowsHighlights
|
||
self.showsSettingsPanel = showsSettingsPanel
|
||
self.reflowableContentInsets = reflowableContentInsets
|
||
self.fixedContentInset = fixedContentInset
|
||
self.theme = theme
|
||
self.darkImageAdjustmentEnabled = darkImageAdjustmentEnabled
|
||
self.darkImageBlendRatio = max(0, min(0.35, darkImageBlendRatio))
|
||
self.fixedLayoutFit = fixedLayoutFit
|
||
self.fixedLayoutSpreadMode = fixedLayoutSpreadMode
|
||
self.textRenderingEngine = textRenderingEngine
|
||
}
|
||
|
||
/// 默认配置实例,使用所有参数的默认值
|
||
public static let `default` = RDEPUBReaderConfiguration()
|
||
}
|
||
|
||
// MARK: - 配置转换
|
||
|
||
extension RDEPUBReaderConfiguration {
|
||
/// 将用户可见的配置转换为底层排版引擎所需的 RDEPUBPreferences
|
||
/// - Returns: 排版偏好设置实例,供 Core 层的渲染管道使用
|
||
func makePreferences() -> RDEPUBPreferences {
|
||
RDEPUBPreferences(
|
||
fontSize: fontSize,
|
||
lineHeightMultiple: lineHeightMultiple,
|
||
reflowableContentInsets: reflowableContentInsets,
|
||
fixedContentInset: fixedContentInset,
|
||
numberOfColumns: numberOfColumns,
|
||
columnGap: columnGap,
|
||
themeBackgroundColor: theme.themeBackgroundColorCSS,
|
||
themeTextColor: theme.themeTextColorCSS,
|
||
fixedBackgroundColor: theme.themeBackgroundColorCSS,
|
||
fixedLayoutFit: fixedLayoutFit,
|
||
fixedLayoutSpreadMode: fixedLayoutSpreadMode
|
||
)
|
||
}
|
||
}
|