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

📄 render_block.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{    // Beginning at |start| we find the largest contiguous run of inlines that    // we can.  We denote the run with start and end points, |inlineRunStart|    // and |inlineRunEnd|.  Note that these two values may be the same if    // we encounter only one inline.    //    // We skip any non-inlines we encounter as long as we haven't found any    // inlines yet.    //    // |stop| indicates a non-inclusive stop point.  Regardless of whether |stop|    // is inline or not, we will not include it.  It's as though we encountered    // a non-inline.    inlineRunStart = inlineRunEnd = 0;    // Start by skipping as many non-inlines as we can.    RenderObject * curr = start;    while (curr && !curr->isInline())        curr = curr->nextSibling();    if (!curr)        return; // No more inline children to be found.    inlineRunStart = inlineRunEnd = curr;    curr = curr->nextSibling();    while (curr && curr->isInline() && (curr != stop)) {        inlineRunEnd = curr;        curr = curr->nextSibling();    }}void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint){    // makeChildrenNonInline takes a block whose children are *all* inline and it    // makes sure that inline children are coalesced under anonymous    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for    // the new block child that is causing us to have to wrap all the inlines.  This    // means that we cannot coalesce inlines before |insertionPoint| with inlines following    // |insertionPoint|, because the new child is going to be inserted in between the inlines,    // splitting them.    KHTMLAssert(isReplacedBlock() || !isInline());    KHTMLAssert(!insertionPoint || insertionPoint->parent() == this);    m_childrenInline = false;    RenderObject *child = firstChild();    while (child) {        RenderObject *inlineRunStart, *inlineRunEnd;        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);        if (!inlineRunStart)            break;        child = inlineRunEnd->nextSibling();        RenderBlock* box = createAnonymousBlock();        insertChildNode(box, inlineRunStart);        RenderObject* o = inlineRunStart;        while(o != inlineRunEnd)        {            RenderObject* no = o;            o = no->nextSibling();            box->appendChildNode(removeChildNode(no));        }        box->appendChildNode(removeChildNode(inlineRunEnd));        box->close();        box->setPos(box->xPos(), -500000);    }}void RenderBlock::makePageBreakAvoidBlocks(){    KHTMLAssert(!childrenInline());    KHTMLAssert(canvas()->pagedMode());    RenderObject *breakAfter = firstChild();    RenderObject *breakBefore = breakAfter ? breakAfter->nextSibling() : 0;    RenderBlock* pageRun = 0;    // ### Should follow margin-collapsing rules, skipping self-collapsing blocks    // and exporting page-breaks from first/last child when collapsing with parent margin.    while (breakAfter) {        if (breakAfter->isRenderBlock() && !breakAfter->childrenInline())            static_cast<RenderBlock*>(breakAfter)->makePageBreakAvoidBlocks();        EPageBreak pbafter = breakAfter->style()->pageBreakAfter();        EPageBreak pbbefore = breakBefore ? breakBefore->style()->pageBreakBefore() : PBALWAYS;        if ((pbafter == PBAVOID && pbbefore == PBAVOID) ||            (pbafter == PBAVOID && pbbefore == PBAUTO) ||            (pbafter == PBAUTO && pbbefore == PBAVOID))        {            if (!pageRun) {                pageRun = createAnonymousBlock();                pageRun->m_avoidPageBreak = true;                pageRun->setChildrenInline(false);            }            pageRun->appendChildNode(removeChildNode(breakAfter));        } else        {            if (pageRun) {                pageRun->appendChildNode(removeChildNode(breakAfter));                pageRun->close();                insertChildNode(pageRun, breakBefore);                pageRun = 0;            }        }        breakAfter = breakBefore;        breakBefore = breakBefore ? breakBefore->nextSibling() : 0;    }    // recurse into positioned block children as well.    if (m_positionedObjects) {        QPtrListIterator<RenderObject> it(*m_positionedObjects);        for ( ; it.current(); ++it ) {            if (it.current()->isRenderBlock() && !it.current()->childrenInline()) {                static_cast<RenderBlock*>(it.current())->makePageBreakAvoidBlocks();            }        }    }    // recurse into floating block children.    if (m_floatingObjects) {        QPtrListIterator<FloatingObject> it(*m_floatingObjects);        for ( ; it.current(); ++it ) {            if (it.current()->node->isRenderBlock() && !it.current()->node->childrenInline()) {                static_cast<RenderBlock*>(it.current()->node)->makePageBreakAvoidBlocks();            }        }    }}void RenderBlock::removeChild(RenderObject *oldChild){    // If this child is a block, and if our previous and next siblings are    // both anonymous blocks with inline content, then we can go ahead and    // fold the inline content back together.    RenderObject* prev = oldChild->previousSibling();    RenderObject* next = oldChild->nextSibling();    bool mergedBlocks = false;    if (document()->renderer() && !isInline() && !oldChild->isInline() && !oldChild->continuation() &&        prev && prev->isAnonymousBlock() && prev->childrenInline() &&        next && next->isAnonymousBlock() && next->childrenInline()) {        // Take all the children out of the |next| block and put them in        // the |prev| block.        RenderObject* o = next->firstChild();        while (o) {            RenderObject* no = o;            o = no->nextSibling();            prev->appendChildNode(next->removeChildNode(no));            no->setNeedsLayoutAndMinMaxRecalc();        }        prev->setNeedsLayoutAndMinMaxRecalc();        // Nuke the now-empty block.        next->detach();        mergedBlocks = true;    }    RenderFlow::removeChild(oldChild);    if (mergedBlocks && prev && !prev->previousSibling() && !prev->nextSibling()) {        // 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;    bool hasAutoHeight = style()->height().isVariable();    if (style()->height().isPercent() && !style()->htmlHacks()) {        hasAutoHeight = true;        for (RenderBlock* cb = containingBlock(); !cb->isCanvas(); cb = cb->containingBlock()) {            if (cb->style()->height().isFixed() || cb->isTableCell())                hasAutoHeight = 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 (hasAutoHeight || ((style()->height().isFixed() || style()->height().isPercent()) && 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){    if (isInline() && !isReplacedBlock()) {        setNeedsLayout(false);        return;    }    //    kdDebug( 6040 ) << renderName() << " " << this << "::layoutBlock() start" << endl;    //     QTime t;    //     t.start();    KHTMLAssert( needsLayout() );    KHTMLAssert( minMaxKnown() );    if (canvas()->pagedMode()) relayoutChildren = true;    if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {        // All we have to is lay out our positioned objects.        layoutPositionedObjects(relayoutChildren);        if (hasOverflowClip())            m_layer->checkScrollbarsAfterLayout();        setNeedsLayout(false);        return;    }    if (markedForRepaint()) {        repaintDuringLayout();        setMarkedForRepaint(false);    }    int oldWidth = m_width;    calcWidth();    m_overflowWidth = m_width;    if ( oldWidth != m_width )        relayoutChildren = true;    //     kdDebug( 6040 ) << floatingObjects << "," << oldWidth << ","    //                     << m_width << ","<< needsLayout() << "," << isAnonymousBox() << ","    //                     << overhangingContents() << "," << 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().isQuirk();        m_bottomMarginQuirk = style()->marginBottom().isQuirk();        if (element() && element()->id() == ID_FORM && static_cast<HTMLFormElementImpl*>(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 (style()->scrollsOverflow() && m_layer) {        // For overflow:scroll blocks, ensure we have both scrollbars in place always.        if (style()->overflow() == OSCROLL) {            m_layer->showScrollbar( Qt::Horizontal, true );            m_layer->showScrollbar( Qt::Vertical, true );        }

⌨️ 快捷键说明

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