Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / rendering / mathml / RenderMathMLUnderOver.cpp
index e07d1cc..b0c34c0 100644 (file)
 
 #include "RenderMathMLUnderOver.h"
 
+#include "MathMLElement.h"
 #include "MathMLNames.h"
+#include "RenderIterator.h"
+#include "RenderMathMLOperator.h"
 
 namespace WebCore {
 
 using namespace MathMLNames;
     
-RenderMathMLUnderOver::RenderMathMLUnderOver(Element* element)
-    : RenderMathMLBlock(element)
+RenderMathMLUnderOver::RenderMathMLUnderOver(Element& element, Ref<RenderStyle>&& style)
+    : RenderMathMLBlock(element, WTFMove(style))
 {
     // Determine what kind of under/over expression we have by element name
-    if (element->hasLocalName(MathMLNames::munderTag))
+    if (element.hasTagName(MathMLNames::munderTag))
         m_kind = Under;
-    else if (element->hasLocalName(MathMLNames::moverTag))
+    else if (element.hasTagName(MathMLNames::moverTag))
         m_kind = Over;
     else {
-        ASSERT(element->hasLocalName(MathMLNames::munderoverTag));
+        ASSERT(element.hasTagName(MathMLNames::munderoverTag));
         m_kind = UnderOver;
     }
 }
 
-RenderBoxModelObject* RenderMathMLUnderOver::base() const
-{
-    RenderObject* baseWrapper = firstChild();
-    if ((m_kind == Over || m_kind == UnderOver) && baseWrapper)
-        baseWrapper = baseWrapper->nextSibling();
-    if (!baseWrapper)
-        return 0;
-    RenderObject* base = baseWrapper->firstChild();
-    if (!base || !base->isBoxModelObject())
-        return 0;
-    return toRenderBoxModelObject(base);
-}
-
-void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeChild)
-{    
-    RenderMathMLBlock* row = createAnonymousMathMLBlock();
-    
-    // look through the children for rendered elements counting the blocks so we know what child
-    // we are adding
-    int blocks = 0;
-    RenderObject* current = this->firstChild();
-    while (current) {
-        blocks++;
-        current = current->nextSibling();
-    }
-    
-    switch (blocks) {
-    case 0:
-        // this is the base so just append it
-        RenderBlock::addChild(row, beforeChild);
-        break;
-    case 1:
-        // the under or over
-        row->style()->setTextAlign(CENTER);
-        if (m_kind == Over) {
-            // add the over as first
-            RenderBlock::addChild(row, firstChild());
-        } else {
-            // add the under as last
-            RenderBlock::addChild(row, beforeChild);
-        }
-        break;
-    case 2:
-        // the under or over
-        row->style()->setTextAlign(CENTER);
-        if (m_kind == UnderOver) {
-            // add the over as first
-            RenderBlock::addChild(row, firstChild());
-        } else {
-            // we really shouldn't get here as only munderover should have three children
-            RenderBlock::addChild(row, beforeChild);
-        }
-        break;
-    default:
-        // munderover shouldn't have more than three children. In theory we shouldn't 
-        // get here if the MathML is correctly formed, but that isn't a guarantee.
-        // We will treat this as another under element and they'll get something funky.
-        RenderBlock::addChild(row, beforeChild);
-    }
-    row->addChild(child);    
-}
-
-void RenderMathMLUnderOver::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
-    RenderMathMLBlock::styleDidChange(diff, oldStyle);
-    
-    RenderObject* base = this->base();
-    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
-        ASSERT(child->isAnonymous() && child->style()->refCount() == 1);
-        if (child->firstChild() != base)
-            child->style()->setTextAlign(CENTER);
-    }
-}
-
 RenderMathMLOperator* RenderMathMLUnderOver::unembellishedOperator()
 {
-    RenderBoxModelObject* base = this->base();
-    if (!base || !base->isRenderMathMLBlock())
-        return 0;
-    return toRenderMathMLBlock(base)->unembellishedOperator();
+    RenderObject* base = firstChild();
+    if (!is<RenderMathMLBlock>(base))
+        return nullptr;
+    return downcast<RenderMathMLBlock>(*base).unembellishedOperator();
 }
 
-inline int getOffsetHeight(RenderObject* obj) 
+Optional<int> RenderMathMLUnderOver::firstLineBaseline() const
 {
-    if (obj->isBoxModelObject()) {
-        RenderBoxModelObject* box = toRenderBoxModelObject(obj);
-        return box->pixelSnappedOffsetHeight();
-    }
-   
-    return 0;
+    RenderBox* base = firstChildBox();
+    if (!base)
+        return Optional<int>();
+    Optional<int> baseline = base->firstLineBaseline();
+    if (baseline)
+        baseline.value() += static_cast<int>(base->logicalTop());
+    return baseline;
 }
 
-LayoutUnit RenderMathMLUnderOver::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+void RenderMathMLUnderOver::layout()
 {
-    RenderObject* current = firstChild();
-    if (!current || linePositionMode == PositionOfInteriorLineBoxes)
-        return RenderMathMLBlock::baselinePosition(baselineType, firstLine, direction, linePositionMode);
-
-    LayoutUnit baseline = direction == HorizontalLine ? marginTop() : marginRight();
-    switch (m_kind) {
-    case UnderOver:
-    case Over:
-        if (current->nextSibling()) {
-            baseline += getOffsetHeight(current);
-            current = current->nextSibling();
+    LayoutUnit stretchWidth = 0;
+    Vector<RenderMathMLOperator*, 2> renderOperators;
+
+    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+        if (child->needsLayout()) {
+            if (is<RenderMathMLBlock>(child)) {
+                if (auto renderOperator = downcast<RenderMathMLBlock>(*child).unembellishedOperator()) {
+                    if (!renderOperator->isVertical()) {
+                        renderOperator->resetStretchSize();
+                        renderOperators.append(renderOperator);
+                    }
+                }
+            }
+
+            downcast<RenderElement>(*child).layout();
         }
-        // fall through
-    case Under:
-        ASSERT(current->isRenderBlock());
-        baseline += toRenderBox(current)->firstLineBoxBaseline();
+
+        // Skipping the embellished op does not work for nested structures like
+        // <munder><mover><mo>_</mo>...</mover> <mo>_</mo></munder>.
+        if (is<RenderBox>(*child))
+            stretchWidth = std::max<LayoutUnit>(stretchWidth, downcast<RenderBox>(*child).logicalWidth());
     }
 
-    return baseline;
+    // Set the sizes of (possibly embellished) stretchy operator children.
+    for (auto& renderOperator : renderOperators)
+        renderOperator->stretchTo(stretchWidth);
+
+    RenderMathMLBlock::layout();
 }
 
 }