⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderblock.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if (marginInfo.bottomQuirk() && marginBottom() == 0)            // We have no bottom margin and our last child has a quirky margin.            // We will pick up this quirky margin and pass it through.            // This deals with the <td><div><p> case.            setBottomMarginQuirk(true);    }}void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInfo){    // If our last flow was a self-collapsing block that cleared a float, then we don't    // collapse it with the bottom of the block.    if (!marginInfo.selfCollapsingBlockClearedFloat())        marginInfo.setAtBottomOfBlock(true);    else {        // We have to special case the negative margin situation (where the collapsed        // margin of the self-collapsing block is negative), since there's no need        // to make an adjustment in that case.        if (marginInfo.margin() < 0)            marginInfo.clearMargin();    }    // If we can't collapse with children then go ahead and add in the bottom margin.    if (!marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()        && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.bottomQuirk()))        setHeight(height() + marginInfo.margin());            // Now add in our bottom border/padding.    setHeight(height() + bottom);    // 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.    setHeight(max(height(), top + bottom));    // Always make sure our overflow height is at least our height.    m_overflowHeight = max(height(), m_overflowHeight);    // Update our bottom collapsed margin info.    setCollapsedBottomMargin(marginInfo);}void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom){    if (gPercentHeightDescendantsMap) {        if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {            HashSet<RenderBox*>::iterator end = descendants->end();            for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {                RenderBox* box = *it;                while (box != this) {                    if (box->normalChildNeedsLayout())                        break;                    box->setChildNeedsLayout(true, false);                    box = box->containingBlock();                    ASSERT(box);                    if (!box)                        break;                }            }        }    }    int top = borderTop() + paddingTop();    int bottom = borderBottom() + paddingBottom() + horizontalScrollbarHeight();    m_overflowHeight = top;    setHeight(m_overflowHeight);    // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,    MarginInfo marginInfo(this, top, bottom);    // Fieldsets need to find their legend and position it inside the border of the object.    // The legend then gets skipped during normal layout.    RenderObject* legend = layoutLegend(relayoutChildren);    int previousFloatBottom = 0;    maxFloatBottom = 0;    RenderBox* child = firstChildBox();    while (child) {        if (legend == child) {            child = child->nextSiblingBox();            continue; // Skip the legend, since it has already been positioned up in the fieldset's border.        }        int oldTopPosMargin = maxTopPosMargin();        int oldTopNegMargin = maxTopNegMargin();        // Make sure we layout children if they need it.        // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into        // an auto value.  Add a method to determine this, so that we can avoid the relayout.        if (relayoutChildren || ((child->style()->height().isPercent() || child->style()->minHeight().isPercent() || child->style()->maxHeight().isPercent()) && !isRenderView()))            child->setChildNeedsLayout(true, false);        // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.        if (relayoutChildren && (child->style()->paddingLeft().isPercent() || child->style()->paddingRight().isPercent()))            child->setPrefWidthsDirty(true, false);        // Handle the four types of special elements first.  These include positioned content, floating content, compacts and        // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.        bool handled = false;        RenderBox* next = handleSpecialChild(child, marginInfo, handled);        if (handled) {            child = next;            continue;        }        // The child is a normal flow object.  Compute its vertical margins now.        child->calcVerticalMargins();        // Do not allow a collapse if the margin top collapse style is set to SEPARATE.        if (child->style()->marginTopCollapse() == MSEPARATE) {            marginInfo.setAtTopOfBlock(false);            marginInfo.clearMargin();        }        // Try to guess our correct y position.  In most cases this guess will        // be correct.  Only if we're wrong (when we compute the real y position)        // will we have to potentially relayout.        int yPosEstimate = estimateVerticalPosition(child, marginInfo);        // Cache our old rect so that we can dirty the proper repaint rects if the child moves.        IntRect oldRect(child->x(), child->y() , child->width(), child->height());#ifndef NDEBUG        IntSize oldLayoutDelta = view()->layoutDelta();#endif        // Go ahead and position the child as though it didn't collapse with the top.        view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate));        child->setLocation(child->x(), yPosEstimate);        bool markDescendantsWithFloats = false;        if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())            markDescendantsWithFloats = true;        else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {            // If an element might be affected by the presence of floats, then always mark it for            // layout.            int fb = max(previousFloatBottom, floatBottom());            if (fb > yPosEstimate)                markDescendantsWithFloats = true;        }        if (child->isRenderBlock()) {            if (markDescendantsWithFloats)                toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();            previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom());        }        bool childHadLayout = child->m_everHadLayout;        bool childNeededLayout = child->needsLayout();        if (childNeededLayout)            child->layout();        // Now determine the correct ypos based off examination of collapsing margin        // values.        int yBeforeClear = collapseMargins(child, marginInfo);        // Now check for clear.        int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear);                view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear));        child->setLocation(child->x(), yAfterClear);            // Now we have a final y position.  See if it really does end up being different from our estimate.        if (yAfterClear != yPosEstimate) {            if (child->shrinkToAvoidFloats()) {                // The child's width depends on the line width.                // When the child shifts to clear an item, its width can                // change (because it has more available line width).                // So go ahead and mark the item as dirty.                child->setChildNeedsLayout(true, false);            }            if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())                toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();            // Our guess was wrong. Make the child lay itself out again.            child->layoutIfNeeded();        }        // We are no longer at the top of the block if we encounter a non-empty child.          // This has to be done after checking for clear, so that margins can be reset if a clear occurred.        if (marginInfo.atTopOfBlock() && !child->isSelfCollapsingBlock())            marginInfo.setAtTopOfBlock(false);        // Now place the child in the correct horizontal position        determineHorizontalPosition(child);        // Update our height now that the child has been placed in the correct position.        setHeight(height() + child->height());        if (child->style()->marginBottomCollapse() == MSEPARATE) {            setHeight(height() + child->marginBottom());            marginInfo.clearMargin();        }        // If the child has overhanging floats that intrude into following siblings (or possibly out        // of this block), then the parent gets notified of the floats now.        if (child->isBlockFlow() && toRenderBlock(child)->containsFloats())            maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));        // Update our overflow in case the child spills out the block.        m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false));        m_overflowHeight = max(m_overflowHeight, height() + child->overflowHeight(false) - child->height());        m_overflowWidth = max(child->x() + child->overflowWidth(false), m_overflowWidth);        m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft);        IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());        if (childOffset.width() || childOffset.height()) {            view()->addLayoutDelta(childOffset);            // If the child moved, we have to repaint it as well as any floating/positioned            // descendants.  An exception is if we need a layout.  In this case, we know we're going to            // repaint ourselves (and the child) anyway.            if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())                child->repaintDuringLayoutIfMoved(oldRect);        }        if (!childHadLayout && child->checkForRepaintDuringLayout())            child->repaint();        ASSERT(oldLayoutDelta == view()->layoutDelta());        child = child->nextSiblingBox();    }    // Now do the handling of the bottom of the block, adding in our bottom border/padding and    // determining the correct collapsed bottom margin information.    handleBottomOfBlock(top, bottom, marginInfo);}bool RenderBlock::layoutOnlyPositionedObjects(){    if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())        return false;    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());    if (needsPositionedMovementLayout()) {        tryLayoutDoingPositionedMovementOnly();        if (needsLayout())            return false;    }    // All we have to is lay out our positioned objects.    layoutPositionedObjects(false);    statePusher.pop();    if (hasOverflowClip())        layer()->updateScrollInfoAfterLayout();    setNeedsLayout(false);    return true;}void RenderBlock::layoutPositionedObjects(bool relayoutChildren){    if (m_positionedObjects) {        RenderBox* r;        Iterator end = m_positionedObjects->end();        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {            r = *it;            // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the            // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned            // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is            // positioned explicitly) this should not incur a performance penalty.            if (relayoutChildren || (r->style()->hasStaticY() && r->parent() != this && r->parent()->isBlockFlow()))                r->setChildNeedsLayout(true, false);                            // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.            //if (relayoutChildren && (r->style()->paddingLeft().isPercent() || r->style()->paddingRight().isPercent()))                r->setPrefWidthsDirty(true, false);                        // We don't have to do a full layout.  We just have to update our position. Try that first. If we have shrink-to-fit width            // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.            if (r->needsPositionedMovementLayoutOnly())                r->tryLayoutDoingPositionedMovementOnly();            r->layoutIfNeeded();        }    }}void RenderBlock::markPositionedObjectsForLayout(){    if (m_positionedObjects) {        RenderBox* r;        Iterator end = m_positionedObjects->end();        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {            r = *it;            r->setChildNeedsLayout(true);        }    }}void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants){    // Repaint any overhanging floats (if we know we're the one to paint them).    if (hasOverhangingFloats()) {        // We think that we must be in a bad state if m_floatingObjects is nil at this point, so         // we assert on Debug builds and nil-check Release builds.        ASSERT(m_floatingObjects);        if (!m_floatingObjects)            return;                FloatingObject* r;        DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);        // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating        // in this

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -