Skip to content

fix: sub-pixel and off-by-one errors in bounded_move_shapes clamping#242

Merged
vietanhdev merged 1 commit into
mainfrom
fix/bounded-move-shapes-subpixel-clamp
Jul 11, 2026
Merged

fix: sub-pixel and off-by-one errors in bounded_move_shapes clamping#242
vietanhdev merged 1 commit into
mainfrom
fix/bounded-move-shapes-subpixel-clamp

Conversation

@vietanhdev

Copy link
Copy Markdown
Owner

Summary

Follow-up to #241. Copilot's review on that PR flagged that the left/top clamp still did int(o1.x()) before wrapping in QPointF, so sub-pixel overflows (e.g. -0.3) truncate to 0 and the correction silently no-ops.

Writing an output-correctness test for that (not just a crash check) surfaced a second, independent bug in the same lines: the right/bottom clamp corrects against pixmap.width()/height() instead of (width() - 1)/(height() - 1) — which is the bound out_off_pixmap() itself enforces. So a shape overflowing the right or bottom edge stayed uncorrected regardless of the int() issue.

Both are pre-existing (predate #237/#238/#240/#241) — this only touches the four lines #241 already modified.

Fix

  • Drop the int() truncation so sub-pixel corrections aren't dropped.
  • Correct the right/bottom clamp to use width() - 1 / height() - 1, matching out_off_pixmap()'s own bound.

Test plan

  • New tests/test_canvas_bounded_move.py: sub-pixel overflow at left/top edge, sub-pixel overflow at right/bottom edge (asserts exact corrected value), original TypeError crash path.
  • Full local suite: 92 tests, same single pre-existing SAM3-fallback failure noted in CLAUDE.md (unrelated), no new failures.

Copilot's review of #241 flagged that the left/top clamp still did
int(o1.x()) before wrapping in QPointF, so sub-pixel overflows (e.g.
-0.3) truncate to 0 and silently fail to correct the position.

Verifying that fix surfaced a second, independent bug in the same
lines: the right/bottom clamp corrects against pixmap.width()/height()
instead of (width() - 1)/(height() - 1), which is the bound
out_off_pixmap() actually enforces — so a shape overflowing the right
or bottom edge stayed uncorrected regardless of the int() truncation.

Both are pre-existing (predate #237/#238/#240/#241); this PR only
touches the four lines already modified by #241. Adds a regression
test covering both edges plus the original TypeError crash path.
Copilot AI review requested due to automatic review settings July 11, 2026 04:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Canvas.bounded_move_shapes() clamping math so sub-pixel overflows are actually corrected (no int() truncation) and right/bottom clamping matches out_off_pixmap()’s inclusive (w - 1, h - 1) bounds, preventing off-by-one “no-op” corrections at the far edge.

Changes:

  • Update left/top clamp to use floating-point deltas (no truncation), preserving sub-pixel corrections.
  • Update right/bottom clamp to correct against (width - 1) / (height - 1) to match out_off_pixmap()’s boundary logic.
  • Add regression tests covering the prior TypeError path and both sub-pixel left/top and right/bottom overflow corrections.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
anylabeling/views/labeling/widgets/canvas.py Fixes the clamp deltas in bounded_move_shapes() to be sub-pixel-safe and consistent with out_off_pixmap()’s bounds.
tests/test_canvas_bounded_move.py Adds regression tests validating the corrected clamping behavior (including sub-pixel cases) and the previously reported TypeError scenario.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vietanhdev
vietanhdev merged commit e23606d into main Jul 11, 2026
10 checks passed
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