feat: improve native text selection and annotation actions

This commit is contained in:
shen
2026-06-01 21:29:41 +08:00
parent 70133e4e6e
commit 1c6108061c
8 changed files with 359 additions and 216 deletions
@@ -53,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(
idx + pageOffset(for: snapshot),
lineRange: line.stringRange,
pageRange: snapshot.pageContentRange
)
#else
return nil
#endif
@@ -81,9 +85,10 @@ final class RDEPUBPageInteractionController {
#if canImport(DTCoreText)
guard let dtLine = dtLineContaining(range: line.stringRange) else { continue }
let startX = dtLine.offset(forStringIndex: overlap.location)
let pageOffset = pageOffset(for: snapshot)
let startX = dtLine.offset(forStringIndex: overlap.location - pageOffset)
let endIdx = overlap.location + overlap.length
let endX = dtLine.offset(forStringIndex: endIdx)
let endX = dtLine.offset(forStringIndex: endIdx - pageOffset)
#else
let startX: CGFloat = 0
let endX: CGFloat = line.frame.width
@@ -141,7 +146,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: index - pageOffset(for: snapshot))
#else
let offsetX: CGFloat = 0
#endif
@@ -192,11 +197,16 @@ final class RDEPUBPageInteractionController {
#if canImport(DTCoreText)
private func dtLineContaining(range: NSRange) -> DTCoreTextLayoutLine? {
guard let dtLayoutFrame else { return nil }
return dtLayoutFrame.lineContaining(UInt(range.location))
guard let dtLayoutFrame, let snapshot else { return nil }
let localLocation = max(range.location - pageOffset(for: snapshot), 0)
return dtLayoutFrame.lineContaining(UInt(localLocation))
}
#endif
private func pageOffset(for snapshot: RDEPUBPageLayoutSnapshot) -> Int {
snapshot.page.pageStartOffset
}
private func mergeAdjacentRects(_ rects: [CGRect]) -> [CGRect] {
guard rects.count > 1 else { return rects }