Skip to content

Fix RefHover popup region on mupdf per-glyph ink boxes#5719

Merged
kjk merged 1 commit into
masterfrom
fix-refhover-glyph-baseline
Jun 22, 2026
Merged

Fix RefHover popup region on mupdf per-glyph ink boxes#5719
kjk merged 1 commit into
masterfrom
fix-refhover-glyph-baseline

Conversation

@koppor

@koppor koppor commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Problem

The citation/reference hover popup (RefHover) cropped to the wrong region on many real PDFs: a clipped narrow strip, or a full-page landscape fallback showing several entries, instead of the single target bibliography entry.

Root cause: the region detectors in RefHoverDetect.cpp key off coords[i].y as a line coordinate, assuming glyphs on one line share a top. EngineBase::GetTextForPage returns mupdf's tight per-glyph ink boxes, whose tops vary within a line (a period/comma sits well below a capital; ascenders and brackets higher). So the trailing . of the previous bibliography entry could fall into the destination band and hijack the entry-start glyph.

(This only reproduces against the real engine — PyMuPDF/fitz rawdict reports near-uniform tops and hides it.)

Fix

  • NormalizeGlyphLines: cluster glyphs by baseline (y + dy, which is stable across a line) and flatten each line to a uniform top-aligned row before detection. RefHoverOnTimer normalizes the page coords once and passes them to both DetectEquationBox and DetectEntryBox.
  • DetectEntryBox bracket path — derive columnRightX from the body run, bridging the hanging-indent labelsep gap (capped so it can't jump a column gutter). A narrow biblatex label ([TA05]) no longer collapses the box width and clips the entry.
  • DetectEntryBox bracket path — trailing-gap trim so a last-on-page entry (no sibling [ below it) ends at its last line instead of swallowing the page-number footer.

Testing

  • RefHover_ut: added coverage for baseline normalization, the variable-top entry-start hijack, narrow-label full width, 2-column safety, and the footer trim. test_util passes all unit tests.
  • Verified against the real engine on two biblatex PDFs (single- and multi-page bibliographies): every citation link now yields a correct full-width single-entry popup region.

🤖 Generated with Claude Code

The citation-hover region detectors keyed off coords[i].y as a line
coordinate, assuming glyphs on one line share a top. mupdf's
GetTextForPage returns tight per-glyph ink boxes whose tops vary within
a line (a period or comma sits well below a capital). This broke
entry-start detection on real PDFs: the trailing "." of the previous
bibliography entry could fall into the destination band and hijack the
start glyph, yielding a narrow clipped strip or a full-page landscape
fallback instead of the target entry.

- NormalizeGlyphLines: cluster glyphs by baseline (y+dy, stable across a
  line) and flatten each line to a uniform top-aligned row before
  detection. RefHoverOnTimer normalizes coords once for both
  DetectEquationBox and DetectEntryBox.
- DetectEntryBox bracket path: derive columnRightX from the body run
  (bridging the hanging-indent labelsep gap, capped so it can't jump a
  column gutter) so a narrow biblatex label no longer collapses the box
  width and clips the entry.
- DetectEntryBox bracket path: trailing-gap trim so a last-on-page entry
  (no sibling "[" below) ends at its last line instead of swallowing the
  page-number footer.

Adds RefHover_ut coverage for baseline normalization, the variable-top
entry-start hijack, narrow-label full width, 2-column safety, and the
footer trim.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kjk kjk merged commit f8b1a15 into master Jun 22, 2026
2 checks passed
@kjk

kjk commented Jun 22, 2026

Copy link
Copy Markdown
Member

thanks!

@kjk kjk deleted the fix-refhover-glyph-baseline branch June 22, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants