int RenderMathMLUnderOver::firstLineBaseline() const { RenderBox* base = firstChildBox(); if (!base) return -1; LayoutUnit baseline = base->firstLineBaseline(); if (baseline != -1) baseline += base->logicalTop(); return baseline; }
Optional<int> RenderMathMLUnderOver::firstLineBaseline() const { RenderBox* base = firstChildBox(); if (!base) return Optional<int>(); Optional<int> baseline = base->firstLineBaseline(); if (baseline) baseline.value() += static_cast<int>(base->logicalTop()); return baseline; }
void RenderMathMLScripts::layout() { RenderMathMLBlock::layout(); if (!m_baseWrapper) return; RenderBox* base = m_baseWrapper->firstChildBox(); if (!base) return; // Our layout rules include: Don't let the superscript go below the "axis" (half x-height above the // baseline), or the subscript above the axis. Also, don't let the superscript's top edge be // below the base's top edge, or the subscript's bottom edge above the base's bottom edge. LayoutUnit baseHeight = base->logicalHeight(); LayoutUnit baseBaseline = base->firstLineBaseline().valueOr(baseHeight); LayoutUnit axis = style().fontMetrics().xHeight() / 2; int fontSize = style().fontSize(); ASSERT(m_baseWrapper->style().hasOneRef()); bool needsSecondLayout = false; LayoutUnit topPadding = 0; LayoutUnit bottomPadding = 0; Element* scriptElement = element(); LayoutUnit superscriptShiftValue = 0; LayoutUnit subscriptShiftValue = 0; if (m_kind == Sub || m_kind == SubSup || m_kind == Multiscripts) parseMathMLLength(scriptElement->fastGetAttribute(MathMLNames::subscriptshiftAttr), subscriptShiftValue, &style(), false); if (m_kind == Super || m_kind == SubSup || m_kind == Multiscripts) parseMathMLLength(scriptElement->fastGetAttribute(MathMLNames::superscriptshiftAttr), superscriptShiftValue, &style(), false); bool isPostScript = true; RenderMathMLBlock* subSupPair = downcast<RenderMathMLBlock>(m_baseWrapper->nextSibling()); for (; subSupPair; subSupPair = downcast<RenderMathMLBlock>(subSupPair->nextSibling())) { // We skip the base and <mprescripts/> elements. if (isPrescript(*subSupPair)) { if (!isPostScript) break; isPostScript = false; continue; } if (RenderBox* superscript = m_kind == Sub ? 0 : subSupPair->lastChildBox()) { LayoutUnit superscriptHeight = superscript->logicalHeight(); LayoutUnit superscriptBaseline = superscript->firstLineBaseline().valueOr(superscriptHeight); LayoutUnit minBaseline = std::max<LayoutUnit>(fontSize / 3 + 1 + superscriptBaseline, superscriptHeight + axis + superscriptShiftValue); topPadding = std::max<LayoutUnit>(topPadding, minBaseline - baseBaseline); } if (RenderBox* subscript = m_kind == Super ? 0 : subSupPair->firstChildBox()) { LayoutUnit subscriptHeight = subscript->logicalHeight(); LayoutUnit subscriptBaseline = subscript->firstLineBaseline().valueOr(subscriptHeight); LayoutUnit baseExtendUnderBaseline = baseHeight - baseBaseline; LayoutUnit subscriptUnderItsBaseline = subscriptHeight - subscriptBaseline; LayoutUnit minExtendUnderBaseline = std::max<LayoutUnit>(fontSize / 5 + 1 + subscriptUnderItsBaseline, subscriptHeight + subscriptShiftValue - axis); bottomPadding = std::max<LayoutUnit>(bottomPadding, minExtendUnderBaseline - baseExtendUnderBaseline); } } Length newPadding(topPadding, Fixed); if (newPadding != m_baseWrapper->style().paddingTop()) { m_baseWrapper->style().setPaddingTop(newPadding); needsSecondLayout = true; } newPadding = Length(bottomPadding, Fixed); if (newPadding != m_baseWrapper->style().paddingBottom()) { m_baseWrapper->style().setPaddingBottom(newPadding); needsSecondLayout = true; } if (!needsSecondLayout) return; setNeedsLayout(MarkOnlyThis); m_baseWrapper->setChildNeedsLayout(MarkOnlyThis); RenderMathMLBlock::layout(); }