Two changes to the per-pixel value labels, which appear above 30x zoom.
They were up to 5000 QGraphicsSimpleTextItems created and destroyed on every
overlay rebuild - so on every pan step while zoomed in. Paint them in
drawForeground() instead: no item churn, no scene invalidation, and the text is
laid out in viewport pixels so it is a constant readable size rather than a
scene-space font scaled by 0.2. Same approach as the magnifier's labels.
The value text becomes a virtual, PixelLabel(). The base still formats from
image_fp, which is what the genuinely float-valued views hold (azimuthal
profile, grid-scan 1/sigma^2, the calibration viewer's eight source types).
JFJochDiffractionImage overrides it to read the int32 image directly: counts are
exact integers, so routing them through float32 is a detour that also cannot
represent summed values above 2^24 exactly.
Verified at 38 wheel clicks over a module edge: identical values and
gap/contrast handling to the previous float path, now centred in each pixel.
Fit-view panel still pixel-identical to the pre-series baseline.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>