📄 render_flow.cpp
字号:
} 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 + -