-
Notifications
You must be signed in to change notification settings - Fork 19
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
Layout of container with only stretchy children #124
Comments
The exception seems slightly strange really. it seems to say that if you have an mrow that just consists of (omitting the markup)
then all the delimiters stretch based on the maximum unstretched size of each delimiter. But
then each delimiter is stretched independently to cover just the Treating the first as if there was say an empty |
The idea behind this rule is that some stretchy chars may have short default versions and others somewhat taller ones. If the short one was on the outside (in the same mrow), then it would look poor if it didn't grow to cover the inner ones. Having said that, in David's examples, it is likely (hopefully) that each pair of bracketing chars in it's own mrow. If true, then the rule only applies to the Of course, one can construct a time consuming case with hundreds of stretchy chars, but it would not be remotely realistic. In practice, you could probably skip this case as the need to stretch beyond the default size if there are only stretchy chars is extermely remote. |
These exceptions require extra code and (conformance/fuzz) testing to ensure that the most general cases with complex embellished operators are properly handled. So the statement that in practice there are only trivial edge cases with two operators is actually an argument to remove/simplify them. For the "only stretchy children", why can't one just use a fixed multiple of font metrics (e.g. 1.5em) as the minimum size if the goal is just to avoid inconsistent unstretched size? In practice, if fonts have large unstretched sizes for operator then these characters will already look weird before you even try to use them in this MathML edge case. Or if the "only stretchy children" case is not important at all then I would suggest just skipping operator stretching in the container. The horizontal case (munder/mover/mundeover with only stretchy children) seems slightly different than the vertical one though. What are the concrete use cases? |
This is really oversimplified and does not correspond to browser layout... You don't have "char" but child nodes and to get the "size" of a child you need to perform layout on it. And again, embellished operators are complex, can be of arbitrary size, involves embellished & space-like definitions. We need a lot of test cases to check that things are laid out correctly, that you have correct preferred width, that rendering is updated after dynamic changes etc. Currently non-stretchy children are laid out to measure the target size and then the embellished stretchy operators are laid out with that size. But in the all-stretchy cases, children must be laid out twice (first without stretching and then with stretching): All of this has been causing bugs and issues in WebKit and Gecko in the past so I doubt it is as simple as just reading a minimal size from the font metrics or just skipping stretching. I'm not questioning whether that's technically possible, I just want to be sure that we don't add extra implementation/testing costs for something that so far does not seem really useful.
Well you are just explaining the spec with a somewhat artificial example. I still don't see any concrete use case that would justify two layout passes. So sorry I'm still not convinced :-/ |
Another issue to consider here:
If mrow1 lays out mrow2 without any stretch constraint in order to get an unstreched size, mrow2 will still try to perform operator stretching on the mo element. I guess a solution would be that mrow1 passes 0 as a target size or extend the stretch constraint with a definition of "do not stretch". |
I do not see what you think is a problem. Where would the size constraint on mrow1 (or any mrow) come from? You can't set it on I'm probably misunderstanding what you are getting at. Can you explain in more detail about the stretch constraints? |
CSS layout constraints are passed from top to bottom. |
This is explained in https://mathml-refresh.github.io/mathml-core/#dfn-algorithm-for-stretching-operators-along-the-block-axis ;
If we modify the algo to make mrow1 first determine the unstretched size of mrow2 in order to calculate the stretch size, then we cannot just layout mrow2 without stretch constraint for that purpose. Otherwise mrow2 will skip 1 (no stretch constraint) will do 2 (layout mspace) and will finally arrive to 5.3 that is layout mo with the stretch constraint calculated from the mspace height. But we want the unstretched size of mrow2! Anyway, I don't want to spend time during the next meeting to explain the stretch algo againn. I think the question here is just whether people want to include the unstretched size or not. And if they do want it, |
Consensus from 2019/11/11: Pass a 0 target size when calculating unstretched sizes, to avoid issues with nested embellished operators |
These are the general rules from MathML3:
https://mathml-refresh.github.io/mathml/#horizontal-stretching-rules
"should stretch to cover the width of the other direct sub-expressions in the given element"
https://mathml-refresh.github.io/mathml/#vertical-stretching-rules
"should stretch to cover the height and depth (above and below the axis) of the non-stretchy direct sub-expressions in the mrow element"
And the exception when all the children are stretchy:
https://mathml-refresh.github.io/mathml/#rules-common-to-both-vertical-and-horizontal-stretching
"If a stretchy operator is required to stretch, but all other expressions in the containing element (as described above) are also stretchy, all elements that can stretch should grow to the maximum of the normal unstretched sizes of all elements in the containing object, if they can grow that large."
Currently MathML Core implements this exception for horizontal layout but not for vertical layout:
https://mathml-refresh.github.io/mathml-core/#algorithm-for-stretching-operators-along-the-inline
https://mathml-refresh.github.io/mathml-core/#algorithm-for-stretching-operators-along-the-block-axis
With this exception, when all the children are stretchy they have to be laid out twice: A first time without a stretch constraint and a second time with a stretch constraint. Note that these children are not just single-character operator but can be embellished operators corresponding a to a subtree of arbitrary size (fortunately, the stretching algorithms never happen again in this subtree).
I'm opening this issue to know how important this case is. Can we avoid this second layout by using a fixed minimum ascent/width instead e.g. 1.5em?
The text was updated successfully, but these errors were encountered: