Exemplo n.º 1
0
int RenderMathMLUnderOver::firstLineBaseline() const
{
    RenderBox* base = firstChildBox();
    if (!base)
        return -1;
    LayoutUnit baseline = base->firstLineBaseline();
    if (baseline != -1)
        baseline += base->logicalTop();
    return baseline;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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();
}