Files
ReadViewSDK/Sources/RDReaderView/EPUBCore/RDEPUBPreferences.swift
T
2026-05-26 09:19:37 +08:00

113 lines
4.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// RDEPUBPreferences.swift
// EPUB 阅读偏好设置
// 封装字号、行高、内容内边距、主题颜色、固定版式适配模式等展示参数,
// 并提供从偏好设置生成渲染请求和展示样式的便捷方法。
import UIKit
/// EPUB 阅读偏好设置,包含所有影响渲染效果的展示参数
public struct RDEPUBPreferences: Equatable {
/// 字体大小(pt
public var fontSize: CGFloat
/// 行高倍数(如 1.5 表示 1.5 倍行高)
public var lineHeightMultiple: CGFloat
/// 重排模式下的内容内边距
public var reflowableContentInsets: UIEdgeInsets
/// 固定版式下的内容内边距
public var fixedContentInset: UIEdgeInsets
/// 主题背景色(CSS 颜色值,如 "#FFFFFF"
public var themeBackgroundColor: String?
/// 主题文字色(CSS 颜色值)
public var themeTextColor: String?
/// 固定版式背景色
public var fixedBackgroundColor: String?
/// 固定版式适配模式(page/width/height/contain/cover
public var fixedLayoutFit: RDEPUBFixedLayoutFit
/// 固定版式双页展开模式(never/always/automatic
public var fixedLayoutSpreadMode: RDEPUBFixedLayoutSpreadMode
/// 多栏排版栏数
public var numberOfColumns: Int
/// 多栏排版栏间距
public var columnGap: CGFloat
public init(
fontSize: CGFloat,
lineHeightMultiple: CGFloat,
reflowableContentInsets: UIEdgeInsets,
fixedContentInset: UIEdgeInsets,
numberOfColumns: Int = 1,
columnGap: CGFloat = 20,
themeBackgroundColor: String? = nil,
themeTextColor: String? = nil,
fixedBackgroundColor: String? = nil,
fixedLayoutFit: RDEPUBFixedLayoutFit = .page,
fixedLayoutSpreadMode: RDEPUBFixedLayoutSpreadMode = .automatic
) {
self.fontSize = fontSize
self.lineHeightMultiple = lineHeightMultiple
self.reflowableContentInsets = reflowableContentInsets
self.fixedContentInset = fixedContentInset
self.numberOfColumns = max(1, numberOfColumns)
self.columnGap = max(0, columnGap)
self.themeBackgroundColor = themeBackgroundColor
self.themeTextColor = themeTextColor
self.fixedBackgroundColor = fixedBackgroundColor
self.fixedLayoutFit = fixedLayoutFit
self.fixedLayoutSpreadMode = fixedLayoutSpreadMode
}
/// 从偏好设置生成重排模式的展示样式
public func presentationStyle(viewportSize: CGSize) -> RDEPUBPresentationStyle {
RDEPUBPresentationStyle(
viewportSize: viewportSize,
contentInsets: reflowableContentInsets,
fontSize: fontSize,
lineHeightMultiple: lineHeightMultiple,
numberOfColumns: numberOfColumns,
columnGap: columnGap,
themeBackgroundColor: themeBackgroundColor,
themeTextColor: themeTextColor
)
}
/// 根据页面和偏好设置生成对应的渲染请求(自动区分固定版式和重排)
public func renderRequest(
for page: EPUBPage,
publication: RDEPUBPublication,
viewportSize: CGSize,
targetLocation: RDEPUBLocation? = nil,
highlights: [RDEPUBHighlight] = [],
searchPresentation: RDEPUBSearchPresentation? = nil
) -> RDEPUBRenderRequest? {
if publication.layout == .fixed, let fixedSpread = page.fixedSpread {
return .fixed(
RDEPUBFixedRenderRequest(
spread: fixedSpread,
viewportSize: viewportSize,
contentInset: fixedContentInset,
backgroundColorCSS: fixedBackgroundColor,
fit: fixedLayoutFit,
searchPresentation: searchPresentation
)
)
}
guard publication.spine.indices.contains(page.spineIndex) else {
return nil
}
return .reflowable(
RDEPUBReflowableRenderRequest(
spineIndex: page.spineIndex,
href: publication.spine[page.spineIndex].href,
pageIndex: page.pageIndexInChapter,
totalPagesInChapter: page.totalPagesInChapter,
presentation: presentationStyle(viewportSize: viewportSize),
targetLocation: targetLocation,
highlights: highlights,
searchPresentation: searchPresentation
)
)
}
}