示例#1
0
void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge)
{
    dirtyForLayoutFromPercentageHeightDescendants(layoutScope);

    RenderBox* next = firstChildBox();
    RenderBox* lastNormalFlowChild = 0;

    while (next) {
        RenderBox* child = next;
        next = child->nextSiblingBox();

        // FIXME: this should only be set from clearNeedsLayout crbug.com/361250
        child->setLayoutDidGetCalled(true);

        updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);

        if (child->isOutOfFlowPositioned()) {
            child->containingBlock()->insertPositionedObject(child);
            adjustPositionedBlock(child);
            continue;
        }

        // Lay out the child.
        layoutBlockChild(child);
        lastNormalFlowChild = child;
    }

    // Negative margins can cause our height to shrink below our minimal height (border/padding).
    // If this happens, ensure that the computed height is increased to the minimal height.
    setLogicalHeight(std::max(logicalHeight() + afterEdge, beforeEdge + afterEdge));
}
示例#2
0
RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutChildren)
{
    if (!m_flowThread)
        return 0;
    
    // Update the sizes of our regions (but not the placement) before we lay out the flow thread.
    // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
    // instead of trying to keep them around.
    bool shouldInvalidateRegions = false;
    for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
        if (childBox == m_flowThread)
            continue;
        
        if (relayoutChildren || childBox->needsLayout()) {
            childBox->updateLogicalWidth();
            childBox->updateLogicalHeight();
            shouldInvalidateRegions = true;
        }
    }
    
    if (shouldInvalidateRegions)
        m_flowThread->invalidateRegions();

    if (relayoutChildren)
        m_flowThread->setChildNeedsLayout(true, MarkOnlyThis);
    
    setLogicalTopForChild(m_flowThread, borderBefore() + paddingBefore());
    m_flowThread->layoutIfNeeded();
    determineLogicalLeftPositionForChild(m_flowThread);
    
    return m_flowThread;
}
示例#3
0
RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutChildren)
{
    if (!m_flowThread)
        return 0;
    
    // Update the dimensions of our regions before we lay out the flow thread.
    // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
    // instead of trying to keep them around.
    bool shouldInvalidateRegions = false;
    for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
        if (childBox == m_flowThread)
            continue;

        if (relayoutChildren || childBox->needsLayout()) {
            if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
                toRenderMultiColumnSet(childBox)->prepareForLayout();
            shouldInvalidateRegions = true;
        }
    }
    
    if (shouldInvalidateRegions)
        m_flowThread->invalidateRegions();

    if (relayoutChildren)
        m_flowThread->setChildNeedsLayout(MarkOnlyThis);
    
    setLogicalTopForChild(*m_flowThread, borderAndPaddingBefore());
    m_flowThread->layoutIfNeeded();
    determineLogicalLeftPositionForChild(*m_flowThread);
    
    return m_flowThread;
}
void RenderMathMLPadded::layoutBlock(bool relayoutChildren, LayoutUnit)
{
    ASSERT(needsLayout());

    if (!relayoutChildren && simplifiedLayout())
        return;

    // We first layout our children as a normal <mrow> element.
    LayoutUnit contentAscent, contentDescent, contentWidth;
    contentAscent = contentDescent = 0;
    RenderMathMLRow::computeLineVerticalStretch(contentAscent, contentDescent);
    RenderMathMLRow::layoutRowItems(contentAscent, contentDescent);
    contentWidth = logicalWidth();

    // We parse the mpadded attributes using the content metrics as the default value.
    LayoutUnit width = contentWidth;
    LayoutUnit ascent = contentAscent;
    LayoutUnit descent = contentDescent;
    LayoutUnit lspace = 0;
    LayoutUnit voffset = 0;
    resolveAttributes(width, ascent, descent, lspace, voffset);

    // Align children on the new baseline and shift them by (lspace, -voffset)
    LayoutPoint contentLocation(lspace, ascent - contentAscent - voffset);
    for (auto* child = firstChildBox(); child; child = child->nextSiblingBox())
        child->setLocation(child->location() + contentLocation);

    // Set the final metrics.
    setLogicalWidth(width);
    m_ascent = ascent;
    setLogicalHeight(ascent + descent);

    clearNeedsLayout();
}
bool RenderMathMLFraction::isValid() const
{
    // Verify whether the list of children is valid:
    // <mfrac> numerator denominator </mfrac>
    auto* child = firstChildBox();
    if (!child)
        return false;
    child = child->nextSiblingBox();
    return child && !child->nextSiblingBox();
}
int RenderView::docWidth() const
{
    int w = rightmostPosition();

    for (RenderBox* c = firstChildBox(); c; c = c->nextSiblingBox()) {
        int dw = c->width() + c->marginLeft() + c->marginRight();
        if (dw > w)
            w = dw;
    }

    return w;
}
示例#7
0
int RenderView::docWidth(int leftOverflow) const
{
    int w = m_bodyIsLTR ? rightmostPosition() : width() - leftOverflow;

    for (RenderBox* c = firstChildBox(); c; c = c->nextSiblingBox()) {
        int dw = c->width() + c->marginLeft() + c->marginRight();
        if (dw > w)
            w = dw;
    }

    return w;
}
示例#8
0
size_t RenderGrid::maximumIndexInDirection(TrackSizingDirection direction) const
{
    const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows();

    size_t maximumIndex = trackStyles.size();

    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
        GridPosition position = (direction == ForColumns) ? child->style()->gridItemColumn() : child->style()->gridItemRow();
        maximumIndex = std::max(maximumIndex, resolveGridPosition(position) + 1);
    }

    return maximumIndex;
}
示例#9
0
LayoutUnit RenderGrid::computePreferredTrackWidth(const Length& length, size_t trackIndex) const
{
    if (length.isFixed()) {
        // Grid areas don't have borders, margins or paddings so we don't need to account for them.
        return length.intValue();
    }

    if (length.isMinContent()) {
        LayoutUnit minContentSize = 0;
        // FIXME: It's inefficient to iterate over our grid items. We should be able to
        // get the subset of grid items in the current row / column faster.
        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
            size_t cellIndex = resolveGridPosition(ForColumns, child);
            if (cellIndex != trackIndex)
                continue;

            // FIXME: We should include the child's fixed margins like RenderFlexibleBox.
            minContentSize = std::max(minContentSize, child->minPreferredLogicalWidth());
        }
        return minContentSize;
    }

    if (length.isMaxContent()) {
        LayoutUnit maxContentSize = 0;
        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
            size_t cellIndex = resolveGridPosition(ForColumns, child);
            if (cellIndex != trackIndex)
                continue;

            // FIXME: We should include the child's fixed margins like RenderFlexibleBox.
            maxContentSize = std::max(maxContentSize, child->maxPreferredLogicalWidth());
        }
        return maxContentSize;
    }

    // FIXME: css3-sizing mentions that we should resolve "definite sizes"
    // (including <percentage> and calc()) but we don't do it elsewhere.
    return 0;
}
bool RenderMathMLRoot::isValid() const
{
    // Verify whether the list of children is valid:
    // <msqrt> child1 child2 ... childN </msqrt>
    // <mroot> base index </mroot>
    if (m_kind == SquareRoot)
        return true;

    ASSERT(m_kind == RootWithIndex);
    auto* child = firstChildBox();
    if (!child)
        return false;
    child = child->nextSiblingBox();
    return child && !child->nextSiblingBox();
}
示例#11
0
int RenderView::docHeight() const
{
    int h = lowestPosition();

    // FIXME: This doesn't do any margin collapsing.
    // Instead of this dh computation we should keep the result
    // when we call RenderBlock::layout.
    int dh = 0;
    for (RenderBox* c = firstChildBox(); c; c = c->nextSiblingBox())
        dh += c->height() + c->marginTop() + c->marginBottom();

    if (dh > h)
        h = dh;

    return h;
}
示例#12
0
void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, size_t i, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction)
{
    GridTrack& track = (direction == ForColumns) ? columnTracks[i] : rowTracks[i];
    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
        size_t cellIndex = resolveGridPosition(direction, child);
        if (cellIndex != i)
            continue;

        LayoutUnit contentSize = (this->*sizingFunction)(child, direction, columnTracks);
        LayoutUnit additionalBreadthSpace = contentSize - (track.*trackGetter)();
        Vector<GridTrack*> tracks;
        tracks.append(&track);
        // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadth|.
        distributeSpaceToTracks(tracks, &tracks, trackGetter, trackGrowthFunction, additionalBreadthSpace);
    }
}
示例#13
0
void RenderFrameSet::positionFrames()
{
    RenderBox* child = firstChildBox();
    if (!child)
        return;

    int rows = frameSetElement().totalRows();
    int cols = frameSetElement().totalCols();

    int yPos = 0;
    int borderThickness = frameSetElement().border();
    for (int r = 0; r < rows; r++) {
        int xPos = 0;
        int height = m_rows.m_sizes[r];
        for (int c = 0; c < cols; c++) {
            child->setLocation(IntPoint(xPos, yPos));
            int width = m_cols.m_sizes[c];

            // has to be resized and itself resize its contents
            if (width != child->width() || height != child->height()) {
                child->setWidth(width);
                child->setHeight(height);
#if PLATFORM(IOS)
                // FIXME: Is this iOS-specific?
                child->setNeedsLayout(MarkOnlyThis);
#else
                child->setNeedsLayout();
#endif
                child->layout();
            }

            xPos += width + borderThickness;

            child = child->nextSiblingBox();
            if (!child)
                return;
        }
        yPos += height + borderThickness;
    }

    // all the remaining frames are hidden to avoid ugly spurious unflowed frames
    for (; child; child = child->nextSiblingBox()) {
        child->setWidth(0);
        child->setHeight(0);
        child->clearNeedsLayout();
    }
}
示例#14
0
void RenderFrameSet::positionFrames()
{
    RenderBox* child = firstChildBox();
    if (!child)
        return;

    int rows = frameSet()->totalRows();
    int cols = frameSet()->totalCols();

    int yPos = 0;
    int borderThickness = frameSet()->border();
    for (int r = 0; r < rows; r++) {
        int xPos = 0;
        int height = m_rows.m_sizes[r];
        for (int c = 0; c < cols; c++) {
            child->setLocation(xPos, yPos);
            int width = m_cols.m_sizes[c];

            // has to be resized and itself resize its contents
            if (width != child->width() || height != child->height()) {
                child->setWidth(width);
                child->setHeight(height);
                child->setNeedsLayout(true);
                child->layout();
            }

            xPos += width + borderThickness;

            child = child->nextSiblingBox();
            if (!child)
                return;
        }
        yPos += height + borderThickness;
    }

    // all the remaining frames are hidden to avoid ugly spurious unflowed frames
    for (; child; child = child->nextSiblingBox()) {
        child->setWidth(0);
        child->setHeight(0);
        child->setNeedsLayout(false);
    }
}
示例#15
0
void RenderGrid::layoutGridItems()
{
    Vector<GridTrack> columnTracks(maximumIndexInDirection(ForColumns));
    Vector<GridTrack> rowTracks(maximumIndexInDirection(ForRows));
    computedUsedBreadthOfGridTracks(ForColumns, columnTracks, rowTracks);
    ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, columnTracks));
    computedUsedBreadthOfGridTracks(ForRows, columnTracks, rowTracks);
    ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, rowTracks));

    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
        LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks);

        size_t columnTrack = resolveGridPosition(child->style()->gridItemColumn());
        size_t rowTrack = resolveGridPosition(child->style()->gridItemRow());

        // Because the grid area cannot be styled, we don't need to adjust
        // the grid breadth to account for 'box-sizing'.
        LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOverrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogicalWidth() : LayoutUnit();
        LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOverrideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogicalHeight() : LayoutUnit();

        if (oldOverrideContainingBlockContentLogicalWidth != columnTracks[columnTrack].m_usedBreadth || oldOverrideContainingBlockContentLogicalHeight != rowTracks[rowTrack].m_usedBreadth)
            child->setNeedsLayout(true, MarkOnlyThis);

        child->setOverrideContainingBlockContentLogicalWidth(columnTracks[columnTrack].m_usedBreadth);
        child->setOverrideContainingBlockContentLogicalHeight(rowTracks[rowTrack].m_usedBreadth);

        // FIXME: Grid items should stretch to fill their cells. Once we
        // implement grid-{column,row}-align, we can also shrink to fit. For
        // now, just size as if we were a regular child.
        child->layoutIfNeeded();

        // FIXME: Handle border & padding on the grid element.
        child->setLogicalLocation(childPosition);
    }

    for (size_t i = 0; i < rowTracks.size(); ++i)
        setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth);

    // FIXME: We should handle min / max logical height.

    setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight());
}
示例#16
0
void RenderSnapshottedPlugIn::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    if (paintInfo.phase == PaintPhaseForeground && plugInImageElement()->displayState() < HTMLPlugInElement::Restarting) {
        paintSnapshot(paintInfo, paintOffset);
    }

    PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
    newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;

    PaintInfo paintInfoForChild(paintInfo);
    paintInfoForChild.phase = newPhase;
    paintInfoForChild.updateSubtreePaintRootForChildren(this);

    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
        LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
        if (!child->hasSelfPaintingLayer() && !child->isFloating())
            child->paint(paintInfoForChild, childPoint);
    }

    RenderEmbeddedObject::paint(paintInfo, paintOffset);
}
示例#17
0
bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer& statePusher)
{
    if (m_inBalancingPass || !requiresBalancing())
        return false;
    m_inBalancingPass = true; // Prevent re-entering this method (and recursion into layout).

    bool needsRelayout;
    bool neededRelayout = false;
    bool firstPass = true;
    do {
        // Column heights may change here because of balancing. We may have to do multiple layout
        // passes, depending on how the contents is fitted to the changed column heights. In most
        // cases, laying out again twice or even just once will suffice. Sometimes we need more
        // passes than that, though, but the number of retries should not exceed the number of
        // columns, unless we have a bug.
        needsRelayout = false;
        for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox())
            if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) {
                RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
                if (multicolSet->calculateBalancedHeight(firstPass)) {
                    multicolSet->setChildNeedsLayout(MarkOnlyThis);
                    needsRelayout = true;
                }
            }

        if (needsRelayout) {
            // Layout again. Column balancing resulted in a new height.
            neededRelayout = true;
            m_flowThread->setChildNeedsLayout(MarkOnlyThis);
            setChildNeedsLayout(MarkOnlyThis);
            if (firstPass)
                statePusher.pop();
            layoutBlock(false);
        }
        firstPass = false;
    } while (needsRelayout);
    m_inBalancingPass = false;
    return neededRelayout;
}
示例#18
0
void Paragraph::paint(Canvas* canvas, double x, double y)
{
    SkCanvas* skCanvas = canvas->canvas();
    if (!skCanvas)
      return;

    FontCachePurgePreventer fontCachePurgePreventer;

    // Very simplified painting to allow painting an arbitrary (layer-less) subtree.
    RenderBox* box = firstChildBox();
    skCanvas->translate(x, y);

    GraphicsContext context(skCanvas);
    Vector<RenderBox*> layers;
    LayoutRect bounds = box->absoluteBoundingBoxRect();
    DCHECK(bounds.x() == 0 && bounds.y() == 0);
    PaintInfo paintInfo(&context, enclosingIntRect(bounds), box);
    box->paint(paintInfo, LayoutPoint(), layers);
    // Note we're ignoring any layers encountered.
    // TODO(abarth): Remove the concept of RenderLayers.

    skCanvas->translate(-x, -y);
}
示例#19
0
void RenderGrid::layoutGridItems()
{
    Vector<GridTrack> columnTracks, rowTracks;
    computedUsedBreadthOfGridTracks(ForColumns, columnTracks);
    // FIXME: The logical width of Grid Columns from the prior step is used in
    // the formatting of Grid items in content-sized Grid Rows to determine
    // their required height. We will probably need to pass columns through.
    computedUsedBreadthOfGridTracks(ForRows, rowTracks);

    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
        LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks);
        // FIXME: Grid items should stretch to fill their cells. Once we
        // implement grid-{column,row}-align, we can also shrink to fit. For
        // now, just size as if we were a regular child.
        child->layoutIfNeeded();

        // FIXME: Handle border & padding on the grid element.
        child->setLogicalLocation(childPosition);
    }

    // FIXME: Handle border & padding on the grid element.
    for (size_t i = 0; i < rowTracks.size(); ++i)
        setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth);
}
RenderBox& RenderMathMLFraction::numerator() const
{
    ASSERT(isValid());
    return *firstChildBox();
}
示例#21
0
void RenderMultiColumnBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    RenderBlockFlow::styleDidChange(diff, oldStyle);
    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox())
        child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
}
void RenderMathMLRoot::layoutBlock(bool relayoutChildren, LayoutUnit)
{
    ASSERT(needsLayout());

    if (!relayoutChildren && simplifiedLayout())
        return;

    updateStyle();
    m_radicalOperatorTop = 0;
    m_baseWidth = 0;

    if (!isValid()) {
        setLogicalWidth(0);
        setLogicalHeight(0);
        clearNeedsLayout();
        return;
    }

    // We layout the children, determine the vertical metrics of the base and set the logical width.
    // Note: Per the MathML specification, the children of <msqrt> are wrapped in an inferred <mrow>, which is the desired base.
    LayoutUnit baseAscent, baseDescent;
    recomputeLogicalWidth();
    if (m_kind == SquareRoot) {
        baseAscent = baseDescent;
        RenderMathMLRow::computeLineVerticalStretch(baseAscent, baseDescent);
        RenderMathMLRow::layoutRowItems(baseAscent, baseDescent);
        m_baseWidth = logicalWidth();
    } else {
        getBase().layoutIfNeeded();
        m_baseWidth = getBase().logicalWidth();
        baseAscent = ascentForChild(getBase());
        baseDescent = getBase().logicalHeight() - baseAscent;
        getIndex().layoutIfNeeded();
    }

    // Stretch the radical operator to cover the base height.
    // We can then determine the metrics of the radical operator + the base.
    m_radicalOperator.stretchTo(style(), baseAscent + baseDescent);
    LayoutUnit radicalOperatorHeight = m_radicalOperator.ascent() + m_radicalOperator.descent();
    LayoutUnit indexBottomRaise = m_degreeBottomRaisePercent * radicalOperatorHeight;
    LayoutUnit radicalAscent = baseAscent + m_verticalGap + m_ruleThickness + m_extraAscender;
    LayoutUnit radicalDescent = std::max<LayoutUnit>(baseDescent, radicalOperatorHeight + m_extraAscender - radicalAscent);
    LayoutUnit descent = radicalDescent;
    LayoutUnit ascent = radicalAscent;

    // We set the logical width.
    if (m_kind == SquareRoot)
        setLogicalWidth(m_radicalOperator.width() + m_baseWidth);
    else {
        ASSERT(m_kind == RootWithIndex);
        setLogicalWidth(m_kernBeforeDegree + getIndex().logicalWidth() + m_kernAfterDegree + m_radicalOperator.width() + m_baseWidth);
    }

    // For <mroot>, we update the metrics to take into account the index.
    LayoutUnit indexAscent, indexDescent;
    if (m_kind == RootWithIndex) {
        indexAscent = ascentForChild(getIndex());
        indexDescent = getIndex().logicalHeight() - indexAscent;
        ascent = std::max<LayoutUnit>(radicalAscent, indexBottomRaise + indexDescent + indexAscent - descent);
    }

    // We set the final position of children.
    m_radicalOperatorTop = ascent - radicalAscent + m_extraAscender;
    LayoutUnit horizontalOffset = m_radicalOperator.width();
    if (m_kind == RootWithIndex)
        horizontalOffset += m_kernBeforeDegree + getIndex().logicalWidth() + m_kernAfterDegree;
    LayoutPoint baseLocation(mirrorIfNeeded(horizontalOffset, m_baseWidth), ascent - baseAscent);
    if (m_kind == SquareRoot) {
        for (auto* child = firstChildBox(); child; child = child->nextSiblingBox())
            child->setLocation(child->location() + baseLocation);
    } else {
        ASSERT(m_kind == RootWithIndex);
        getBase().setLocation(baseLocation);
        LayoutPoint indexLocation(mirrorIfNeeded(m_kernBeforeDegree, getIndex()), ascent + descent - indexBottomRaise - indexDescent - indexAscent);
        getIndex().setLocation(indexLocation);
    }

    setLogicalHeight(ascent + descent);
    clearNeedsLayout();
}
RenderBox& RenderMathMLRoot::getBase() const
{
    ASSERT(isValid());
    ASSERT(m_kind == RootWithIndex);
    return *firstChildBox();
}
RenderBox& RenderMathMLRoot::getIndex() const
{
    ASSERT(isValid());
    ASSERT(m_kind == RootWithIndex);
    return *firstChildBox()->nextSiblingBox();
}
示例#25
0
void RenderFrameSet::positionFramesWithFlattening()
{
    RenderBox* child = firstChildBox();
    if (!child)
        return;

    int rows = frameSetElement().totalRows();
    int cols = frameSetElement().totalCols();

    int borderThickness = frameSetElement().border();
    bool repaintNeeded = false;

    // calculate frameset height based on actual content height to eliminate scrolling
    bool out = false;
    for (int r = 0; r < rows && !out; r++) {
        int extra = 0;
        int height = m_rows.m_sizes[r];

        for (int c = 0; c < cols; c++) {
            IntRect oldFrameRect = pixelSnappedIntRect(child->frameRect());

            int width = m_cols.m_sizes[c];

            bool fixedWidth = frameSetElement().colLengths() && frameSetElement().colLengths()[c].isFixed();
            bool fixedHeight = frameSetElement().rowLengths() && frameSetElement().rowLengths()[r].isFixed();

            // has to be resized and itself resize its contents
            if (!fixedWidth)
                child->setWidth(width ? width + extra / (cols - c) : 0);
            else
                child->setWidth(width);
            child->setHeight(height);

            child->setNeedsLayout();

            if (child->isFrameSet())
                toRenderFrameSet(child)->layout();
            else
                toRenderFrame(child)->layoutWithFlattening(fixedWidth, fixedHeight);

            if (child->height() > m_rows.m_sizes[r])
                m_rows.m_sizes[r] = child->height();
            if (child->width() > m_cols.m_sizes[c])
                m_cols.m_sizes[c] = child->width();

            if (child->frameRect() != oldFrameRect)
                repaintNeeded = true;

            // difference between calculated frame width and the width it actually decides to have
            extra += width - m_cols.m_sizes[c];

            child = child->nextSiblingBox();
            if (!child) {
                out = true;
                break;
            }
        }
    }

    int xPos = 0;
    int yPos = 0;
    out = false;
    child = firstChildBox();
    for (int r = 0; r < rows && !out; r++) {
        xPos = 0;
        for (int c = 0; c < cols; c++) {
            // ensure the rows and columns are filled
            IntRect oldRect = pixelSnappedIntRect(child->frameRect());

            child->setLocation(IntPoint(xPos, yPos));
            child->setHeight(m_rows.m_sizes[r]);
            child->setWidth(m_cols.m_sizes[c]);

            if (child->frameRect() != oldRect) {
                repaintNeeded = true;

                // update to final size
                child->setNeedsLayout();
                if (child->isFrameSet())
                    toRenderFrameSet(child)->layout();
                else
                    toRenderFrame(child)->layoutWithFlattening(true, true);
            }

            xPos += m_cols.m_sizes[c] + borderThickness;
            child = child->nextSiblingBox();
            if (!child) {
                out = true;
                break;
            }
        }
        yPos += m_rows.m_sizes[r] + borderThickness;
    }

    setWidth(xPos - borderThickness);
    setHeight(yPos - borderThickness);

    if (repaintNeeded)
        repaint();

    // all the remaining frames are hidden to avoid ugly spurious unflowed frames
    for (; child; child = child->nextSiblingBox()) {
        child->setWidth(0);
        child->setHeight(0);
        child->clearNeedsLayout();
    }
}
RenderBox& RenderMathMLFraction::denominator() const
{
    ASSERT(isValid());
    return *firstChildBox()->nextSiblingBox();
}