fix(reader): stabilize pagination display and page curl reuse
This commit is contained in:
@@ -13,12 +13,18 @@ final class RDEPUBPageInteractionController {
|
||||
|
||||
var snapshot: RDEPUBPageLayoutSnapshot?
|
||||
private var dtLayoutFrame: DTCoreTextLayoutFrame?
|
||||
private var contentOffsetBase: Int = 0
|
||||
|
||||
#if canImport(DTCoreText)
|
||||
func configure(layoutFrame: DTCoreTextLayoutFrame?, page: RDEPUBTextPage?) {
|
||||
func configure(layoutFrame: DTCoreTextLayoutFrame?, page: RDEPUBTextPage?, contentOffsetBase: Int = 0) {
|
||||
dtLayoutFrame = layoutFrame
|
||||
self.contentOffsetBase = contentOffsetBase
|
||||
if let layoutFrame, let page {
|
||||
snapshot = RDEPUBPageLayoutSnapshot.build(from: layoutFrame, page: page)
|
||||
snapshot = RDEPUBPageLayoutSnapshot.build(
|
||||
from: layoutFrame,
|
||||
page: page,
|
||||
contentOffsetBase: contentOffsetBase
|
||||
)
|
||||
} else {
|
||||
snapshot = nil
|
||||
}
|
||||
@@ -47,7 +53,11 @@ final class RDEPUBPageInteractionController {
|
||||
)
|
||||
let idx = dtLine.stringIndex(forPosition: relativePoint)
|
||||
guard idx != NSNotFound, idx >= 0 else { return nil }
|
||||
return normalizedIndex(idx, lineRange: line.stringRange, pageRange: snapshot.pageContentRange)
|
||||
return normalizedIndex(
|
||||
absoluteIndex(for: idx),
|
||||
lineRange: line.stringRange,
|
||||
pageRange: snapshot.pageContentRange
|
||||
)
|
||||
#else
|
||||
return nil
|
||||
#endif
|
||||
@@ -75,9 +85,9 @@ final class RDEPUBPageInteractionController {
|
||||
|
||||
#if canImport(DTCoreText)
|
||||
guard let dtLine = dtLineContaining(range: line.stringRange) else { continue }
|
||||
let startX = dtLine.offset(forStringIndex: overlap.location)
|
||||
let startX = dtLine.offset(forStringIndex: localIndex(for: overlap.location))
|
||||
let endIdx = overlap.location + overlap.length
|
||||
let endX = dtLine.offset(forStringIndex: endIdx)
|
||||
let endX = dtLine.offset(forStringIndex: localIndex(for: endIdx))
|
||||
#else
|
||||
let startX: CGFloat = 0
|
||||
let endX: CGFloat = line.frame.width
|
||||
@@ -135,7 +145,7 @@ final class RDEPUBPageInteractionController {
|
||||
|
||||
#if canImport(DTCoreText)
|
||||
guard let dtLine = dtLineContaining(range: line.stringRange) else { return nil }
|
||||
let offsetX = dtLine.offset(forStringIndex: index)
|
||||
let offsetX = dtLine.offset(forStringIndex: localIndex(for: index))
|
||||
#else
|
||||
let offsetX: CGFloat = 0
|
||||
#endif
|
||||
@@ -187,10 +197,18 @@ final class RDEPUBPageInteractionController {
|
||||
#if canImport(DTCoreText)
|
||||
private func dtLineContaining(range: NSRange) -> DTCoreTextLayoutLine? {
|
||||
guard let dtLayoutFrame else { return nil }
|
||||
return dtLayoutFrame.lineContaining(UInt(range.location))
|
||||
return dtLayoutFrame.lineContaining(UInt(max(localIndex(for: range.location), 0)))
|
||||
}
|
||||
#endif
|
||||
|
||||
private func localIndex(for absoluteIndex: Int) -> Int {
|
||||
absoluteIndex - contentOffsetBase
|
||||
}
|
||||
|
||||
private func absoluteIndex(for localIndex: Int) -> Int {
|
||||
localIndex + contentOffsetBase
|
||||
}
|
||||
|
||||
private func mergeAdjacentRects(_ rects: [CGRect]) -> [CGRect] {
|
||||
guard rects.count > 1 else { return rects }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user