Skip to content

Commit bacf20f

Browse files
authored
Use 2D proximity for text layout hit testing (#15)
1 parent f1e943e commit bacf20f

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

Sources/Textual/Internal/TextInteraction/Shared/TextLayout/TextLayoutCollection+Geometry.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
func closestPosition(to point: CGPoint) -> TextPosition? {
5454
guard !layouts.isEmpty else { return nil }
5555

56-
let layoutIndex = layoutIndex(closestToY: point.y)
56+
let layoutIndex = layoutIndex(closestTo: point)
5757
let layout = layouts[layoutIndex]
5858

5959
guard !layout.lines.isEmpty else { return nil }
@@ -93,7 +93,7 @@
9393
func characterRange(at point: CGPoint) -> TextRange? {
9494
guard !layouts.isEmpty else { return nil }
9595

96-
let layoutIndex = layoutIndex(closestToY: point.y)
96+
let layoutIndex = layoutIndex(closestTo: point)
9797
let layout = layouts[layoutIndex]
9898

9999
guard !layout.lines.isEmpty else { return nil }
@@ -264,11 +264,11 @@
264264
return line.typographicBounds.offsetBy(dx: layout.origin.x, dy: layout.origin.y)
265265
}
266266

267-
fileprivate func layoutIndex(closestToY y: CGFloat) -> Int {
267+
fileprivate func layoutIndex(closestTo point: CGPoint) -> Int {
268268
var closestIndex = 0
269269
var closestDistance = CGFloat.greatestFiniteMagnitude
270270
for (index, layout) in zip(layouts.indices, layouts) {
271-
let distance = layout.frame.verticalDistance(to: y)
271+
let distance = layout.frame.distanceSquared(to: point)
272272
if distance < closestDistance {
273273
closestDistance = distance
274274
closestIndex = index
@@ -347,5 +347,11 @@
347347
if x > maxX { return x - maxX }
348348
return 0
349349
}
350+
351+
fileprivate func distanceSquared(to point: CGPoint) -> CGFloat {
352+
let dx = horizontalDistance(to: point.x)
353+
let dy = verticalDistance(to: point.y)
354+
return dx * dx + dy * dy
355+
}
350356
}
351357
#endif

0 commit comments

Comments
 (0)