feat(epub): complete wxread parity scope

This commit is contained in:
shen
2026-05-26 09:19:37 +08:00
parent 23182e8b5a
commit 0e7d952fe5
31 changed files with 2619 additions and 1533 deletions
@@ -64,6 +64,15 @@ struct RDEPUBPageLayoutSnapshot {
let layoutFrame: DTCoreTextLayoutFrame
#endif
var contentBounds: CGRect {
let rects = lines.map(\.frame) + attachments.map(\.frame)
guard var bounds = rects.first else { return .zero }
for rect in rects.dropFirst() {
bounds = bounds.union(rect)
}
return bounds
}
func line(containing absoluteIndex: Int) -> RDEPUBPageLine? {
lines.first { NSLocationInRange(absoluteIndex, $0.stringRange) }
}
@@ -80,12 +89,44 @@ struct RDEPUBPageLayoutSnapshot {
attachments.first { $0.frame.insetBy(dx: -hitSlop, dy: -hitSlop).contains(point) }
}
func line(at point: CGPoint, hitSlop: CGFloat = 4) -> RDEPUBPageLine? {
lines.first { line in
let lineRect = CGRect(
x: line.frame.minX,
y: line.baselineOrigin.y - line.ascent,
width: max(line.frame.width, 1),
height: line.ascent + line.descent + line.leading
)
return lineRect.insetBy(dx: -hitSlop, dy: -hitSlop).contains(point)
}
}
func run(at point: CGPoint, hitSlop: CGFloat = 4) -> RDEPUBPageRun? {
runs.first { $0.frame.insetBy(dx: -hitSlop, dy: -hitSlop).contains(point) }
}
func rects(containing point: CGPoint, in decorations: [RDEPUBTextOverlayDecoration]) -> [RDEPUBTextOverlayDecoration] {
decorations.filter { decoration in
decoration.rects.contains { $0.insetBy(dx: -4, dy: -4).contains(point) }
}
}
func absoluteRange(at point: CGPoint, in decorations: [RDEPUBTextOverlayDecoration]) -> NSRange? {
if let attachment = attachment(at: point) {
return attachment.stringRange
}
if let run = run(at: point) {
return run.stringRange
}
let hitDecorations = rects(containing: point, in: decorations)
if let mostSpecific = hitDecorations.min(by: { lhs, rhs in
lhs.absoluteRange.length < rhs.absoluteRange.length
}) {
return mostSpecific.absoluteRange
}
return line(at: point)?.stringRange
}
#if canImport(DTCoreText)
static func build(
from layoutFrame: DTCoreTextLayoutFrame,