-
Notifications
You must be signed in to change notification settings - Fork 110
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
Request: Allow buffer dimensions to be undefined #42
Comments
Using the maximum value for size essentially does this, unless you have text that will be more than billions of pixels wide |
If the goal is simply to measure the text's width for UI layout purposes, then (1) there will be some maximum width above which the exact result doesn't matter (because wrapping will be needed) and (2) layout of any remaining text is irrelevant. Consider adding a method especially for this purpose: https://docs.rs/kas-text/latest/kas_text/struct.TextDisplay.html#method.measure_width |
This is basically the use case, except:
|
Height can only be determined after wrapping (hence you must do full layout and automatically get both). Maybe some opts are available if you only want height (e.g. not re-ordering lines), but I doubt there's much value. I assumed #70 is about this. I ended up using a GUI layout algorithm which fully determines width before considering height, hence the two-step approach works for me, but I am well aware that most layout algorithms address both simultaneously. Calculating only height without ever wrapping is as simple as multiplying the line height by the number of lines and adding in line-gaps (not sure if Cosmic-text uses these?), assuming your font size is constant and there are no oversize glyphs, subscript / superscript, etc. Not sure why you'd want to measure height with "zero width". If words are too long for a line, there is hyphenation and even per-glyph breaking. You might as well just assume the maximum height is some BIG NUMBER (or screen height), at which point it doesn't help with layout. |
Presumably for vertical text this is reversed and it's width that can only be determined by doing a full layout? (I'd be interested to to know if/how your GPU layout algorithm works for vertical text). I think what I want is a way to do "full layout" but without storing the result except for the overall width/height. Which should mean that no allocations need to take place unlike what I'm imagining happens in a regular layout where the contents of each line are stored.
CSS layout uses this to determine a minimum width for text nodes (under specified line-breaking rules which by default do not permit hyphenation or per-glyph breaking)
I think I'd usually want the height taking into account all these edge cases. |
This doesn't work as expected in all cases, specifically in conjunction with text alignment. For Bevy UI, my current implementation of "text alignment" just creates the buffer with This works; however, if I want to be able to turn these into Since we want text areas to be "content-sized" when no width is explicitly provided, we use This doesn't work when I use let alignment_correction = match (align, self.rtl) {
(Align::Left, true) => line_width - visual_line.w,
(Align::Left, false) => 0.,
(Align::Right, true) => 0.,
(Align::Right, false) => line_width - visual_line.w,
(Align::Center, _) => (line_width - visual_line.w) / 2.0,
(Align::Justified, _) => {
// Don't justify the last line in a paragraph.
if visual_line.spaces > 0 && index != number_of_visual_lines - 1 {
(line_width - visual_line.w) / visual_line.spaces as f32
} else {
0.
}
}
}; I'm passing f32::MAX when creating the buffer. For But text alignment correction is In my case I'm passing, effectively, "infinity" as the width, but if Since every glyph is horizontally offset by |
I did not see this mentioned, but I'm fairly certain there are some scenarios where layout needs to continue after wrapping to determine the exact width. I.e. if the UI layout algorithm needs the minimum width that the text will fit in, it is useful to continue since wrapped text won't necessarily be as wide as the width limit that forced it to wrap. For instance, consider text consisting of just two words that slightly exceed the width limit such that the second word will be placed on a new line. In this case, the difference between the width of the wrapped text (which is the width of the larger word) and the width used as a limit can be quite significant. I can see how the difference would be negligible when there are many lines of wrapped text (so there is likely a line that almost fills the space) or the width limit is relatively large compared to typical words. So in scenarios like these or where UI layouting doesn't actually need the minimum width, it seems like skipping further layout work can be quite useful. It might be interesting to have UI layout code that heuristically switches to the more efficient method when processing large pieces of text or to have a way to short-circuit width measurement if it reaches a certain threshold after wrapping is accounted for 🤔 |
I've written up a pseudo-RFC with a potential API for measurement (where using I think it is rough in some respects and could benefit from examination, input, and alternative ideas. Especially, wrt the "awkward workflow" drawback and the unresolved question. |
This will be handled in #70. |
Currently you have to set the Buffer dimensions before shaping. But it is common requirement to size a box containing some text based on the size of the text itself. It would therefore be great if it were possible to shape/layout with one or both dimensions being unset/infinite (it should be possible to independently set each dimension to infinite).
This could be represented with an
Option<i32>
(orOption<u32>
- does a negative buffer size make sense?) or possibly just anf32
, making use of the floating pointInfinity
value.The text was updated successfully, but these errors were encountered: