-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better support for different pixel densities #16
Comments
See DioxusLabs/taffy#369 for some investigation into how browsers to rounding. Conclusions:
|
Thanks for that! Your comment here is interesting:
I made a similar example here a while back (zoom in and out a lot - their relative sizes change even though their defined pixels sum to the same) that shows that browsers do round the layout boxes. I agree they don't totally re-layout after that. Sounds like that's what Taffy does now (rounds the layout boxes before render)? I can see this getting difficult. If an inline table changed total size, the line it's on has to change size too. It's like you have to do layout again, but only changing sizes and positions rather than what flex item or text run goes on what line. Did you come across anything like that with flexboxes-in-flexboxes?
In the issue you posted, I can see why this would fix it. According to this old WebKit Wiki, Safari rounded lengths sometimes, and edges sometimes. They don't say when they use which methods though. |
Hmm... I'm not quite sure what I'm supposed to be looking at here. Is the ratio between the first and second columns that you're comparing? How are you measuring the widths? What I found (mostly testing Chrome, although FF seemed similar) was that:
My mental model is that it doesn't ever change size. It ends up with a fractional size. Which will be rounded up or down by (0 < x < 1) pixels for paint but that won't cause anything else to move.
Yeah, I think I've read that before. I think borders thicknesses are one of those cases but I'm not sure on all of them. I suspect different browsers may do this slightly differently in some cases. |
Ah I see. This does actually seem to be something to do with the borders. Remove the borders between cells and the table is always exactly 400px high (and always matches the float if you change it to have 400px height) |
Huh, interesting. With the borders, though, I can't explain it unless pixel snapping is layout-aware. If it's only reproducible with borders it means something, but I don't know what. |
My understanding is that there is an additional pixel rounding/snapping step specifically for borders (rounding to integer physical pixels perhaps?) that takes place either prior to layout or as part of layout. I can't remember where I've seen this, but I've definitely seen this referenced in material about one of the major browsers somewhere. |
That would explain it! Kinda complicates zooming/pixel density though. Let me know if you remember where you read that. I feel relieved. I can't find much in Firefox that would indicate pixel snapping in/after layout, and I've read some things saying it happens in WebRender (lots of pixel snapping here). So I think you're right, it can mostly be done in painting. |
This isn't what I read before, but this issue (w3c/csswg-drafts#3720) has good information. In particular w3c/csswg-drafts#3720 (comment):
This test is also interesting: |
So I also found this comment which says it definitively:
Thanks for pointing me in the right direction. I guess it's because the edge-snapping behavior could snap borders to zero-sized? Rounding during computed style calc is a little better than snapping to at least 1px during paint since it won't go over content, but the whole thing strikes me as too odd to be better. Did Taffy adopt this behavior/are you planning on it? |
w3c/csswg-drafts#5210 (comment) also seems good:
So it seems like border values in device pixels are rounded to integer values (again device pixels) using this floor if > 1, ceil if < 1 formula Where device pixel is defined as:
Taffy doesn't currently implement this, but probably will, perhaps as an option (although I think it can currently be implemented outside of Taffy (and for Blitz/Stylo-Dioxus, I wonder whether stylo will actually already be doing this for us). Currently Taffy has no concept of scale factor: you get ought the units you use as input. But Taffy's existing rounding/pixel-snapping behaviour effectively assumes physical pixels (it doesn't make much sense to snap to logical pixels) and we may well want to make it a setting (where you can the scale to 1.0 to get the existing behaviour). At a meta-level, I'd definitely like Taffy to serve a role in documenting this kind of "kinda-in-the-spec-but-kinda-not" stuff. Also: |
Ref #16. Just need to snap border, padding, and content areas during paint (absolutify?) and then I can close it.
Right now the method is to scale the canvas by a certain amount before painting and round paint coordinates for rects to the nearest integer. But that only produces sharp edges when the zoom is an integer.
It's not hard to support any arbitrary zoom level (like
1.3333
). Don't scale the canvas at all and instead, the painting code receives the zoom level as an input, multiplies the layout coordinates by that, and then rounds. This is particularly useful for browser zoom, which makes thewindow.devicePixelRatio
non-even. Things should line up correctly.Browsers use a much more complicated method of snapping the layouts to pixels. I don't totally know why that is; maybe to produce more desirable results at the extremes.
The text was updated successfully, but these errors were encountered: