-
Notifications
You must be signed in to change notification settings - Fork 14
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
Avoid underestimation of min/max stretchy horizontal operators #123
Comments
I'm not a big fan of estimation, but if it is needed, I agree over estimation is better than under estimation in terms of it's consequences... except that in most cases, probably the smallest size character will be used (e.g., parens tend not to stretch unless there fractions or other tall notations in the expr). Hence, over estimation will almost always be wrong, likely significantly wrong. Is it possible to be more sophisticated in the estimate and take into account whether there are tall elements in the mrow (mfrac and mtable) in doing the estimate? Other options for a heuristic are to check for big operators, munder/over's that are nested or have a big operator at their core, nested roots, and likely others. At some point though, the time/complexity it takes to develop heuristics to improve the estimate leads one to say that one shouldn't do the estimate and instead should just do two passes so the widths are properly calculated. Bottom line: at least a few heuristics should be used for the estimate because using the max size is the worst possible choice in the vast majority of cases. |
@NSoiffer Let me highlight again these two points from my initial description:
Also, when we asked about this to Google last July, the last point is actually stronger:
AFAIK, these are general invariants for CSS / LayoutNG / CSS Layout API / browser implementations. I also understand it is possible to do "multi-pass layout" but that does not help here since the error happens during the preferred width computation not during layout. |
Some additional notes:
|
@fred-wang ah actually I think I knew that when you originally commented but clearly I merged these issues in my head this morning, I deleted my comment above to avoid confusion. So I'll repeat here what I said in the deleted comment, I'm happy to go with your suggestion at the start of this issue. |
I we want to #123 ; then I think preferred min should take into account minsize (% still resolved as multipled of preferred min for mo for unstretched size). |
Consensus from 2019/11/11: "When calculating the inline size of munder/mover/munderover, the unstretched size of horizontal stretchy embellished operators is used." There is a potential problem with minsize/maxsize but for now the core spec does not say anything about it: #64 |
I think we would need to be careful when a stretch size contrainst is passed to the element, as in that case we might prefer to use the passed constraint size for the base/element which may be significantly wider than the scripts e.g.
I believe the proposal would still work though since the embellished ancestor will calculate the proper width. However I'd postpone this change for a next version of core and keep the logic similar for inline/block stretching for now. We can see later how to refine it depending on the feedback during code upstreaming. |
cc @bfgeek
As you can see on the screenshot, with how math fonts are designed:
One can use scale transform to distort the glyph, but that would go against the will of the font designer and might give poor math rendering.
This has implications in min/max size computation (https://mathml-refresh.github.io/mathml-core/#layout-of-operators):
We cannot determine the preferred width of a vertical stretchy operator since vertical metrics are unknown during min/max size computation. MathML Core addresses that by taking the maximum of all widths. This may be an overestimation of the final width.
We cannot even determine the preferred width of a horizontal stretchy operators since we cannot use layout constraint during min/max size computation. MathML Core addresses that by taking the width of the unstretched operator. This may be an underestimation of the final width.
and has consequences for the rest of the page layout:
When the min/max size is overestimated, linebreaking might not be optimal. For example, an inline MathML formula in a paragraph of text can be moved to the next line even if there is enough room for it on the current line. Or a table cell containing a MathML formula might be larger than what is needed to contain the formula.
When the min/max size is underestimated, the situation is the opposite: the inline formula in a paragraph may overflow instead of forcing a line break and moving to the next line ; a MathML formula inside a table may overflow its containing cell.
I think overestimation is an acceptable approximation, at worst it adds some extra white space. Underestimation can cause more annoying overflow bugs, so should be preferably avoided. Hence I'd like to propose the following change:
( https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover )
(Note that these operators remain laid out with the stretched size and the horizontal position remains as defined in the spec)
This means that the width matches the min/max calculation and we get rid of the approximation error. Or said otherwise, we just have some possible overflow on each side of each munderover rather than an error accumulated for the min/max size of the math root.
Note that with MathML Core, one may already have to layout stretchy horizontal operators twice (when all children are of this kind) and per discussion in w3c/mathml#124, Neil thinks it is important to keep this anyway. (I would still prefer to avoid this second layout for vertical operators and keep the current description in MathML Core)
The text was updated successfully, but these errors were encountered: