On Sun, 21 Dec 2025 21:45:45 GMT, Michael Strauß <[email protected]> wrote:

> We wouldn't have problems like this if we didn't try to emulate integer 
> arithmetic with doubles. So instead of snapping everywhere, it would be 
> conceptually easier to just do:
> 
> 1. Convert input values to pixel-space integers.
> 2. Do all arithmetic with integers.
> 3. Convert back to doubles.
> 
> Now everything is snapped by definition, because all operations happened with 
> actual integer arithmetic. This also scales nicely with multiple intermediate 
> operations, and it is not affected by arithmetic drift (so repeatedly adding 
> some numbers won't cause the result to be slightly off).

The problem is that you can also use FX "unsnapped" (which can be good for 
fluent animation, where you sometimes actually want something to be rendered at 
a non-pixel boundary).   You'd need two code paths, or start delving into fixed 
point math which brings a few new challenges (but probably not as bad as 
floating point math).

I think doubles are not necessarily the problem.  You can do all operations 
with them without any intermediate snapping, but have to remember to snap at 
the end (which is basically your conversion back to double).   I'll admit 
conversion from say `long` to `double` is harder to "miss" as the compiler will 
yell at you.

Most problems stem from:
- Assuming that doing math with pre-snapped values will result in a snapped 
value
- Using `Math.ceil` for anything (snapSize uses this); as ceil has the nasty 
habit of rounding `1.00000001` to `2` which was surely not what was intended

In many areas we can just remove the snapping as long as we do a snap that 
rounds at the end (so either snapPosition or snapSpace).

One thing I think we maybe should consider in the future is to change 
`snapSize` to use rounding as well, perhaps with a minimum of 1 or something, 
unless it is near zero.

-------------

PR Comment: https://git.openjdk.org/jfx/pull/2016#issuecomment-3679603688

Reply via email to