[Webkit-unassigned] [Bug 179682] Incorrect bounds inside <mover>/<munder> when a stretchy operator is present

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Wed Nov 29 00:12:37 PST 2017


--- Comment #28 from Frédéric Wang (:fredw) <fred.wang at free.fr> ---
@Minsheng: I believe things are becoming complicated but we have made some progress. We should keep in mind that the code must be readable, so mixing too many special cases and stretch width computation in the same loop or departing too much from the official spec is not a good idea. Sorry if I added more confusion with my suggestion (BTW, I really meant to skip *stretchy* children). Let's forget what was discussed above for now and focused on a simpler approach, which I believe is closer to Gecko & the spec. What do you think of this:

1) First add isStretchWidthLocked() into the helper function. That way, the algorithm will just treat such operators as non-stretchy and will never reset their stretch size or lock them again (hence you don't need a counter for it). 

static RenderMathMLOperator* toHorizontalStretchyOperator(RenderBox* box)
            if (renderOperator->isStretchy() && !renderOperator->isVertical() && !renderOperator->isStretchWidthLocked())
                return renderOperator;

2) Let's calculate the stretch width in one loop. Instead of calculating the size of the whole embellished operator as I suggested, let's take the unstretched size of the <mo> at the core. I think this is what Gecko does and will follow what you like in edge cases like in comment 22. Also, that will render attachment 327649 as we want. Finally, we will not "Skip the embellished op" although I'm still not sure what this comment was about so we may just remove it. Last, but not least this avoids to do the costly lock & relayout.

// The stretch size is calculated by taking the maximum widths of children.
// For stretchy (possibly embellished) operators, the unstretched size of the <mo> operator at the core is considered.
// This allows to satisfy the following rules from the MathML specification:
// a) "cover the width of the other direct sub-expressions in the given element"
// b) "If a stretchy operator is required to stretch, but all other expressions in the containing element [...] 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"
LayoutUnit stretchWidth = 0;
Vector<RenderBox*, 3> embellishedOperators;
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    if (auto renderOperator = toHorizontalStretchyOperator(child)) {
        stretchWidth = std::max(stretchWidth, renderOperator->logicalWidth());
    } else {
        stretchWidth = std::max(stretchWidth, child->logicalWidth());

3) Finally, let's stretch the embellished operators in one loop.

// Now that the stretch width has been calculated, let's stretch the (possibly embellished) operators and relayout them.
// Note that we lock the stretch width of the <mo> elements at the core of embellished operators so that the stretch size is not modified during the relayout e.g. in
// <munder>
//   <mtext>Base</mtext>
//   <munder>
//      <mtext>LoooongBaaaaase</mtext>
//      <mo>_</mo>
//   </munder>
// </munder>
for (auto& child : embellishedOperators) {
    auto renderOperator = toHorizontalStretchyOperator(child);

Can you please test the code above and tell me the result? I haven't tried it, so I may have made mistakes...

You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20171129/60a621ff/attachment-0001.html>

More information about the webkit-unassigned mailing list