📄 render_box.cpp
字号:
switch(m_style->verticalAlign()) { case BASELINE:// kdDebug( 6040 ) << "aligned to baseline" << endl; return m_height; case SUB: // ### case SUPER: // ### case TOP: return -1000; case TEXT_TOP: return MGFontMetrics(m_style->font(), m_part).descent(); case MIDDLE: return -MGFontMetrics(m_style->font(), m_part).width('x')/2; case BOTTOM: return 1000; case TEXT_BOTTOM: return MGFontMetrics(m_style->font(), m_part).ascent(); } return 0;}int RenderBox::bidiHeight() const{ return contentHeight();}void RenderBox::repaint(){ repaintRectangle(0, 0, m_width, m_height);}void RenderBox::repaintRectangle(int x, int y, int w, int h){ x += m_x; y += m_y; RenderObject *o = container(); if( o ) o->repaintRectangle(x, y, w, h);}void RenderBox::repaintObject(RenderObject *o, int x, int y){ x += m_x; y += m_y; RenderObject *c = container(); if( c ) c->repaintObject(o, x, y);}void RenderBox::relativePositionOffset(int &tx, int &ty){ if(!m_style->left().isVariable()) tx += m_style->left().width(containingBlockWidth()); else if(!m_style->right().isVariable()) tx -= m_style->right().width(containingBlockWidth()); if(!m_style->top().isVariable()) { if (!m_style->top().isPercent() || containingBlock()->style()->height().isFixed()) ty += m_style->top().width(containingBlockHeight()); } else if(!m_style->bottom().isVariable()) { if (!m_style->bottom().isPercent() || containingBlock()->style()->height().isFixed()) ty -= m_style->bottom().width(containingBlockHeight()); }}void RenderBox::calcWidth(){#ifdef DEBUG_LAYOUT// kdDebug( 6040 ) << "RenderBox("<<renderName()<<")::calcWidth()" << endl;#endif if (isPositioned()) { calcAbsoluteHorizontal(); } else { Length w = m_style->width(); if (isReplaced()) { if(w.isVariable()) { Length h = m_style->height(); if(intrinsicHeight() > 0 && (h.isFixed() || h.isPercent())) { int myh = h.width(containingBlockHeight()); int iw = (int)((((double)(myh))/((double) intrinsicHeight()))*((double)intrinsicWidth())); w = Length(iw, Fixed); } else w = Length(intrinsicWidth(), Fixed); } else w = Length(w.width(containingBlockWidth()), Fixed); } Length ml = m_style->marginLeft(); Length mr = m_style->marginRight(); int cw = containingBlockWidth(); 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() + borderLeft() + borderRight(); 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(m_width < m_minWidth) m_width = m_minWidth; } else {// kdDebug( 6040 ) << "non-variable " << w.type << ","<< w.value << endl; m_width = w.width(cw); m_width += paddingLeft() + paddingRight() + borderLeft() + borderRight(); if(m_width < m_minWidth) m_width = m_minWidth; 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 ) { m_marginRight = (cw - m_width)/2; m_marginLeft = cw - m_width - m_marginRight; } 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 if (isTableCell()) return; if (isPositioned()) calcAbsoluteVertical(); else { Length h = m_style->height(); if (isReplaced()) { if(h.isVariable()) { Length w = m_style->width(); if(intrinsicWidth() > 0 && (w.isFixed() || w.isPercent())) { int myw = w.width(containingBlockWidth()); int ih = (int) ((((double)(myw))/((double)intrinsicWidth()))*((double)intrinsicHeight())); h = Length(ih, Fixed); } else h = Length(intrinsicHeight(), Fixed); } else h = Length(h.width(containingBlockHeight()), Fixed); } Length tm = style()->marginTop(); Length bm = style()->marginBottom(); Length ch = containingBlock()->style()->height(); // margins are calculated with respect to the _width_ of // the containing block (8.3) int cw = containingBlockWidth(); m_marginTop = tm.minWidth(cw); m_marginBottom = bm.minWidth(cw); // for tables, calculate margins only if (isTable()) return; if (h.isFixed()) m_height = QMAX (h.value + borderTop() + paddingTop() + borderBottom() + paddingBottom() , m_height); else if (h.isPercent()) { if (ch.isFixed()) m_height = QMAX (h.width(ch.value) + borderTop() + paddingTop() + borderBottom() + paddingBottom(), m_height); } }}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(!m_style->left().isVariable()) l = m_style->left().width(cw); if(!m_style->right().isVariable()) r = m_style->right().width(cw); if(!m_style->width().isVariable()) w = m_style->width().width(cw); else if (isReplaced()) w = intrinsicWidth(); if(!m_style->marginLeft().isVariable()) ml = m_style->marginLeft().width(cw); if(!m_style->marginRight().isVariable()) mr = m_style->marginRight().width(cw); // css2 spec 10.3.7 & 10.3.8 // 1 RenderObject* o=parent(); if (style()->direction()==LTR && l==AUTO ) { if (m_next) l = m_next->xPos(); else if (m_previous) l = m_previous->xPos()+m_previous->contentWidth(); else l=0; while (o && o!=containingBlock()) { l+=o->xPos(); o=o->parent(); } } // 2 else if (style()->direction()==RTL && r==AUTO ) { if (m_previous) r = (m_previous->xPos() + m_previous->contentWidth()); else if (m_next) r = m_next->xPos(); else r=0; r += cw - (o->width()-o->borderLeft()-o->borderRight()-o->paddingLeft()-o->paddingRight()); while (o && o!=containingBlock()) { r-=o->xPos(); o=o->parent(); } }// printf("h12: w=%d, l=%d, r=%d, ml=%d, mr=%d\n",w,l,r,ml,mr); // 3 if (w==AUTO) { if (l==AUTO) l=0; if (r==AUTO) r=0; };// printf("h3: w=%d, l=%d, r=%d, ml=%d, mr=%d\n",w,l,r,ml,mr); // 4 if (w==AUTO || l==AUTO || r==AUTO) { if (ml==AUTO) ml=0; if (mr==AUTO) mr=0; }// printf("h4: w=%d, l=%d, r=%d, ml=%d, mr=%d\n",w,l,r,ml,mr); // 5 if (ml==AUTO && mr==AUTO) { int ot = w + r + l + pab; ml = (cw - ot)/2; mr = cw - ot - ml; }// printf("h5: w=%d, l=%d, r=%d, ml=%d, mr=%d\n",w,l,r,ml,mr); // 6 if (w==AUTO) w = cw - ( r + l + ml + mr + pab); if (l==AUTO) l = cw - ( r + w + ml + mr + pab); if (r==AUTO) r = cw - ( l + w + ml + mr + pab); if (ml==AUTO) ml = cw - ( r + l + w + mr + pab); if (mr==AUTO) mr = cw - ( r + l + w + ml + pab);// printf("h6: w=%d, l=%d, r=%d, ml=%d, mr=%d\n",w,l,r,ml,mr); // 7 if (cw != l + r + w + ml + mr + pab) { if (m_style->left().isVariable()) l = cw - ( r + w + ml + mr + pab); else if (m_style->right().isVariable()) r = cw - ( l + w + ml + mr + pab); else if (style()->direction()==LTR) r = cw - ( l + w + ml + mr + pab); else l = cw - ( r + w + ml + mr + pab); } m_width = w + pab; m_marginLeft = ml+l; m_marginRight = mr+r; 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(){ 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(!m_style->top().isVariable()) t = m_style->top().width(ch); if(!m_style->bottom().isVariable()) b = m_style->bottom().width(ch); if(!m_style->height().isVariable()) { h = m_style->height().width(ch); // use real height if higher if (h < m_height - pab) h = m_height - pab; } else if (isReplaced()) h = intrinsicHeight(); if(!m_style->marginTop().isVariable()) mt = m_style->marginTop().width(ch); if(!m_style->marginBottom().isVariable()) mb = m_style->marginBottom().width(ch); // css2 spec 10.6.4 & 10.6.5 // 1 RenderObject* o = parent(); if (t==AUTO && (h==AUTO || b==AUTO)) { if (m_next) t = m_next->yPos(); else if (m_previous) t = m_previous->yPos()+m_previous->height(); else t=0; while (o && o!=containingBlock()) { t+=o->yPos(); o=o->parent(); } } // 2 if (b==AUTO && h==AUTO) b=0; // 3 if (b==AUTO || h==AUTO || t==AUTO) { if (mt==AUTO) mt=0; if (mb==AUTO) mb=0; } // 4 if (mt==AUTO && mb==AUTO) { int ot = h + t + b + pab; mt = (ch - ot)/2; mb = ch - ot - mt; } // 5 if (h==AUTO) h = ch - ( t+b+mt+mb+pab); if (t==AUTO) t = ch - ( h+b+mt+mb+pab); if (b==AUTO) b = ch - ( h+t+mt+mb+pab); if (mt==AUTO) mt = ch - ( h+t+b+mb+pab); if (mb==AUTO) mb = ch - ( h+t+b+mt+pab); if (m_height<h+pab) m_height = h+pab; // add the top and bottom distance to the value of margin. // in principle this is incorrect, but no one (except // the document height code, where it is useful) should // care about it anyway m_marginTop = mt+t; m_marginBottom = mb+b; 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();}#undef DEBUG_LAYOUT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -