📄 render_box.cpp
字号:
void RenderBox::calcWidth(){#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << "RenderBox("<<renderName()<<")::calcWidth()" << endl;#endif if (isPositioned()) { calcAbsoluteHorizontal(); } else { Length w; if ( isReplaced () ) w = Length( static_cast<RenderReplaced*>( this )->calcReplacedWidth(), Fixed ); else w = style()->width(); Length ml = style()->marginLeft(); Length mr = style()->marginRight(); int cw; RenderObject *cb = containingBlock(); if ( style()->flowAroundFloats() && cb->isFlow() ) cw = static_cast<RenderFlow *>(cb)->lineWidth( m_y ); else cw = cb->contentWidth(); if (cw<0) cw = 0; m_marginLeft = 0; m_marginRight = 0; if (isInline()) { // just calculate margins m_marginLeft = ml.minWidth(cw); m_marginRight = mr.minWidth(cw); if (isReplaced()) { m_width = w.width(cw); m_width += paddingLeft() + paddingRight() + style()->borderLeftWidth() + style()->borderRightWidth(); if(m_width < m_minWidth) m_width = m_minWidth; } return; } else if (w.type == Variable) {// kdDebug( 6040 ) << "variable" << endl; m_marginLeft = ml.minWidth(cw); m_marginRight = mr.minWidth(cw); if (cw) m_width = cw - m_marginLeft - m_marginRight;// kdDebug( 6040 ) << m_width <<"," << cw <<"," <<// m_marginLeft <<"," << m_marginRight << endl; if (isFloating()) { calcMinMaxWidth(); if(m_width < m_minWidth) m_width = m_minWidth; if(m_width > m_maxWidth) m_width = m_maxWidth; } } else {// kdDebug( 6040 ) << "non-variable " << w.type << ","<< w.value << endl; m_width = w.width(cw); m_width += paddingLeft() + paddingRight() + style()->borderLeftWidth() + style()->borderRightWidth(); calcHorizontalMargins(ml,mr,cw); } if (cw && cw != m_width + m_marginLeft + m_marginRight && !isFloating() && !isInline()) { if (style()->direction()==LTR) m_marginRight = cw - m_width - m_marginLeft; else m_marginLeft = cw - m_width - m_marginRight; } }#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << "RenderBox::calcWidth(): m_width=" << m_width << " containingBlockWidth()=" << containingBlockWidth() << endl; kdDebug( 6040 ) << "m_marginLeft=" << m_marginLeft << " m_marginRight=" << m_marginRight << endl;#endif}void RenderBox::calcHorizontalMargins(const Length& ml, const Length& mr, int cw){ if (isFloating()) { m_marginLeft = ml.minWidth(cw); m_marginRight = mr.minWidth(cw); } else { if ( (ml.type == Variable && mr.type == Variable) || (ml.type != Variable && containingBlock()->style()->textAlign() == KONQ_CENTER) ) { m_marginLeft = (cw - m_width)/2; if (m_marginLeft<0) m_marginLeft=0; m_marginRight = cw - m_width - m_marginLeft; } else if (mr.type == Variable) { m_marginLeft = ml.width(cw); m_marginRight = cw - m_width - m_marginLeft; } else if (ml.type == Variable) { m_marginRight = mr.width(cw); m_marginLeft = cw - m_width - m_marginRight; } else { m_marginLeft = ml.minWidth(cw); m_marginRight = mr.minWidth(cw); } }}void RenderBox::calcHeight(){#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << "RenderBox::calcHeight()" << endl;#endif //cell height is managed by table, inline elements do not have a height property. if ( isTableCell() || (isInline() && !isReplaced()) ) return; if (isPositioned()) calcAbsoluteVertical(); else { Length h; if ( isReplaced() ) h = Length( static_cast<RenderReplaced*>( this )-> calcReplacedHeight(), Fixed ); else h = style()->height(); calcVerticalMargins(); // for tables, calculate margins only if (isTable()) return; if (!h.isVariable()) { int fh=-1; if (h.isFixed()) fh = h.value + borderTop() + paddingTop() + borderBottom() + paddingBottom(); else if (h.isPercent()) { Length ch = containingBlock()->style()->height(); if (ch.isFixed()) fh = h.width(ch.value) + borderTop() + paddingTop() + borderBottom() + paddingBottom(); } if (fh!=-1) { //containsPositioned needs a less misleading name if (fh<m_height && !containsPositioned() && style()->overflow()==OVISIBLE) { setContainsPositioned(true); } m_height = fh; } } }}void RenderBox::calcVerticalMargins(){ if( isTableCell() ) { // table margins are basically infinite m_marginTop = TABLECELLMARGIN; m_marginBottom = TABLECELLMARGIN; return; } Length tm = style()->marginTop(); Length bm = style()->marginBottom(); // margins are calculated with respect to the _width_ of // the containing block (8.3) int cw = containingBlock()->contentWidth(); m_marginTop = tm.minWidth(cw); m_marginBottom = bm.minWidth(cw);}void RenderBox::calcAbsoluteHorizontal(){ const int AUTO = -666666; int l,r,w,ml,mr,cw; int pab = borderLeft()+ borderRight()+ paddingLeft()+ paddingRight(); l=r=ml=mr=w=AUTO; cw = containingBlockWidth() +containingBlock()->paddingLeft() +containingBlock()->paddingRight(); if(!style()->left().isVariable()) l = style()->left().width(cw); if(!style()->right().isVariable()) r = style()->right().width(cw); if(!style()->width().isVariable()) w = style()->width().width(cw); else if (isReplaced()) w = intrinsicWidth(); if(!style()->marginLeft().isVariable()) ml = style()->marginLeft().width(cw); if(!style()->marginRight().isVariable()) mr = style()->marginRight().width(cw);// printf("h1: w=%d, l=%d, r=%d, ml=%d, mr=%d\n",w,l,r,ml,mr); int static_distance=0; if ((style()->direction()==LTR && (l==AUTO && r==AUTO )) || style()->left().isStatic()) { // calc hypothetical location in the normal flow // used for 1) left=static-position // 2) left, right, width are all auto -> calc top -> 3. // 3) precalc for case 2 below // all positioned elements are blocks, so that // would be at the left edge RenderObject* po = parent(); while (po && po!=containingBlock()) { static_distance+=po->xPos(); po=po->parent(); } if (l==AUTO || style()->left().isStatic()) l = static_distance; } else if ((style()->direction()==RTL && (l==AUTO && r==AUTO )) || style()->right().isStatic()) { RenderObject* po = parent(); static_distance = cw - po->width(); while (po && po!=containingBlock()) { static_distance-=po->xPos(); po=po->parent(); } if (r==AUTO || style()->right().isStatic()) r = static_distance; } if (l!=AUTO && w!=AUTO && r!=AUTO) { // left, width, right all given, play with margins int ot = l + w + r + pab; if (ml==AUTO && mr==AUTO) { // both margins auto, solve for equality ml = (cw - ot)/2; mr = cw - ot - ml; } else if (ml==AUTO) // solve for left margin ml = cw - ot - mr; else if (mr==AUTO) // solve for right margin mr = cw - ot - ml; else { // overconstrained, solve according to dir if (style()->direction()==LTR) r = cw - ( l + w + ml + mr + pab); else l = cw - ( r + w + ml + mr + pab); } } else { // one or two of (left, width, right) missing, solve // auto margins are ignored if (ml==AUTO) ml = 0; if (mr==AUTO) mr = 0; //1. solve left & width. if (l==AUTO && w==AUTO && r!=AUTO) { w = QMIN(m_maxWidth, cw - ( r + ml + mr + pab)); l = cw - ( r + w + ml + mr + pab); } else //2. solve left & right. use static positioning. if (l==AUTO && w!=AUTO && r==AUTO) { if (style()->direction()==RTL) { r = static_distance; l = cw - ( r + w + ml + mr + pab); } else { l = static_distance; r = cw - ( l + w + ml + mr + pab); } } else //3. solve width & right. if (l!=AUTO && w==AUTO && r==AUTO) { w = QMIN(m_maxWidth, cw - ( l + ml + mr + pab)); r = cw - ( l + w + ml + mr + pab); } else //4. solve left if (l==AUTO && w!=AUTO && r!=AUTO) l = cw - ( r + w + ml + mr + pab); else //5. solve width if (l!=AUTO && w==AUTO && r!=AUTO) w = cw - ( r + l + ml + mr + pab); else //6. solve right if (l!=AUTO && w!=AUTO && r==AUTO) r = cw - ( l + w + ml + mr + pab); } m_width = w + pab; m_marginLeft = ml; m_marginRight = mr; m_x = l + ml + containingBlock()->borderLeft();// printf("h: w=%d, l=%d, r=%d, ml=%d, mr=%d\n",w,l,r,ml,mr);}void RenderBox::calcAbsoluteVertical(){ // css2 spec 10.6.4 & 10.6.5 // based on // http://www.w3.org/Style/css2-updates/REC-CSS2-19980512-errata // (actually updated 2000-10-24) // that introduces static-position value for top, left & right const int AUTO = -666666; int t,b,h,mt,mb,ch; t=b=h=mt=mb=AUTO; int pab = borderTop()+borderBottom()+paddingTop()+paddingBottom(); Length hl = containingBlock()->style()->height(); if (hl.isFixed()) ch = hl.value + containingBlock()->paddingTop() + containingBlock()->paddingBottom(); else ch = containingBlock()->height(); if(!style()->top().isVariable()) t = style()->top().width(ch); if(!style()->bottom().isVariable()) b = style()->bottom().width(ch); if(!style()->height().isVariable()) { h = style()->height().width(ch); if (m_height-pab>h) h=m_height-pab; } else if (isReplaced()) h = intrinsicHeight(); if(!style()->marginTop().isVariable()) mt = style()->marginTop().width(ch); if(!style()->marginBottom().isVariable()) mb = style()->marginBottom().width(ch); int static_top=0; if ((t==AUTO && b==AUTO ) || style()->top().isStatic()) { // calc hypothetical location in the normal flow // used for 1) top=static-position // 2) top, bottom, height are all auto -> calc top -> 3. // 3) precalc for case 2 below RenderObject* ro = previousSibling(); while ( ro && ro->isPositioned()) ro = ro->previousSibling(); if (ro) static_top = ro->yPos()+ro->marginBottom()+ro->height(); RenderObject* po = parent(); while (po && po!=containingBlock()) { static_top+=po->yPos(); po=po->parent(); } if (h==AUTO || style()->top().isStatic()) t = static_top; } if (t!=AUTO && h!=AUTO && b!=AUTO) { // top, height, bottom all given, play with margins int ot = h + t + b + pab; if (mt==AUTO && mb==AUTO) { // both margins auto, solve for equality mt = (ch - ot)/2; mb = ch - ot - mt; } else if (mt==AUTO) // solve for top margin mt = ch - ot - mb; else if (mb==AUTO) // solve for bottom margin mb = ch - ot - mt; else // overconstrained, solve for bottom b = ch - ( h+t+mt+mb+pab); } else { // one or two of (top, height, bottom) missing, solve // auto margins are ignored if (mt==AUTO) mt = 0; if (mb==AUTO) mb = 0; //1. solve top & height. use content height. if (t==AUTO && h==AUTO && b!=AUTO) { h = m_height-pab; t = ch - ( h+b+mt+mb+pab); } else //2. solve top & bottom. use static positioning. if (t==AUTO && h!=AUTO && b==AUTO) { t = static_top; b = ch - ( h+t+mt+mb+pab); } else //3. solve height & bottom. use content height. if (t!=AUTO && h==AUTO && b==AUTO) { h = m_height-pab; b = ch - ( h+t+mt+mb+pab); } else //4. solve top if (t==AUTO && h!=AUTO && b!=AUTO) t = ch - ( h+b+mt+mb+pab); else //5. solve height if (t!=AUTO && h==AUTO && b!=AUTO) h = ch - ( t+b+mt+mb+pab); else //6. solve bottom if (t!=AUTO && h!=AUTO && b==AUTO) b = ch - ( h+t+mt+mb+pab); } if (m_height<h+pab) //content must still fit m_height = h+pab; m_marginTop = mt; m_marginBottom = mb; m_y = t + mt + containingBlock()->borderTop();// printf("v: h=%d, t=%d, b=%d, mt=%d, mb=%d, m_y=%d\n",h,t,b,mt,mb,m_y);}int RenderBox::lowestPosition() const{ return m_height + marginBottom();}int RenderBox::rightmostPosition() const{ return m_width;}#undef DEBUG_LAYOUT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -