refactor: rename RDReaderView -> RDEpubReaderView, update pod config and docs
- Rename source module from RDReaderView to RDEpubReaderView - Move all source files from Sources/RDReaderView/ to Sources/RDEpubReaderView/ - Update podspec: RDReaderView.podspec -> RDEpubReaderView.podspec - Update Podfile, demo project, and CocoaPods config for new pod name - Delete old RDReaderView pod support files from ReadViewDemo/Pods - Add new RDEpubReaderView pod support files - Update documentation (API ref, architecture, UML, conventions, etc.) - Add FixedLayoutRotationTests - Update .gitignore: exclude .DS_Store, manual unpack backups, _ssoft-output
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
import Foundation
|
||||
|
||||
public enum RDEPUBTextPageBreakReason: String, Codable, Equatable {
|
||||
|
||||
case chapterEnd
|
||||
|
||||
case frameLimit
|
||||
|
||||
case blockBoundary
|
||||
|
||||
case attachmentBoundary
|
||||
|
||||
case semanticBoundary
|
||||
}
|
||||
|
||||
public enum RDEPUBTextAttachmentKind: String, Codable, Equatable {
|
||||
|
||||
case image
|
||||
|
||||
case generic
|
||||
|
||||
case footnote
|
||||
}
|
||||
|
||||
public struct RDEPUBTextPageMetadata: Codable, Equatable {
|
||||
|
||||
public var breakReason: RDEPUBTextPageBreakReason
|
||||
|
||||
public var blockRange: NSRange?
|
||||
|
||||
public var attachmentRanges: [NSRange]
|
||||
|
||||
public var attachmentKinds: [RDEPUBTextAttachmentKind]
|
||||
|
||||
public var blockKinds: [RDEPUBTextBlockKind]
|
||||
|
||||
public var semanticHints: [RDEPUBTextSemanticHint]
|
||||
|
||||
public var attachmentPlacements: [RDEPUBTextAttachmentPlacement]
|
||||
|
||||
public var trailingFragmentID: String?
|
||||
|
||||
public var diagnostics: [String]
|
||||
|
||||
public init(
|
||||
breakReason: RDEPUBTextPageBreakReason,
|
||||
blockRange: NSRange? = nil,
|
||||
attachmentRanges: [NSRange] = [],
|
||||
attachmentKinds: [RDEPUBTextAttachmentKind] = [],
|
||||
blockKinds: [RDEPUBTextBlockKind] = [],
|
||||
semanticHints: [RDEPUBTextSemanticHint] = [],
|
||||
attachmentPlacements: [RDEPUBTextAttachmentPlacement] = [],
|
||||
trailingFragmentID: String? = nil,
|
||||
diagnostics: [String] = []
|
||||
) {
|
||||
self.breakReason = breakReason
|
||||
self.blockRange = blockRange
|
||||
self.attachmentRanges = attachmentRanges
|
||||
self.attachmentKinds = attachmentKinds
|
||||
self.blockKinds = blockKinds
|
||||
self.semanticHints = semanticHints
|
||||
self.attachmentPlacements = attachmentPlacements
|
||||
self.trailingFragmentID = trailingFragmentID
|
||||
self.diagnostics = diagnostics
|
||||
}
|
||||
}
|
||||
|
||||
public struct EPUBChapterInfo: Codable, Equatable {
|
||||
|
||||
public var spineIndex: Int
|
||||
|
||||
public var title: String
|
||||
|
||||
public var pageCount: Int
|
||||
|
||||
public init(spineIndex: Int, title: String, pageCount: Int) {
|
||||
self.spineIndex = spineIndex
|
||||
self.title = title
|
||||
self.pageCount = pageCount
|
||||
}
|
||||
}
|
||||
|
||||
public struct EPUBPage: Codable, Equatable {
|
||||
|
||||
public var spineIndex: Int
|
||||
|
||||
public var chapterIndex: Int
|
||||
|
||||
public var pageIndexInChapter: Int
|
||||
|
||||
public var totalPagesInChapter: Int
|
||||
|
||||
public var chapterTitle: String
|
||||
|
||||
public var fixedSpread: EPUBFixedSpread?
|
||||
|
||||
public init(
|
||||
spineIndex: Int,
|
||||
chapterIndex: Int,
|
||||
pageIndexInChapter: Int,
|
||||
totalPagesInChapter: Int,
|
||||
chapterTitle: String,
|
||||
fixedSpread: EPUBFixedSpread?
|
||||
) {
|
||||
self.spineIndex = spineIndex
|
||||
self.chapterIndex = chapterIndex
|
||||
self.pageIndexInChapter = pageIndexInChapter
|
||||
self.totalPagesInChapter = totalPagesInChapter
|
||||
self.chapterTitle = chapterTitle
|
||||
self.fixedSpread = fixedSpread
|
||||
}
|
||||
}
|
||||
|
||||
public struct EPUBFixedSpreadResource: Codable, Equatable {
|
||||
|
||||
public var spineIndex: Int
|
||||
|
||||
public var href: String
|
||||
|
||||
public var title: String
|
||||
|
||||
public var pageSpread: RDEPUBPageSpread?
|
||||
|
||||
public init(spineIndex: Int, href: String, title: String, pageSpread: RDEPUBPageSpread? = nil) {
|
||||
self.spineIndex = spineIndex
|
||||
self.href = href
|
||||
self.title = title
|
||||
self.pageSpread = pageSpread
|
||||
}
|
||||
}
|
||||
|
||||
public struct EPUBFixedSpread: Codable, Equatable {
|
||||
|
||||
public var resources: [EPUBFixedSpreadResource]
|
||||
|
||||
public init(resources: [EPUBFixedSpreadResource]) {
|
||||
self.resources = resources
|
||||
}
|
||||
|
||||
public var primaryResource: EPUBFixedSpreadResource {
|
||||
resources.first ?? EPUBFixedSpreadResource(spineIndex: 0, href: "", title: "")
|
||||
}
|
||||
|
||||
public func contains(normalizedHref: String, normalizer: (String) -> String?) -> Bool {
|
||||
resources.contains { resource in
|
||||
normalizer(resource.href) == normalizedHref
|
||||
}
|
||||
}
|
||||
|
||||
public static func makeSpreads(spine: [RDEPUBSpineItem], spreadEnabled: Bool) -> [EPUBFixedSpread] {
|
||||
let resources = spine.enumerated().map { index, item in
|
||||
EPUBFixedSpreadResource(
|
||||
spineIndex: index,
|
||||
href: item.href,
|
||||
title: item.title,
|
||||
pageSpread: item.pageSpread
|
||||
)
|
||||
}
|
||||
|
||||
guard spreadEnabled, resources.count > 1 else {
|
||||
return resources.map { EPUBFixedSpread(resources: [$0]) }
|
||||
}
|
||||
|
||||
var spreads: [EPUBFixedSpread] = []
|
||||
var cursor = 0
|
||||
|
||||
while cursor < resources.count {
|
||||
let current = resources[cursor]
|
||||
|
||||
guard cursor + 1 < resources.count else {
|
||||
spreads.append(EPUBFixedSpread(resources: [current]))
|
||||
break
|
||||
}
|
||||
|
||||
let next = resources[cursor + 1]
|
||||
if shouldPair(current: current, next: next) {
|
||||
spreads.append(EPUBFixedSpread(resources: [current, next]))
|
||||
cursor += 2
|
||||
} else {
|
||||
spreads.append(EPUBFixedSpread(resources: [current]))
|
||||
cursor += 1
|
||||
}
|
||||
}
|
||||
|
||||
return spreads
|
||||
}
|
||||
|
||||
public static func makeSpreads(parser: RDEPUBParser, spreadEnabled: Bool) -> [EPUBFixedSpread] {
|
||||
makeSpreads(spine: parser.spine, spreadEnabled: spreadEnabled)
|
||||
}
|
||||
|
||||
private static func shouldPair(current: EPUBFixedSpreadResource, next: EPUBFixedSpreadResource) -> Bool {
|
||||
if current.pageSpread == .center || next.pageSpread == .center {
|
||||
return false
|
||||
}
|
||||
|
||||
switch (current.pageSpread, next.pageSpread) {
|
||||
case (.left, .right), (.right, .left):
|
||||
return true
|
||||
case (.left, .left), (.right, .right):
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user