On Tue, 1 Sep 2026 17:02:01 GMT, John Hendrikx <[email protected]> wrote:

>>> I wonder, why do we even need the unsnapped setting? what is the use case?
>> 
>> In theory, with a sufficiently high-DPI display, you don't need pixel 
>> snapping at all. The number of photons emitted from a perfectly-aligned 
>> hairline, and a hairline that straddles a pixel boundary, is the same. The 
>> only difference is that in the latter case, the photons are emitted from a 
>> more spread-out area. But once your DPI is so high that you can't see a 
>> difference between the two, there's no need for snapping.
>
>> > * HBox 2 (snapped) gets 10.25 pixels
>> >   
>> >   * Child 1 gets 5 pixels
>> >   * Child 2 gets 5 pixels
>> >   * (empty space within border of 0.25 pixels)
>> >     
>> >     * Empty space location determined by alignment
>> >       
>> >       * LEFT: C1  C2 (0.25)
>> >       * CENTER: (0.125) C1  C2 (0.125)
>> >       * RIGHT: (0.25) C1  C2
>> 
>> It can't possibly work like that. You have a snapped HBox that is allocated 
>> 10.25 pixels. Now, each of the two children must be allocated 5 pixels, as 
>> otherwise they will be off-grid. If you allocate 5.0 pixels to C1, and 5.25 
>> pixels to C2, then the latter will be off-grid at its right edge.
> 
> What makes you think that snapping here will result in being on-grid? Clearly 
> with an allocation of 10.25 pixels, we're dealing with an unsnapped parent of 
> the HBox container, why would pixel 0 be on the grid?  Where we put that 0.25 
> of empty space is anyone's guess as to whether that will align you; saying 
> that it can only be on the right edge is ridiculous:
> 
> <img width="883" height="207" alt="image" 
> src="https://github.com/user-attachments/assets/b82e4407-3923-42b2-a8da-52d230b3193b";
>  />
> 
>  
>> The remainder of 0.25 pixels can't possibly be anywhere else but at the 
>> right edge of the allocated space:
>> 
>> 1. If the remainder is at the left edge of the allocation, then both 
>> children will be offset 0.25 pixels relative to the grid.
>> 2. If it is between the children, then the left child will be aligned, but 
>> the right child will be offset.
> 
> Both entirely depend on where the container starts.
> 
>> 3. This leaves the right edge as the only place where to insert the 
>> remainder.
> 
> Assuming that your anchor is on the grid, but it won't be.
> 
> The rest of your argument is the same. If your unsnapped parent didn't set 
> your x/y to be on the grid, then nothing you can do as a child will get you 
> aligned back. I think you even said as much in the snapping docs.
> 
> This is why I think we shouldn't bother at all with this, and treat any 
> unsnapped ancestor as final for that subtree.

> > I wonder, why do we even need the unsnapped setting? what is the use case?
> 
> In theory, with a sufficiently high-DPI display, you don't need pixel 
> snapping at all. The number of photons emitted from a perfectly-aligned 
> hairline, and a hairline that straddles a pixel boundary, is the same. The 
> only difference is that in the latter case, the photons are emitted from a 
> more spread-out area. But once your DPI is so high that you can't see a 
> difference between the two, there's no need for snapping.

I'm starting to get the feeling "unsnapped" was added as a "performance" thing, 
to avoid the divide/multiply required to do snapping for each and every 
input/output. I can already imagine how that discussion went: 

- E1: we have to support high dpi displays and arbitrary render scales
- E2: but that would mean rounding every layout calculation costing 500000 
div/mul operations for an average UI, adding 30 microseconds per layout
  - never mind we currently do double layouts, and often repeat layout 
calculations half a dozen of time because of `requestLayout` calls for 
properties that don't affect layout (like background changes triggering 
relayout... sigh) 
- E3: and what about being backwards incompatible, what if people want to keep 
drawing fuzzy junk on their high DPI displays??
- E1: we'll make it switchable...

... and SnapToPixel as a per Node setting is born...

I still see no use case for it, not even on the best high DPI displays -- 
snapping will still look better.  Also snapping will never look worse. Given a 
fabled 10000 dpi display, you'd likely set render scale to 10000% to make 
things readable, giving "snapping" a possible 100 pixels to choose from per one 
"normal sized 96 dpi" pixel. It will look just as sharp and crisp.

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

PR Review Comment: https://git.openjdk.org/jfx/pull/2262#discussion_r3906673801

Reply via email to