-
Notifications
You must be signed in to change notification settings - Fork 30
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
Floated boxes (CSS Floats) #99
Comments
It's not clear to me why this is necessary. If float positioning is delegated to a higher level layout engine, the only thing Parley needs to know is where a line can start and where a line can end. The high level layout engine can just compute the location of the floats and fill the remaining space with text. This would even work with non-square floats, such as floats with a |
@wfdewith It's because the position of the float depends on line-breaking. The position of a float is not specified in terms of pixels, it's specified as an index into the string of text that makes up a paragraph, and the position of float's top edge (y offset) is floored by the position of the top of the line of text that it belongs. Which you can only work out by running the line-breaking algorithm (which is of course something that Parley does). I believe it also depends on the remaining space within that line when it encountered. So if you have:
Then the float will be pushed to the next line if it doesn't fit on the line in the space left after "text before the float" has already been laid out. |
I see now, it does make a difference when placing floats in the middle of the text. I'm still not sure what the exact behavior is supposed to be, but I'll try to figure that out.
Ah right, it makes sense to want to support that, but as far as I know you can't make floats like the one below with just CSS, unless there is some trick I'm not aware of. |
The rules are here: https://www.w3.org/TR/CSS22/visuren.html#float-position. But you'll probably find that isn't enough to fully grok how it works. I'd recommend: reading that a few times, reading some other articles on float positioning, and playing around with test snippets of HTML. I would also add that we could start with an implementation that isn't perfect and evolve it towards actually being compliant. I have a very early start of support in Taffy here: https://github.com/DioxusLabs/taffy/blob/float-layout/src/compute/float.rs. I should probably do a write up for the Taffy side like I've done for Parley. The
Yeah, you can't really do that. The text can only flow around one side. There are some kinda tricks as detailed here https://stackoverflow.com/a/41004410, but it involves duplicating content. The CSS specs for this https://drafts.csswg.org/css-exclusions/ and https://drafts.csswg.org/css-shapes-2/ haven't been finalised or widely implemented yet. |
This issue tracks the implementation of CSS Floats in Parley (/API enhancements that enable CSS Floats to be implemented on top of Parley).
Code Flow
If we go with the latter option (APIs that enable Floats to implemented on top of Parley) then I think the requirements for Parley itself might actually be quite simple. Parley would need to:
Allow the
max_advance
to be set independently for each lineWhen a float is present it takes up space meaning that the line is effectively shorter as far as line-breaking is concerned.
Allow each line's Y position to set as a parameter.
Floats may take up all of the space in a line, meaning a line should start further down that it otherwise should.
Allow each line to have an horizontal
offset
(set externally).This would be similar to the offset used for end/center alignment, but would be in addition to it (this is to account for
left
floats which cause the text on lines they intersect to be shifted to the right).To be able to yield control flow when a "floated box" is encountered in the layout. A "floated box" would be specified like the existing "inline boxes" but a simple enum field would be added to specify whether the box is "inline" or "floated".
Parley would not necessarily need to be able to compute the correct position for the box. But it should yield to external code, making available the following information:
Use the per-line
max_advance
(or a separately specified alignment width) for alignmentThe wider layout engine (that handles both box layout and text layout) would then be responsible for:
max_advance
andoffset
of the current line. Parley would be able to rely on the invariant that the newmax_advance
would be greater than the already-consumed space (and should perhaps enforce that).Parley API
In concrete API terms this would probably look like:
BreakLines::break_next
would layout up to "the end of the line OR the next floated box". Returning the reason for which it has yielded (line end or floated box).BreakLines
allowing callers to access the current state of the breaker for the purpose of positioning floated boxes (making this a separate method would keep it out of the way for the float-free case).BreakLines
to set theoffset
andmax_advance
of the current line. And to commit the current line.BreakLines::break_remaining
would become the simple implementation ignoring floatsbreak_remaining
but float-aware would be added. Or it would be left up to external code to implement this itself on top ofbreak_next
.Appendix A: The position of the floated box
The position of the floated box would be either:
float: right
). In this case:float: left
). In this case:The text was updated successfully, but these errors were encountered: