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

📄 render_block.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // The remerge has knocked us down to containing only a single anonymous        // box.  We can go ahead and pull the content right back up into our        // box.        RenderObject* anonBlock = removeChildNode(prev);        m_childrenInline = true;        RenderObject* o = anonBlock->firstChild();        while (o) {            RenderObject* no = o;            o = no->nextSibling();            appendChildNode(anonBlock->removeChildNode(no));            no->setNeedsLayoutAndMinMaxRecalc();        }                // Nuke the now-empty block.        anonBlock->detach();    }}bool RenderBlock::isSelfCollapsingBlock() const{    // We are not self-collapsing if we    // (a) have a non-zero height according to layout (an optimization to avoid wasting time)    // (b) are a table,    // (c) have border/padding,    // (d) have a min-height    if (m_height > 0 ||        isTable() || (borderBottom() + paddingBottom() + borderTop() + paddingTop()) != 0 ||        style()->minHeight().value > 0)        return false;    // If the height is 0 or auto, then whether or not we are a self-collapsing block depends    // on whether we have content that is all self-collapsing or not.    if (style()->height().isVariable() ||        (style()->height().isFixed() && style()->height().value == 0)) {        // If the block has inline children, see if we generated any line boxes.  If we have any        // line boxes, then we can't be self-collapsing, since we have content.        if (childrenInline())            return !firstLineBox();                // Whether or not we collapse is dependent on whether all our normal flow children        // are also self-collapsing.        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {            if (child->isFloatingOrPositioned())                continue;            if (!child->isSelfCollapsingBlock())                return false;        }        return true;    }    return false;}void RenderBlock::layout(){    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into    // layoutBlock().    layoutBlock(false);}void RenderBlock::layoutBlock(bool relayoutChildren){    //    kdDebug( 6040 ) << renderName() << " " << this << "::layoutBlock() start" << endl;    //     QTime t;    //     t.start();    KHTMLAssert( needsLayout() );    KHTMLAssert( minMaxKnown() );    if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can        return;	    		                     // cause us to come in here.  Just bail. -dwh    if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {        // All we have to is lay out our positioned objects.        layoutPositionedObjects(relayoutChildren);        if (hasOverflowClip())            m_layer->updateScrollInfoAfterLayout();        setNeedsLayout(false);        return;    }        QRect oldBounds, oldFullBounds;    bool checkForRepaint = checkForRepaintDuringLayout();    if (checkForRepaint)        getAbsoluteRepaintRectIncludingFloats(oldBounds, oldFullBounds);    int oldWidth = m_width;        calcWidth();    m_overflowWidth = m_width;    if ( oldWidth != m_width )        relayoutChildren = true;    //     kdDebug( 6040 ) << floatingObjects << "," << oldWidth << ","    //                     << m_width << ","<< needsLayout() << "," << isAnonymous() << ","    //                     << "," << isPositioned() << endl;#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(RenderBlock) " << this << " ::layout() width=" << m_width << ", needsLayout=" << needsLayout() << endl;    if(containingBlock() == static_cast<RenderObject *>(this))        kdDebug( 6040 ) << renderName() << ": containingBlock == this" << endl;#endif    clearFloats();    m_height = 0;    m_overflowHeight = 0;    m_clearStatus = CNONE;    // We use four values, maxTopPos, maxPosNeg, maxBottomPos, and maxBottomNeg, to track    // our current maximal positive and negative margins.  These values are used when we    // are collapsed with adjacent blocks, so for example, if you have block A and B    // collapsing together, then you'd take the maximal positive margin from both A and B    // and subtract it from the maximal negative margin from both A and B to get the    // true collapsed margin.  This algorithm is recursive, so when we finish layout()    // our block knows its current maximal positive/negative values.    //    // Start out by setting our margin values to our current margins.  Table cells have    // no margins, so we don't fill in the values for table cells.    if (!isTableCell()) {        initMaxMarginValues();        m_topMarginQuirk = style()->marginTop().quirk;        m_bottomMarginQuirk = style()->marginBottom().quirk;        if (element() && element()->id() == ID_FORM && element()->isMalformed())            // See if this form is malformed (i.e., unclosed). If so, don't give the form            // a bottom margin.            m_maxBottomPosMargin = m_maxBottomNegMargin = 0;    }    if (scrollsOverflow()) {        // For overflow:scroll blocks, ensure we have both scrollbars in place always.        if (style()->overflow() == OSCROLL) {            m_layer->setHasHorizontalScrollbar(true);            m_layer->setHasVerticalScrollbar(true);        }                // Move the scrollbars aside during layout.  The layer will move them back when it        // does painting or event handling.        m_layer->moveScrollbarsAside();    }        //    kdDebug( 6040 ) << "childrenInline()=" << childrenInline() << endl;    QRect repaintRect(0,0,0,0);    if (childrenInline())        repaintRect = layoutInlineChildren( relayoutChildren );    else        layoutBlockChildren( relayoutChildren );    // Expand our intrinsic height to encompass floats.    int toAdd = borderBottom() + paddingBottom();    if (includeScrollbarSize())        toAdd += m_layer->horizontalScrollbarHeight();    if ( hasOverhangingFloats() && (isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() ||                                    (parent() && parent()->isFlexibleBox())) )        m_height = floatBottom() + toAdd;               int oldHeight = m_height;    calcHeight();    if (oldHeight != m_height) {        relayoutChildren = true;        // If the block got expanded in size, then increase our overflowheight to match.        if (m_overflowHeight > m_height)            m_overflowHeight -= paddingBottom() + borderBottom();        if (m_overflowHeight < m_height)            m_overflowHeight = m_height;    }    if (isTableCell()) {        // Table cells need to grow to accommodate both overhanging floats and        // blocks that have overflowed content.        // Check for an overhanging float first.        // FIXME: This needs to look at the last flow, not the last child.        if (lastChild() && lastChild()->hasOverhangingFloats()) {            KHTMLAssert(lastChild()->isRenderBlock());            m_height = lastChild()->yPos() + static_cast<RenderBlock*>(lastChild())->floatBottom();            m_height += borderBottom() + paddingBottom();        }        if (m_overflowHeight > m_height && !hasOverflowClip())            m_height = m_overflowHeight + borderBottom() + paddingBottom();    }    if( hasOverhangingFloats() && (isFloating() || isTableCell())) {        m_height = floatBottom();        m_height += borderBottom() + paddingBottom();    }    layoutPositionedObjects( relayoutChildren );    //kdDebug() << renderName() << " layout width=" << m_width << " height=" << m_height << endl;    // Always ensure our overflow width/height are at least as large as our width/height.    if (m_overflowWidth < m_width)        m_overflowWidth = m_width;    if (m_overflowHeight < m_height)        m_overflowHeight = m_height;        // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if    // we overflow or not.    if (hasOverflowClip())        m_layer->updateScrollInfoAfterLayout();    // Repaint with our new bounds if they are different from our old bounds.    bool didFullRepaint = false;    if (checkForRepaint)        didFullRepaint = repaintAfterLayoutIfNeeded(oldBounds, oldFullBounds);    if (!didFullRepaint && !repaintRect.isEmpty()) {        RenderCanvas* c = canvas();        if (c && c->view())            c->view()->addRepaintInfo(this, repaintRect); // We need to do a partial repaint of our content.    }    setNeedsLayout(false);}void RenderBlock::layoutBlockChildren( bool relayoutChildren ){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << " layoutBlockChildren( " << this <<" ), relayoutChildren="<< relayoutChildren << endl;#endif    int xPos = borderLeft() + paddingLeft();    if( style()->direction() == RTL )        xPos = m_width - paddingRight() - borderRight();    int toAdd = borderBottom() + paddingBottom();    if (includeScrollbarSize())        toAdd += m_layer->horizontalScrollbarHeight();        m_height = borderTop() + paddingTop();    // 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 minHeight = m_height + toAdd;    m_overflowHeight = m_height;    RenderObject* child = firstChild();    RenderBlock* prevFlow = 0;    RenderObject* prevBlock = 0;        // A compact child that needs to be collapsed into the margin of the following block.    RenderObject* compactChild = 0;    // The block with the open margin that the compact child is going to place itself within.    RenderObject* blockForCompactChild = 0;    // For compact children that don't fit, we lay them out as though they are blocks.  This    // boolean allows us to temporarily treat a compact like a block and lets us know we need    // to turn the block back into a compact when we're done laying out.    bool treatCompactAsBlock = false;        // Whether or not we can collapse our own margins with our children.  We don't do this    // if we had any border/padding (obviously), if we're the root or HTML elements, or if    // we're positioned, floating, a table cell.    // For now we only worry about the top border/padding.  We will update the variable's    // value when it comes time to check against the bottom border/padding.    bool canCollapseWithChildren = !isCanvas() && !isRoot() && !isPositioned() &&        !isFloating() && !isTableCell() && !hasOverflowClip() && !isInlineBlockOrInlineTable();    bool canCollapseTopWithChildren = canCollapseWithChildren && (m_height == 0);    // If any height other than auto is specified in CSS, then we don't collapse our bottom    // margins with our children's margins.  To do otherwise would be to risk odd visual    // effects when the children overflow out of the parent block and yet still collapse    // with it.  We also don't collapse if we had any bottom border/padding (represented by    // |toAdd|).    bool canCollapseBottomWithChildren = canCollapseWithChildren && (toAdd == 0) &&        (style()->height().isVariable() && style()->height().value == 0);        // Whether or not we are a quirky container, i.e., do we collapse away top and bottom    // margins in our container.    bool quirkContainer = isTableCell() || isBody();    // This flag tracks whether the child should collapse with the top margins of the block.    // It can remain set through multiple iterations as long as we keep encountering    // self-collapsing blocks.    bool topMarginContributor = true;    // These flags track the previous maximal positive and negative margins.    int prevPosMargin = canCollapseTopWithChildren ? maxTopMargin(true) : 0;    int prevNegMargin = canCollapseTopWithChildren ? maxTopMargin(false) : 0;    // Whether or not we encountered an element with clear set that actually had to    // be pushed down below a float.    bool clearOccurred = false;    // If our last normal flow child was a self-collapsing block that cleared a float,    // we track it in this variable.    bool selfCollapsingBlockClearedFloat = false;        bool topChildQuirk = false;    bool bottomChildQuirk = false;    bool determinedTopQuirk = false;    bool strictMode = !style()->htmlHacks();    //kdDebug() << "RenderBlock::layoutBlockChildren " << prevMargin << endl;    //     QTime t;    //     t.start();    while( child != 0 )    {        // Sometimes an element will be shoved down away from a previous sibling, e.g., when        // clearing to pass beyond a float.  In this case, you don't need to collapse.  This        // boolean is updated with each iteration through our child list to reflect whether        // that particular child should be collapsed with its previous sibling (or with the top        // of the block).        bool shouldCollapseChild = true;                        int oldTopPosMargin = m_maxTopPosMargin;

⌨️ 快捷键说明

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