GNOME Bugzilla – Bug 635186
Nudging sometimes moves either zero or two pixels
Last modified: 2018-05-24 12:53:56 UTC
When nudging selection boundaries with the arrow keys, e.g. after having drawn a rectangular selection, sometimes the selection boundary can only be moved in increments of two pixels. This only seems to happen at zoom levels that are powers of two (200%, 400%, 800% etc). Steps to reproduce: 1. Open any image 2. Zoom in to 200% 3. Make any rectangular selection 4. Either try to nudge the position of the entire selection or one of its edges/corners with the arrow keys 5. Repeat steps 3 and 4 several times. Expected results: The selection or its edge always moves with an increment of one pixel. Actual results: Sometimes the selection or its edge will alternate between not moving at all and moving two pixels when pressing the same arrow key in succession. This seems related to bug 620355 in some way. It has been present in many previous versions of GIMP and now it has annoyed me enough since then to file this bug report. A workaround is to zoom in to e.g. 201%.
I can easily reproduce this too. There is clearly some rounding problem.
Created attachment 184713 [details] [review] 0001-RectangleTool-Rounding-error-when-moving-resizing-re.patch Created a patch which should fix this bug: When a rectangle selection is created or moved by mouse at certain zoom-levels (200%, 400%, 800%), its coordinates can become exactly .500. By then using the keyboard to move/resize in steps of one pixel, a rounding error occurs in gimp_rectangle_tool_update_int_rect(). This leads to the coordinate either not being changed at all or changed by 2 pixels at a time. The patch changes the function from using RINT() to ROUND() for the calculations, which prevents the rounding error from happening.
Thanks, nicely found! Keep up the good work :) Fixed in master: commit 074e2c088a4a59ca7d744a131745a869bb1017d7 Author: Enrico Schröder <enni.schroeder@gmail.com> Date: Wed Mar 30 18:22:21 2011 +0200 app: GimpRectangleTool: Rounding error when moving/resizing with keyboard Fix for bug #653186: When a rectangle selection is created or moved by mouse at certain zoom-levels (200%, 400%, 800%), its coordinates can become exactly .500. By then using the keyboard to move/resize in steps of one pixel, a rounding error occurs in gimp_rectangle_tool_update_int_rect(). This leads to the coordinate either not beeing changed at all or changed by 2 pixels at a time. The patch changes the function from using RINT() to ROUND() for the calculations, which prevents the rounding error from happening. app/tools/gimprectangletool.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
*** Bug 620355 has been marked as a duplicate of this bug. ***
This commit reverted the fix to bug 567393, and reintroduced the behaviour described there. I think that it is possible to fix both bugs choosing neither ROUND (wrong with negative values), nor RINT (rounds the integer and a half to the even), but either floor (x + .5) or ceil (x - .5) depending whether the mouse on the half pixel should be considered nearest to the right or left integer. Important is to choose a rounding function that has everywhere the same rounding direction.
Reopening, the fix needs to be redone.
Created attachment 192505 [details] [review] Use floor(x+½) to avoid both round-to-even and bogus rounding of -ve values Here is a patch (suitable for git am) which switches to the floor (x+0.5) idiom, which rounds tied towards +∞. The other reasonable option is to round ties away from zero. That would require either testing for <0 and varying from there (using floor(x+0.5) for +ve and ceil(x-0.5) for -ve would work) or explicitly setting the fp rounding direction. I can provide patches for those alternatives if desired.
I'd say that the other option is less attractive. It is important that the translation of the rectangle of an integer displacement does not change rectangle rounded width and height. If you have: x1 = 1/2 y1 = 1 x2 = 10 + 1/2 y2 = 2 the rounded width (what is displayed in the gui) is 10 but if now you translate the rectangle of (-1, 0) (rounding ties away from zero) the width becomes 11. Now, if a constraint (fixed width) is active there's the risk that an infinite loop starts or that the user cannot position the rectangle where she likes. The width spinbutton emits a "value-changed" signal, the satisfaction of the constraint moves one corner, if the width changes again a new signal is emitted and so on.
Massimo, do you think the latest proposed patch is good enough to push it?
(In reply to comment #9) > Massimo, do you think the latest proposed patch is good enough to push it? I don't know. I recall that different tools have different requirements and fixing one broke another. My recollection is that the first thing should be fixed is constraints enforcing (fixed aspect ratio, fixed size etc). There was a redundant representation (double, int) and an assumption that ROUND (x2 - x1) == ROUND (x2) - ROUND (x1) which is rarely wrong and shows as computing a rectangular selection whose size is off by one. But an off by one is better than data loss cause the GUI is frozen.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gimp/issues/349.