It is indeed a problem that everyone has to solve in some form or
another. JavaFX chose an approach where snapping is not really built
into the core algorithms, but almost entirely delegated to container
implementations.

Android instead uses integer layout coordinates. That makes it
impossible to lay out regions any other way but on the pixel grid, but
it doesn't magically solve all the problems. For example, when you
have 100 pixels and want to distribute this among three equal-sized
children, even with integer coordinates you need additional logic to
fill the available space exactly. Naively int-dividing 100 by 3 gives
you 33 pixels per child, and one unaccounted pixel which you need to
add to any of the children if you don't want to have a gap in the
layout.

WPF uses a two-phase layout algorithm (similar to Android), but
doesn't allow you to override the Measure/Arrange methods like you can
override layoutChildren() in JavaFX. There is substantial accounting
for what WPF calls "layout rounding" built into those core methods,
and control authors only provide some of the algorithm via the
MeasureOverride/ArrangeOverride extension points. For example, the
non-overridable MeasureCore method rounds the available size passed to
MeasureOverride, and it also rounds the eventual desired size. Its
surrounding margin and minimum/maximum-size calculations also contain
rounding logic.

Interestingly, WPF doesn't use rounding in the layout system by
default, and instead defaults to guideline-based pixel snapping in the
native renderer. This works by supplying guidelines in addition to
drawing geometry. These guidelines usually identify the "important"
edges of the geometry. For each coordinate that the renderer wants to
snap to the pixel grid, it finds the closest guideline, and then adds
the guideline's offset from the pixel grid to the coordinate. For
example, a simple region might have four guidelines that correspond to
its edges, and the offsets of those guidelines from the pixel grid are
the correction that is applied to the rendered geometry. As a more
complex example, the TickBar control supplies guidelines for each
individual tick it needs to draw.

Guideline-based snapping gives the native renderer two pieces of
information: the ideal, unsnapped geometry, as well as information how
to map it to the pixel grid. The native renderer can then do some
tricks like subpixel animation correction: when it detects that a
guideline starts moving gradually, it can fade out of snapping, and
when the movement settles, fade back into snapping.




On Thu, Sep 10, 2026 at 9:27 AM Nir Lisker <[email protected]> wrote:
>
> I have to wonder if there isn't already existing literature on snapping. 
> Every UI toolkit (not only in Java) has had to deal with snapping in some 
> way, we're not doing anything new.
> What do they do? Are there any established algorithms in papers?
>
> - Nir

Reply via email to