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

📄 render_flow.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }    return 0;}void RenderFlow::calcMinMaxWidth(){    m_minWidth = 0;    m_maxWidth = 0;            if (isInline())        return;//    if(minMaxKnown())//        return;    // non breaking space    const QChar nbsp = 0xa0;    RenderObject *child = firstChild();    RenderObject *prevchild = 0;    if(childrenInline())    {        int inlineMax=0;        int inlineMin=0;        bool noBreak=false;        while(child != 0)        {            if( !child->isBR() )            {                int margins = 0;                if (!child->style()->marginLeft().isVariable())                    margins += child->marginLeft();                if (!child->style()->marginRight().isVariable())                    margins += child->marginRight();                int childMin = child->minWidth() + margins;                int childMax = child->maxWidth() + margins;                if (child->isText() && static_cast<RenderText *>(child)->length() > 0)                {                    if(!child->minMaxKnown())                        child->calcMinMaxWidth();                    bool hasNbsp=false;                    RenderText* t = static_cast<RenderText *>(child);                    if (t->data()[0] == nbsp) //inline starts with nbsp                    {                        inlineMin += childMin;                        inlineMax += childMax;                        hasNbsp = true;                    }                    if (hasNbsp && t->data()[t->length()-1]==nbsp)                    {                           //inline starts and ends with nbsp                        noBreak=true;                    }                    else if (t->data()[t->length()-1] == nbsp)                    {                           //inline only ends with nbsp                        if(inlineMin < childMin) inlineMin = childMin;                        inlineMax += childMax;                        noBreak = true;                        hasNbsp = true;                    }                    if (hasNbsp)                    {                        child = next(child);	        prevchild = child;                        hasNbsp = false;                        continue;                    }                }                if (noBreak ||                         (prevchild && prevchild->isFloating() && child->isFloating()))                {                    inlineMin += childMin;                    inlineMax += childMax;                    noBreak = false;                }                else                {                    if(inlineMin < childMin) inlineMin = childMin;                    inlineMax += childMax;                }            }            else            {                if(m_minWidth < inlineMin) m_minWidth = inlineMin;                if(m_maxWidth < inlineMax) m_maxWidth = inlineMax;                inlineMin = inlineMax = 0;            }            prevchild = child;            child = next(child);        }        if(m_minWidth < inlineMin) m_minWidth = inlineMin;        if(m_maxWidth < inlineMax) m_maxWidth = inlineMax;//        kdDebug( 6040 ) << "m_maxWidth=" << m_maxWidth << endl;    }    else    {        while(child != 0)        {            if(!child->minMaxKnown())                child->calcMinMaxWidth();            int margin=0;            //  auto margins don't affect minwidth            Length ml = child->style()->marginLeft();            Length mr = child->style()->marginRight();            if (ml.type!=Variable && mr.type!=Variable)            {                if (child->style()->width().type!=Variable)                {                    if (child->style()->direction()==LTR)                        margin = child->marginLeft();                    else                        margin = child->marginRight();                }                else                    margin = child->marginLeft()+child->marginRight();            }            else if (ml.type != Variable)                margin = child->marginLeft();            else if (mr.type != Variable)                margin = child->marginRight();            if (margin<0) margin=0;            int w = child->minWidth() + margin;            if(m_minWidth < w) m_minWidth = w;            w = child->maxWidth() + margin;            if(m_maxWidth < w) m_maxWidth = w;            child = child->nextSibling();        }    }    if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth;    int toAdd = 0;    if(m_style->hasBorder())        toAdd = borderLeft() + borderRight();    if(m_style->hasPadding())        toAdd += paddingLeft() + paddingRight();    m_minWidth += toAdd;    m_maxWidth += toAdd;//    seems to work but I'm not sure so I better leave it out//    maybe checking minMaxKnown() for each child and only set it if//    all childs have minMaxKnown() set ? this should be save? (Dirk)//    if(childrenInline())//        setMinMaxKnown();    // ### compare with min/max width set in style sheet...}void RenderFlow::close(){//    kdDebug( 6040 ) << (void*)this<< " renderFlow::close()" << endl;    if(haveAnonymousBox())    {        m_last->close();        //kdDebug( 6040 ) << "RenderFlow::close(): closing anonymous box" << endl;        setHaveAnonymousBox(false);    }    calcWidth();    calcHeight();    calcMinMaxWidth();    if(containingBlockWidth() < m_minWidth && m_parent)        containingBlock()->updateSize();    else        containingBlock()->updateHeight();    setParsing(false);#ifdef DEBUG_LAYOUT//    kdDebug( 6040 ) << renderName() << "(RenderFlow)::close() total height =" << m_height << endl;#endif}void RenderFlow::addChild(RenderObject *newChild, RenderObject *beforeChild){#ifdef DEBUG_LAYOUT//    kdDebug( 6040 ) << renderName() << "(RenderFlow)::addChild( " << newChild->renderName() <<                       ", " << (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;//    kdDebug( 6040 ) << "current height = " << m_height << endl;#endif    bool nonInlineInChild = false;    if (beforeChild && beforeChild->parent() != this) {        // perhaps beforeChild is inside an anonymous box that is our child        if (!newChild->isInline() && !newChild->isFloating() && beforeChild->parent() &&            beforeChild->parent()->isAnonymousBox() && beforeChild->parent()->parent() == this)            nonInlineInChild = true;        else {            beforeChild->parent()->addChild(newChild,beforeChild);            return;        }    }    //to prevents non-layouted elements from getting printed    if (!newChild->isInline() && !newChild->isFloating())    {        newChild->setYPos(-500000);    }    if (!newChild->isText())    {        if (newChild->style()->position() != STATIC)                setContainsPositioned(true);    }    if((m_childrenInline && !newChild->isInline() && !newChild->isFloating()) ||       nonInlineInChild)    {        RenderObject *boxSource;        if (nonInlineInChild)            boxSource = beforeChild->parent();        else            boxSource = this;        // put all inline children from boxSource in two anonymous block boxes -        // one containing those before beforeChild, and one containing beforeChild and after        if(boxSource->lastChild())        {//          kdDebug( 6040 ) << "no inline child, moving previous inline children!" << endl;            RenderFlow *beforeBox = 0;            if(beforeChild != boxSource->firstChild()) {                RenderStyle *newStyle = new RenderStyle(boxSource->style());                newStyle->setDisplay(BLOCK);                beforeBox = new RenderFlow();                beforeBox->setPart(m_part);                beforeBox->setStyle(newStyle);                beforeBox->setIsAnonymousBox(true);                // ### the children have a wrong style!!!                // They get exactly the style of this element, not of the anonymous box                // might be important for bg colors!                beforeBox->setFirstChild(boxSource->firstChild());                RenderObject *beforeBoxLast;                if (beforeChild)                    beforeBoxLast = beforeChild->previousSibling();                else                    beforeBoxLast = boxSource->lastChild();                beforeBoxLast->setNextSibling(0);                beforeBox->setLastChild(beforeBoxLast);                RenderObject *o = beforeBox->firstChild();                while(o) {                    o->setParent(beforeBox);                    o = o->nextSibling();                }                beforeBox->setParent(boxSource);                boxSource->setFirstChild(beforeBox);                boxSource->setLastChild(beforeBox);                beforeBox->close();                beforeBox->setYPos(-100000);                beforeBox->setLayouted(false);            }            if (beforeChild) {                RenderFlow *afterBox = new RenderFlow();                afterBox = new RenderFlow();                RenderStyle *newStyle = new RenderStyle(boxSource->style());                newStyle->setDisplay(BLOCK);                afterBox->setPart(m_part);                afterBox->setStyle(newStyle);                afterBox->setIsAnonymousBox(true);                // ### the children have a wrong style!!!                // They get exactly the style of this element, not of the anonymous box                // might be important for bg colors!                beforeChild->setPreviousSibling(0);                afterBox->setFirstChild(beforeChild);                RenderObject *o = afterBox->firstChild();                while(o)                {                    // a bit hacky, but should work                    afterBox->setLastChild(o);                    o->setParent(afterBox);                    o = o->nextSibling();                }                afterBox->setParent(boxSource);                boxSource->setLastChild(afterBox);                if(beforeBox)                  beforeBox->setNextSibling(afterBox);                else                  boxSource->setFirstChild(afterBox);                afterBox->setPreviousSibling(beforeBox);                afterBox->close();                afterBox->setYPos(-100000);                afterBox->setLayouted(false);                beforeChild = afterBox;            }            if (nonInlineInChild) {                boxSource->setLayouted(false);                // boxSource will now contain up to two anonymous boxes - move                // them into this in place of boxSource                boxSource->firstChild()->setParent(this);                boxSource->firstChild()->setPreviousSibling(boxSource->previousSibling());                if (boxSource->previousSibling())                    boxSource->previousSibling()->setNextSibling(boxSource->firstChild());                boxSource->lastChild()->setParent(this);                boxSource->lastChild()->setNextSibling(boxSource->nextSibling());                if (boxSource->nextSibling())                    boxSource->nextSibling()->setPreviousSibling(boxSource->lastChild());                if (m_first == boxSource)                    m_first = boxSource->firstChild();                if (m_last == boxSource)                    m_last = boxSource->lastChild();                // make sure boxSource doesn't muck other objects up when deleted                boxSource->setFirstChild(0);                boxSource->setLastChild(0);                boxSource->setPreviousSibling(0);                boxSource->setNextSibling(0);                delete boxSource;                // ### what happens with boxSource's bg image if it had one?            }        }        m_childrenInline = false;    }    else if(!m_childrenInline)    {        if(newChild->isInline() || newChild->isFloating())        {            // #### this won't work with beforeChild != 0 !!!!            if (beforeChild && beforeChild->previousSibling() && beforeChild->previousSibling()->isAnonymousBox()) {                beforeChild->previousSibling()->addChild(newChild);                setLayouted(false);                return;            }//          kdDebug( 6040 ) << "adding inline child to anonymous box" << endl;            if(!haveAnonymousBox())            {                //kdDebug( 6040 ) << "creating anonymous box" << endl;                RenderStyle *newStyle = new RenderStyle(m_style);                newStyle->setDisplay(BLOCK);                RenderFlow *newBox = new RenderFlow();                newBox->setPart(m_part);                newBox->setStyle(newStyle);                newBox->setIsAnonymousBox(true);                RenderObject::addChild(newBox,beforeChild);                newBox->addChild(newChild);                newBox->setYPos(-100000);                setHaveAnonymousBox();                return;            }            else            {                //kdDebug( 6040 ) << "adding to last box" << endl;                m_last->addChild(newChild); // ,beforeChild ???                return;            }        }        else if(haveAnonymousBox())        {            m_last->close();            m_last->layout();            setHaveAnonymousBox(false);//          kdDebug( 6040 ) << "closing anonymous box" << endl;        }    }    else if(!newChild->isInline() && !newChild->isFloating())    {        m_childrenInline = false;    }    if(!newChild->isInline() && !newChild->isFloating())    {        newChild->setParent(this);        if (style()->display() == INLINE)        {            m_inline=false; // inline can't contain blocks            if (parent() && parent()->isFlow())                static_cast<RenderFlow*>(parent())->makeChildrenNonInline();        }    }    setLayouted(false);    RenderObject::addChild(newChild,beforeChild);    // ### care about aligned stuff}void RenderFlow::makeChildrenNonInline(){// Put all inline children into anonymous block boxes// ### should we call this all the way up to the top of the tree?    m_childrenInline = false;    RenderObject *child = m_first;    RenderObject *next;    RenderObject *boxFirst = m_first;    RenderObject *boxLast = m_first;    while (child) {        next = child->nextSibling();        if (child->isInline() || child->isFloating()) {            boxLast = child;        }        if ((!child->isInline() && !child->isFloating() && boxFirst != child) ||            (!next && (boxFirst->isInline() || boxFirst->isFloating()))) {            // make anon box of those before child            RenderStyle *newStyle = new RenderStyle(style());            newStyle->setDisplay(BLOCK);            RenderFlow *box = new RenderFlow();            box->setPart(m_part);            box->setStyle(newStyle);            box->setIsAnonymousBox(true);            // ### the children have a wrong style!!!            // They get exactly the style of this element, not of the anonymous box            // might be important for bg colors!            box->setPreviousSibling(boxFirst->previousSibling());            if (boxFirst->previousSibling())                boxFirst->previousSibling()->setNextSibling(box);            boxFirst->setPreviousSibling(0);            box->setNextSibling(boxLast->nextSibling());            if (boxLast->nextSibling())                boxLast->nextSibling()->setPreviousSibling(box);            boxLast->setNextSibling(0);            if (m_first == boxFirst)                m_first = box;            if (m_last == boxLast)                m_last = box;            box->setFirstChild(boxFirst);            box->setLastChild(boxLast);            RenderObject *o = box->firstChild();            while(o) {                o->setParent(box);                o = o->nextSibling();            }            box->setParent(this);            box->close();            box->setYPos(-100000);            box->setLayouted(false);        }        if (!child->isInline() && !child->isFloating())            boxFirst = boxLast = next;        child = next;    }    if ( isInline() ) {        m_inline = false;        if ( parent()->isFlow() )            static_cast<RenderFlow *>(parent())->makeChildrenNonInline();    }    setLayouted(false);}void RenderFlow::specialHandler(RenderObject *o){//    kdDebug( 6040 ) << "specialHandler" << endl;    if(o->isFloating())        insertFloat(o);    else if(o->isPositioned())        static_cast<RenderFlow*>(o->containingBlock())->insertPositioned(o);}#undef DEBUG#undef DEBUG_LAYOUT#undef BOX_DEBUG

⌨️ 快捷键说明

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