This PR formalizes render scale and snapping policy as an inheritable layout 
context. I've chosen the term "layout context" because it establishes 
additional inputs to the layout algorithm that need to be accounted for, but 
are not part of the geometric definition of the nodes in the scene graph 
themselves.

For example, consider a `VBox` with a spacing of 0.6: the gaps snap to 1.0 at 
render scale 1, but to 0.5 at render scale 2. Even though the size of the 
`VBox` and all of its inputs remain exactly the same, its children still need 
to move a little bit. This is especially relevant for layout containers that 
cache measurements or layout results (of which there are some), and makes it 
necessary that we have a way to invalidate those containers when the render 
scale or effective snapping policy changes.

For this purpose, the following new APIs are added:
1. `Parent.isSnappedToPixel()` returns the effective pixel-snapping policy, 
which is only `true` if the node itself and all of its ancestors have their 
`snapToPixel` property set. All snapping methods use this method (instead of 
the `snapToPixel` property) to determine whether values should be snapped.
2. `Parent.layoutContextInvalidated()` will be called whenever the render scale 
or the effective pixel-snapping policy changes. This method can be overridden 
by subclasses to clear their cached measurements.

Since we now have a way to invalidate the layout context, we can also cache 
render scales in each node instead of chasing pointers back to `Window` for 
every individual snapping operation. Interestingly, `Region` already cached the 
render scales, but in a useless way that accomplished almost nothing.

Additionally, the snapping methods and the `snapToPixel` property are moved 
from `Region` to `Parent`, as I think having them on `Region` was always 
incorrect. Layout is a mechanism introduced by `Parent` (the `layoutChildren()` 
method is defined on `Parent`), and pixel-snapping intrinsically belongs to 
layout. Think about it: there can be subclasses of `Parent` that can lay out 
nodes, so they must also have access to pixel-snapping APIs. One such example 
is `Group`, which resizes its children to their preferred sizes, but is itself 
not a `Region`.

Moving methods to a superclass is a binary- and source-compatible change.

---------
- [x] I confirm that I make this contribution in accordance with the [OpenJDK 
Interim AI Policy](https://openjdk.org/legal/ai).

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

Commit messages:
 - line endings
 - inherit snapping policy
 - failing test

Changes: https://git.openjdk.org/jfx/pull/2309/files
  Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=2309&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8392161
  Stats: 2451 lines in 30 files changed: 1723 ins; 509 del; 219 mod
  Patch: https://git.openjdk.org/jfx/pull/2309.diff
  Fetch: git fetch https://git.openjdk.org/jfx.git pull/2309/head:pull/2309

PR: https://git.openjdk.org/jfx/pull/2309

Reply via email to