-
Notifications
You must be signed in to change notification settings - Fork 32
Make use of physical and logical size types #70
Comments
Can you say something about the advantages/disadvantages of the two representations? |
For outputs, e.g. For inputs, e.g. ...but note there are some restrictions, e.g. on Wayland the initial window size must be specified in logical pixels (the scale factor might be guessable but should be treated as unknown). Meanwhile, X11 is the other way around: the size must be specified in physical pixels (but, since the scale factor must be the same for all screens, you should at least be able to guess that and convert from logical pixels). |
I think a leaner less complex API is superior. We should use logical everywhere in the API except places where it won't work. (So basically how the current API works.) Then the inner implementation can worry about how to translate the platform API. From that it follows that an enum isn't ideal, because yes it'll mandate two paths for every method. Additionally, we want to do the conversion the minimum number of times possible, because of floating point math error accumulation and pixel alignment. Doing as much as possible with logical units gives us the power to choose where and how many times the conversion happens. Also, ergonomics is important. Given the thinking that logical units should be used whenever possible, it would be a lot more ergonomical to just define a convention that a bare |
That's pretty convincing; I'm on board with doing the statically typed version instead of the enum. There's one situation that I'm still a little concerned about (that Druid currently gets wrong): although we mostly want to use logical units, we do often want to round layout to pixel boundaries in order to ensure, for example, that 1-pixel-width lines look nice. Having a bare |
Yes alignment is tricky. Druid has a partial solution, but it fails some cases and doesn't even attempt dynamic fractional scale alignment [1]. I've been thinking about this on and off, but haven't found an ultimate solution yet. It would probably be wise to write up some thoughts and get some discussion going that would result in a document describing what we would like to happen in all the various cases. For now, here are some rough thoughts that immediately come to mind. There's the simple case of 1x and 2x scaling. Just rounding the logical units will go very far to solve the problem here. Then there's the extremely common 1.25x, 1.75x, and friends. Just rounding logical units won't work too well. Containers could probably use scale info to perform the rounding based on physical integers. That way at least every container's origin would be aligned and thus the container could do alignment of children with just the scale info and not having to know its window coords. [1] It gets trickier though. Because yes what about things like thin lines. Perhaps a dynamic size would be interesting. Sometimes you want the half-transparent interpolation and other times you want sharp alignment. Should probably try to gather some use case scenarios and figure out if there is a strong bias either way, because that's what the default should be. |
I agree that I'm not a fan of the enum option either.
But alignment isn't really glazier's responsibility, right? It's the responsibility of a UI toolkit built on top. (Unless you're talking about the sub compositor). I just need to know the physical size of the buffer I'm drawing on. For a UI toolkit, allowing mixed units makes more sense: "I want a button that's 60 points wide but with a 1 pixel border".
Wouldn't you want sharp alignment in almost all cases for a gui? |
Sounds good. A couple of exceptions I see:
This is getting way off-topic, but I basically solved it. E.g. see But yes, this has nothing to do with Glazier (or Winit). |
It isn't always clear whether a size is in pixel or display points. Better documentation could help, but making use of the type system would be even better.
I think there are 2 ways of going about this. Using wrapper types
Or using an enum. This is how winit does it
The text was updated successfully, but these errors were encountered: