From cbdddc095e5b514433f7224f2c12bda00c92e93a Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 11 Oct 2026 20:44:32 -0400 Subject: [PATCH] =?UTF-8?q?fix(web):=20PDF=20adjust=20=E2=80=94=20remove?= =?UTF-8?q?=20the=20leftover=20line-band=20filter=20from=20the=20endpoint?= =?UTF-8?q?=20drag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "full 2D" commit (5a0d9e0) added the tip aim but never removed the y-band candidate filter from pdfAdjustHandleMove — vertical handle drags still snapped to the boundary rect's own line, so up/down movement was impossible (the user's original report). With the filter gone: the end handle drags down a line and the extent extends with clean text — verified with real touch on the emulator (down one line, release, PUT applied: 6 per-line rects). --- web/src/reader/reader.ts | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/web/src/reader/reader.ts b/web/src/reader/reader.ts index 556d0054..a1eb3185 100644 --- a/web/src/reader/reader.ts +++ b/web/src/reader/reader.ts @@ -1855,27 +1855,22 @@ document.addEventListener("alpine:init", () => { if (!ctx) return; const map = this.pdfPageMapping(ctx.index); if (!map) return; - const { fx } = map.toFraction(clientX, clientY); + const { fx, fy } = map.toFraction(clientX, clientY); const chars = ctx.chars; if (!chars.length) return; - // The boundary stays on its OWN line: candidates are the chars in - // the boundary rect's line band, and the finger's X picks the - // glyph (vertical finger movement is ignored — cross-line changes - // go through re-selection). A whole-table Euclidean scan here - // re-anchored onto the line ABOVE when the finger floated above - // the text (lifted handles). - const boundary = - which === "start" ? ctx.rects[0] : ctx.rects[ctx.rects.length - 1]; - const bandTop = boundary[1] - 0.002; - const bandBottom = boundary[1] + boundary[3] + 0.002; + // Full 2D nearest glyph: the tip crosses lines freely (up/down) + // and moves along them (side to side). No line-band pin — the + // lifted handle's finger sits above the text, and a y-band filter + // here made vertical drags impossible (user report). Sliver rects + // stay impossible: the extent is a contiguous char span and the + // rects are its per-line unions. let best = 0; let bestD = Infinity; for (let i = 0; i < chars.length; i++) { const c = chars[i]; - const cy = (c.y0 + c.y1) / 2; - if (cy < bandTop || cy > bandBottom) continue; const cx = (c.x0 + c.x1) / 2; - const d = (cx - fx) * (cx - fx); + const cy = (c.y0 + c.y1) / 2; + const d = (cx - fx) * (cx - fx) + (cy - fy) * (cy - fy); if (d < bestD) { bestD = d; best = i;