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

📄 render_inline.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * This file is part of the render object implementation for KHTML. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) *           (C) 1999-2003 Antti Koivisto (koivisto@kde.org) *           (C) 2002-2003 Dirk Mueller (mueller@kde.org) *           (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */#include <kglobal.h>#include "rendering/render_arena.h"#include "rendering/render_inline.h"#include "rendering/render_block.h"#include "xml/dom_docimpl.h"#include <qvaluevector.h>using namespace khtml;void RenderInline::setStyle(RenderStyle* _style){    RenderFlow::setStyle(_style);    setInline(true);    // Ensure that all of the split inlines pick up the new style. We    // only do this if we're an inline, since we don't want to propagate    // a block's style to the other inlines.    // e.g., <font>foo <h4>goo</h4> moo</font>.  The <font> inlines before    // and after the block share the same style, but the block doesn't    // need to pass its style on to anyone else.    RenderFlow* currCont = continuation();    while (currCont) {        if (currCont->isInline()) {            RenderFlow* nextCont = currCont->continuation();            currCont->setContinuation(0);            currCont->setStyle(style());            currCont->setContinuation(nextCont);        }        currCont = currCont->continuation();    }    // Update pseudos for ::before and ::after now.    updatePseudoChildren();}bool RenderInline::isInlineContinuation() const{    return m_isContinuation;}void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild){    // Make sure we don't append things after :after-generated content if we have it.    if (!beforeChild && lastChild() && lastChild()->style()->styleType() == RenderStyle::AFTER)        beforeChild = lastChild();    if (!newChild->isText() && newChild->style()->position() != STATIC)        setOverhangingContents();    if (!newChild->isInline() && !newChild->isFloatingOrPositioned() )    {        // We are placing a block inside an inline. We have to perform a split of this        // inline into continuations.  This involves creating an anonymous block box to hold        // |newChild|.  We then make that block box a continuation of this inline.  We take all of        // the children after |beforeChild| and put them in a clone of this object.        RenderBlock *newBox = createAnonymousBlock();        RenderFlow* oldContinuation = continuation();        setContinuation(newBox);        // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content        // has to move into the inline continuation.  Call updatePseudoChild to ensure that our :after        // content gets properly destroyed.        bool isLastChild = (beforeChild == lastChild());        updatePseudoChild(RenderStyle::AFTER, lastChild());        if (isLastChild && beforeChild != lastChild())            beforeChild = 0; // We destroyed the last child, so now we need to update our insertion                             // point to be 0.  It's just a straight append now.        splitFlow(beforeChild, newBox, newChild, oldContinuation);        return;    }    RenderBox::addChild(newChild,beforeChild);    newChild->setNeedsLayoutAndMinMaxRecalc();}RenderInline* RenderInline::cloneInline(RenderFlow* src){    RenderInline *o = new (src->renderArena()) RenderInline(src->element());    o->m_isContinuation = true;    o->setStyle(src->style());    return o;}void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,                                RenderBlock* middleBlock,                                RenderObject* beforeChild, RenderFlow* oldCont){    // Create a clone of this inline.    RenderInline* clone = cloneInline(this);    clone->setContinuation(oldCont);    // Now take all of the children from beforeChild to the end and remove    // then from |this| and place them in the clone.    RenderObject* o = beforeChild;    while (o) {        RenderObject* tmp = o;        o = tmp->nextSibling();        clone->addChildToFlow(removeChildNode(tmp), 0);        tmp->setNeedsLayoutAndMinMaxRecalc();    }    // Hook |clone| up as the continuation of the middle block.    middleBlock->setContinuation(clone);    // We have been reparented and are now under the fromBlock.  We need    // to walk up our inline parent chain until we hit the containing block.    // Once we hit the containing block we're done.    RenderFlow* curr = static_cast<RenderFlow*>(parent());    RenderFlow* currChild = this;    while (curr && curr != fromBlock) {        // Create a new clone.        RenderInline* cloneChild = clone;        clone = cloneInline(curr);        // Insert our child clone as the first child.        clone->addChildToFlow(cloneChild, 0);        // Hook the clone up as a continuation of |curr|.        RenderFlow* oldCont = curr->continuation();        curr->setContinuation(clone);        clone->setContinuation(oldCont);        // Now we need to take all of the children starting from the first child        // *after* currChild and append them all to the clone.        o = currChild->nextSibling();        while (o) {            RenderObject* tmp = o;            o = tmp->nextSibling();            clone->appendChildNode(curr->removeChildNode(tmp));            tmp->setNeedsLayoutAndMinMaxRecalc();        }        // Keep walking up the chain.        currChild = curr;        curr = static_cast<RenderFlow*>(curr->parent());    }    // Now we are at the block level. We need to put the clone into the toBlock.    toBlock->appendChildNode(clone);    // Now take all the children after currChild and remove them from the fromBlock    // and put them in the toBlock.    o = currChild->nextSibling();    while (o) {        RenderObject* tmp = o;        o = tmp->nextSibling();        toBlock->appendChildNode(fromBlock->removeChildNode(tmp));    }}void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,                             RenderObject* newChild, RenderFlow* oldCont){    RenderBlock* pre = 0;    RenderBlock* block = containingBlock();    bool madeNewBeforeBlock = false;    if (block->isAnonymousBlock()) {        // We can reuse this block and make it the preBlock of the next continuation.        pre = block;        block = block->containingBlock();    }    else {        // No anonymous block available for use.  Make one.        pre = block->createAnonymousBlock();        madeNewBeforeBlock = true;    }    RenderBlock* post = block->createAnonymousBlock();    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();    if (madeNewBeforeBlock)        block->insertChildNode(pre, boxFirst);    block->insertChildNode(newBlockBox, boxFirst);    block->insertChildNode(post, boxFirst);    block->setChildrenInline(false);    if (madeNewBeforeBlock) {        RenderObject* o = boxFirst;        while (o)        {            RenderObject* no = o;            o = no->nextSibling();            pre->appendChildNode(block->removeChildNode(no));            no->setNeedsLayoutAndMinMaxRecalc();        }    }    splitInlines(pre, post, newBlockBox, beforeChild, oldCont);    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting    // time in makeChildrenNonInline by just setting this explicitly up front.    newBlockBox->setChildrenInline(false);    // We don't just call addChild, since it would pass things off to the    // continuation, so we call addChildToFlow explicitly instead.  We delayed    // adding the newChild until now so that the |newBlockBox| would be fully    // connected, thus allowing newChild access to a renderArena should it need    // to wrap itself in additional boxes (e.g., table construction).    newBlockBox->addChildToFlow(newChild, 0);    // XXXdwh is any of this even necessary? I don't think it is.    pre->close();    pre->setPos(0, -500000);    pre->setNeedsLayout(true);    newBlockBox->close();    newBlockBox->setPos(0, -500000);    newBlockBox->setNeedsLayout(true);    post->close();    post->setPos(0, -500000);    post->setNeedsLayout(true);    block->setNeedsLayoutAndMinMaxRecalc();}void RenderInline::paint(PaintInfo& i,                      int _tx, int _ty){#ifdef DEBUG_LAYOUT    //    kdDebug( 6040 ) << renderName() << "(RenderInline) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;#endif    if ( i.phase == PaintActionElementBackground )        return;    // let the children their backgrounds    PaintAction oldphase = i.phase;    if ( i.phase == PaintActionChildBackgrounds )        i.phase = PaintActionChildBackground;    paintLineBoxBackgroundBorder(i, _tx, _ty);    for( RenderObject *child = firstChild(); child; child = child->nextSibling())        if(!child->layer() && !child->isFloating())            child->paint(i, _tx, _ty);    paintLineBoxDecorations(i, _tx, _ty);    i.phase = oldphase;    if (style()->visibility() == VISIBLE && i.phase == PaintActionOutline) {        paintOutlines(i.p, _tx, _ty);    }}/** * Appends the given coordinate-pair to the point-array if it is not * equal to the last element. * @param pointArray point-array * @param pnt point to append * @return \c true if \c pnt has actually been appended */inline static bool appendIfNew(QValueVector<QPoint> &pointArray, const QPoint &pnt){//   if (!pointArray.isEmpty()) kdDebug(6040) << "appifnew: " << pointArray.back() << " == " << pnt << ": " << (pointArray.back() == pnt) << endl;//   else kdDebug(6040) << "appifnew: " << pnt << " (unconditional)" << endl;    if (!pointArray.isEmpty() && pointArray.back() == pnt) return false;    pointArray.append(pnt);    return true;}/** * Does spike-reduction on the given point-array's stack-top. * * Spikes are path segments of which one goes forward, and the sucessor * goes backward on the predecessor's segment: * * 2      0      1 * x------x<-----x * (0 is stack-top in point-array) * * This will be reduced to * 1      0 * x------x * * Preconditions: * - No other spikes exist in the whole point-array except at most *   one at the end * - No two succeeding points are ever equal * - For each two succeeding points either p1.x == p2.x or p1.y == p2.y holds *   true * - No such spike exists where 2 is situated between 0 and 1. * * Postcondition: * - No spikes exist in the whole point-array * * If no spike is found, the point-array is left unchanged. * @return \c true if an actual reduction was done */inline static bool reduceSpike(QValueVector<QPoint> &pointArray)

⌨️ 快捷键说明

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