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

📄 render_block.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // Move the scrollbars aside during layout.  The layer will move them back when it        // does painting or event handling.        m_layer->moveScrollbarsAside();    }    // A quirk that has become an unfortunate standard.  Positioned elements, floating elements    // and table cells don't ever collapse their margins with either themselves or their    // children.    bool canCollapseOwnMargins = !isPositioned() && !isFloating() && !isTableCell();    setContainsPageBreak(false);    if (childrenInline())        layoutInlineChildren( relayoutChildren );    else        layoutBlockChildren( relayoutChildren );    // Expand our intrinsic height to encompass floats.    int toAdd = borderBottom() + paddingBottom();    if (m_layer && style()->scrollsOverflow() && style()->height().isVariable())        toAdd += m_layer->horizontalScrollbarHeight();    if ( hasOverhangingFloats() && (isFloatingOrPositioned() || flowAroundFloats()) )        m_overflowHeight = 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 -= (borderBottom()+paddingBottom());        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() && !lastChild()->style()->hidesOverflow()) {            KHTMLAssert(lastChild()->isRenderBlock());            m_height = lastChild()->yPos() + static_cast<RenderBlock*>(lastChild())->floatBottom();            m_height += borderBottom() + paddingBottom();        }        if (m_overflowHeight > m_height && !style()->hidesOverflow())            m_height = m_overflowHeight + borderBottom() + paddingBottom();    }    if( hasOverhangingFloats() && ((isFloating() && style()->height().isVariable()) || isTableCell())) {        m_height = floatBottom();        m_height += borderBottom() + paddingBottom();    }    if (canvas()->pagedMode()) {#ifdef PAGE_DEBUG        kdDebug(6040) << renderName() << " Page Bottom: " << pageTopAfter(0) << endl;        kdDebug(6040) << renderName() << " Bottom: " << m_height << endl;#endif        bool needsPageBreak = false;        int xpage = crossesPageBreak(0, m_height);        if (xpage) {            needsPageBreak = true;#ifdef PAGE_DEBUG            kdDebug( 6040 ) << renderName() << " crosses to page " << xpage << endl;#endif        }        if (needsPageBreak && !containsPageBreak()) {            setNeedsPageClear(true);#ifdef PAGE_DEBUG            kdDebug( 6040 ) << renderName() << " marked for page-clear" << endl;#endif        }    }    layoutPositionedObjects( relayoutChildren );    // Always ensure our overflow width/height are at least as large as our width/height.    m_overflowWidth = kMax(m_overflowWidth, (int)m_width);    m_overflowHeight = kMax(m_overflowHeight, m_height);    if (canCollapseOwnMargins && m_height == 0) {        // We are a block with no border and padding and a computed height        // of 0.  The CSS spec states that zero-height blocks collapse their margins        // together.        // When blocks are self-collapsing, we just use the top margin values and set the        // bottom margin max values to 0.  This way we don't factor in the values        // twice when we collapse with our previous vertically adjacent and        // following vertically adjacent blocks.        if (m_maxBottomPosMargin > m_maxTopPosMargin)            m_maxTopPosMargin = m_maxBottomPosMargin;        if (m_maxBottomNegMargin > m_maxTopNegMargin)            m_maxTopNegMargin = m_maxBottomNegMargin;        m_maxBottomNegMargin = m_maxBottomPosMargin = 0;    }    // Update our scrollbars if we're overflow:auto/scroll now that we know if    // we overflow or not.    if (style()->hidesOverflow() && m_layer)        m_layer->checkScrollbarsAfterLayout();    setNeedsLayout(false);}void RenderBlock::adjustPositionedBlock(RenderObject* child, const MarginInfo& marginInfo){    if (child->isBox() && child->hasStaticX()) {        if (style()->direction() == LTR)            static_cast<RenderBox*>(child)->setStaticX(borderLeft() + paddingLeft());        else            static_cast<RenderBox*>(child)->setStaticX(borderRight() + paddingRight());    }    if (child->isBox() && child->hasStaticY()) {        int marginOffset = 0;        if (!marginInfo.canCollapseWithTop()) {            int collapsedTopPos = marginInfo.posMargin();            int collapsedTopNeg = marginInfo.negMargin();            bool posMargin = child->marginTop() >= 0;            if (posMargin && child->marginTop() > collapsedTopPos)                collapsedTopPos = child->marginTop();            else if (!posMargin && child->marginTop() > collapsedTopNeg)                collapsedTopNeg = child->marginTop();            marginOffset += (collapsedTopPos - collapsedTopNeg) - child->marginTop();        }        static_cast<RenderBox*>(child)->setStaticY(m_height + marginOffset);    }}void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo){    // The float should be positioned taking into account the bottom margin    // of the previous flow.  We add that margin into the height, get the    // float positioned properly, and then subtract the margin out of the    // height again.  In the case of self-collapsing blocks, we always just    // use the top margins, since the self-collapsing block collapsed its    // own bottom margin into its top margin.    //    // Note also that the previous flow may collapse its margin into the top of    // our block.  If this is the case, then we do not add the margin in to our    // height when computing the position of the float.   This condition can be tested    // for by simply calling canCollapseWithTop.  See    // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for    // an example of this scenario.    int marginOffset = marginInfo.canCollapseWithTop() ? 0 : marginInfo.margin();    m_height += marginOffset;    positionNewFloats();    m_height -= marginOffset;}RenderObject* RenderBlock::handleSpecialChild(RenderObject* child, const MarginInfo& marginInfo, CompactInfo& compactInfo, bool& handled){    // Handle positioned children first.    RenderObject* next = handlePositionedChild(child, marginInfo, handled);    if (handled) return next;    // Handle floating children next.    next = handleFloatingChild(child, marginInfo, handled);    if (handled) return next;    // See if we have a compact element.  If we do, then try to tuck the compact element into the margin space of the next block.    next = handleCompactChild(child, compactInfo, marginInfo, handled);    if (handled) return next;    // Finally, see if we have a run-in element.    return handleRunInChild(child, handled);}RenderObject* RenderBlock::handlePositionedChild(RenderObject* child, const MarginInfo& marginInfo, bool& handled){    if (child->isPositioned()) {        handled = true;        child->containingBlock()->insertPositionedObject(child);        adjustPositionedBlock(child, marginInfo);        return child->nextSibling();    }    return 0;}RenderObject* RenderBlock::handleFloatingChild(RenderObject* child, const MarginInfo& marginInfo, bool& handled){    if (child->isFloating()) {        handled = true;        insertFloatingObject(child);        adjustFloatingBlock(marginInfo);        return child->nextSibling();    }    return 0;}static inline bool isAnonymousWhitespace( RenderObject* o ) {    if (!o->isAnonymous())        return false;    RenderObject *fc = o->firstChild();    return fc && fc == o->lastChild() && fc->isText() && static_cast<RenderText *>(fc)->stringLength() == 1 &&           static_cast<RenderText *>(fc)->text()[0].unicode() == ' ';}RenderObject* RenderBlock::handleCompactChild(RenderObject* child, CompactInfo& compactInfo, const MarginInfo& marginInfo, bool& handled){    // FIXME: We only deal with one compact at a time.  It is unclear what should be    // done if multiple contiguous compacts are encountered.  For now we assume that    // compact A followed by another compact B should simply be treated as block A.    if (child->isCompact() && !compactInfo.compact() && (child->childrenInline() || child->isReplaced())) {        // Get the next non-positioned/non-floating RenderBlock.        RenderObject* next = child->nextSibling();        RenderObject* curr = next;        while (curr && (curr->isFloatingOrPositioned() || isAnonymousWhitespace(curr)) )            curr = curr->nextSibling();        if (curr && curr->isRenderBlock() && !curr->isCompact() && !curr->isRunIn()) {            curr->calcWidth(); // So that horizontal margins are correct.            // Need to compute margins for the child as though it is a block.            child->style()->setDisplay(BLOCK);            child->calcWidth();            child->style()->setDisplay(COMPACT);            int childMargins = child->marginLeft() + child->marginRight();            int margin = style()->direction() == LTR ? curr->marginLeft() : curr->marginRight();            if (margin >= (childMargins + child->maxWidth())) {                // The compact will fit in the margin.                handled = true;                compactInfo.set(child, curr);                child->layoutIfNeeded();                int off = marginInfo.margin();                m_height += off + curr->marginTop() < child->marginTop() ?                            child->marginTop() - curr->marginTop() -off: 0;                child->setPos(0,0); // This position will be updated to reflect the compact's                                    // desired position and the line box for the compact will                                    // pick that position up.                return next;            }        }    }    return 0;}void RenderBlock::insertCompactIfNeeded(RenderObject* child, CompactInfo& compactInfo){    if (compactInfo.matches(child)) {        // We have a compact child to squeeze in.        RenderObject* compactChild = compactInfo.compact();        int compactXPos = borderLeft() + paddingLeft() + compactChild->marginLeft();        if (style()->direction() == RTL) {            compactChild->calcWidth(); // have to do this because of the capped maxwidth            compactXPos = width() - borderRight() - paddingRight() -                compactChild->width() - compactChild->marginRight();        }        int compactYPos = child->yPos() + child->borderTop() + child->paddingTop()                            - compactChild->paddingTop() - compactChild->borderTop();        int adj = 0;        KHTMLAssert(child->isRenderBlock());        InlineRunBox *b = static_cast<RenderBlock*>(child)->firstLineBox();        InlineRunBox *c = static_cast<RenderBlock*>(compactChild)->firstLineBox();        if (b && c) {            // adjust our vertical position            int vpos = compactChild->getVerticalPosition( true, child );            if (vpos == PositionBottom)                adj = b->height() > c->height() ? (b->height() + b->yPos() - c->height() - c->yPos()) : 0;            else if (vpos == PositionTop)                adj = b->yPos() - c->yPos();            else                adj = vpos;            compactYPos += adj;        }        Length newLineHeight( kMax(compactChild->lineHeight(true)+adj, (int)child->lineHeight(true)), khtml::Fixed);        child->style()->setLineHeight( newLineHeight );        child->setNeedsLayout( true, false );        child->layout();        compactChild->setPos(compactXPos, compactYPos); // Set the x position.        compactInfo.clear();    }}RenderObject* RenderBlock::handleRunInChild(RenderObject* child, bool& handled){    // See if we have a run-in element with inline children.  If the    // children aren't inline, then just treat the run-in as a normal    // block.    if (child->isRunIn() && (child->childrenInline() || child->isReplaced())) {        // Get the next non-positioned/non-floating RenderBlock.        RenderObject* curr = child->nextSibling();        while (curr && (curr->isFloatingOrPositioned() || isAnonymousWhitespace(curr)) )            curr = curr->nextSibling();        if (curr && (curr->isRenderBlock() && curr->childrenInline() && !curr->isCompact() && !curr->isRunIn())) {            // The block acts like an inline, so just null out its            // position.            handled = true;            child->setInline(true);            child->setPos(0,0);            // Remove the child.            RenderObject* next = child->nextSibling();            removeChildNode(child);            // Now insert the child under |curr|.            curr->insertChildNode(child, curr->firstChild());            return next;        }    }    return 0;}void RenderBlock::collapseMargins(RenderObject* child, MarginInfo& marginInfo, int yPosEstimate){    // Get our max pos and neg top margins.

⌨️ 快捷键说明

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