- 实现EPUB阅读器搜索功能及选中注释功能 - 优化CFI模块,修复代码审查发现的11个问题 - 实现大书远距目录跳转与后台补全优化方案 - 优化设置面板与章节运行时联动 - 重构及大量改进优化
188 lines
6.3 KiB
Swift
188 lines
6.3 KiB
Swift
import UIKit
|
|
|
|
public enum RDEPUBTextRenderingEngine: Equatable {
|
|
|
|
case dtCoreText
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct RDEPUBReaderConfiguration: Equatable {
|
|
|
|
public var fontSize: CGFloat
|
|
|
|
public var lineHeightMultiple: CGFloat
|
|
|
|
public var fontChoice: RDEPUBReaderFontChoice
|
|
|
|
public var numberOfColumns: Int
|
|
|
|
public var columnGap: CGFloat
|
|
|
|
public var displayType: RDReaderView.DisplayType
|
|
|
|
public var landscapeDualPageEnabled: Bool
|
|
|
|
public var showsTableOfContents: Bool
|
|
|
|
public var allowsHighlights: Bool
|
|
|
|
public var showsSettingsPanel: Bool
|
|
|
|
public var reflowableContentInsets: UIEdgeInsets
|
|
|
|
public var fixedContentInset: UIEdgeInsets
|
|
|
|
public var theme: RDEPUBReaderTheme
|
|
|
|
public var darkImageAdjustmentEnabled: Bool
|
|
|
|
public var darkImageBlendRatio: CGFloat
|
|
|
|
public var fixedLayoutFit: RDEPUBFixedLayoutFit
|
|
|
|
public var fixedLayoutSpreadMode: RDEPUBFixedLayoutSpreadMode
|
|
|
|
public var textRenderingEngine: RDEPUBTextRenderingEngine
|
|
|
|
public var onDemandChapterWindowSize: Int
|
|
|
|
public var metadataParsingConcurrency: Int
|
|
|
|
public var jumpSessionPolicy: RDEPUBJumpSessionPolicy
|
|
|
|
public var allowedExternalURLSchemes: Set<String>
|
|
|
|
public var requiresExternalLinkConfirmation: Bool
|
|
|
|
public var allowsInspectableWebViews: Bool
|
|
|
|
public var enablesVerboseWebViewLogging: Bool
|
|
|
|
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,
|
|
onDemandChapterWindowSize: Int = 3,
|
|
metadataParsingConcurrency: Int = ProcessInfo.processInfo.activeProcessorCount,
|
|
jumpSessionPolicy: RDEPUBJumpSessionPolicy = .default,
|
|
allowedExternalURLSchemes: Set<String> = ["https"],
|
|
requiresExternalLinkConfirmation: Bool = true,
|
|
allowsInspectableWebViews: Bool = false,
|
|
enablesVerboseWebViewLogging: Bool = false
|
|
) {
|
|
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
|
|
self.onDemandChapterWindowSize = Self.normalizedChapterWindowSize(onDemandChapterWindowSize)
|
|
self.metadataParsingConcurrency = max(1, metadataParsingConcurrency)
|
|
self.jumpSessionPolicy = jumpSessionPolicy
|
|
self.allowedExternalURLSchemes = allowedExternalURLSchemes
|
|
self.requiresExternalLinkConfirmation = requiresExternalLinkConfirmation
|
|
self.allowsInspectableWebViews = allowsInspectableWebViews
|
|
self.enablesVerboseWebViewLogging = enablesVerboseWebViewLogging
|
|
}
|
|
|
|
public static let `default` = RDEPUBReaderConfiguration()
|
|
}
|
|
|
|
extension RDEPUBReaderConfiguration {
|
|
|
|
static func normalizedChapterWindowSize(_ size: Int) -> Int {
|
|
let clamped = max(3, min(15, size))
|
|
return clamped % 2 == 0 ? clamped + 1 : clamped
|
|
}
|
|
|
|
var chapterWindowRadius: Int {
|
|
onDemandChapterWindowSize / 2
|
|
}
|
|
}
|
|
|
|
extension RDEPUBReaderConfiguration {
|
|
|
|
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
|
|
)
|
|
}
|
|
}
|