00001
00024
00025
00026
00027
00028
00029 #include <qpainter.h>
00030
00031 #include "rendering/render_box.h"
00032 #include "rendering/render_replaced.h"
00033 #include "rendering/render_root.h"
00034 #include "misc/htmlhashes.h"
00035 #include "xml/dom_nodeimpl.h"
00036
00037 #include <khtmlview.h>
00038 #include <kdebug.h>
00039 #include <kglobal.h>
00040 #include <assert.h>
00041
00042
00043 using namespace DOM;
00044 using namespace khtml;
00045
00046 #define TABLECELLMARGIN -0x4000
00047
00048 RenderBox::RenderBox(DOM::NodeImpl* node)
00049 : RenderContainer(node)
00050 {
00051 m_minWidth = -1;
00052 m_maxWidth = -1;
00053 m_width = m_height = 0;
00054 m_x = 0;
00055 m_y = 0;
00056 m_marginTop = 0;
00057 m_marginBottom = 0;
00058 m_marginLeft = 0;
00059 m_marginRight = 0;
00060 }
00061
00062 void RenderBox::setStyle(RenderStyle *_style)
00063 {
00064 RenderObject::setStyle(_style);
00065
00066 switch(_style->position())
00067 {
00068 case ABSOLUTE:
00069 case FIXED:
00070 setPositioned(true);
00071 break;
00072 default:
00073 setPositioned(false);
00074 if(!isTableCell() && _style->isFloating()) {
00075 setFloating(true);
00076 } else {
00077 if(_style->position() == RELATIVE)
00078 setRelPositioned(true);
00079 }
00080 }
00081 }
00082
00083 RenderBox::~RenderBox()
00084 {
00085
00086 }
00087
00088 short RenderBox::contentWidth() const
00089 {
00090 short w = m_width - style()->borderLeftWidth() - style()->borderRightWidth();
00091 w -= paddingLeft() + paddingRight();
00092
00093
00094 return w;
00095 }
00096
00097 int RenderBox::contentHeight() const
00098 {
00099 int h = m_height - style()->borderTopWidth() - style()->borderBottomWidth();
00100 h -= paddingTop() + paddingBottom();
00101
00102 return h;
00103 }
00104
00105 void RenderBox::setPos( int xPos, int yPos )
00106 {
00107 m_x = xPos; m_y = yPos;
00108 }
00109
00110 short RenderBox::width() const
00111 {
00112 return m_width;
00113 }
00114
00115 int RenderBox::height() const
00116 {
00117 return m_height;
00118 }
00119
00120
00121
00122
00123 void RenderBox::paint(QPainter *p, int _x, int _y, int _w, int _h,
00124 int _tx, int _ty)
00125 {
00126 _tx += m_x;
00127 _ty += m_y;
00128
00129
00130 RenderObject *child = firstChild();
00131 while(child != 0)
00132 {
00133 child->paint(p, _x, _y, _w, _h, _tx, _ty);
00134 child = child->nextSibling();
00135 }
00136 }
00137
00138 void RenderBox::setPixmap(const QPixmap &, const QRect&, CachedImage *image)
00139 {
00140 if(image && image->pixmap_size() == image->valid_rect().size() && parent())
00141 repaint();
00142 }
00143
00144
00145 void RenderBox::paintBoxDecorations(QPainter *p,int, int _y,
00146 int, int _h, int _tx, int _ty)
00147 {
00148
00149
00150 int w = width();
00151 int h = height() + borderTopExtra() + borderBottomExtra();
00152 _ty -= borderTopExtra();
00153
00154 int my = QMAX(_ty,_y);
00155 int end = QMIN( _y + _h, _ty + h );
00156 int mh = end - my;
00157
00158 paintBackground(p, style()->backgroundColor(), style()->backgroundImage(), my, mh, _tx, _ty, w, h);
00159
00160 if(style()->hasBorder())
00161 paintBorder(p, _tx, _ty, w, h, style());
00162 }
00163
00164 void RenderBox::paintBackground(QPainter *p, const QColor &c, CachedImage *bg, int clipy, int cliph, int _tx, int _ty, int w, int h)
00165 {
00166 if ( cliph < 0 )
00167 return;
00168
00169 if(c.isValid())
00170 p->fillRect(_tx, clipy, w, cliph, c);
00171
00172 if(bg && bg->pixmap_size() == bg->valid_rect().size() && !bg->isTransparent() && !bg->isErrorImage()) {
00173
00174
00175
00176
00177
00178 RenderStyle* sptr = style();
00179 if ( isHtml() && firstChild() && !style()->backgroundImage() )
00180 sptr = firstChild()->style();
00181
00182 int sx = 0;
00183 int sy = 0;
00184 int cw,ch;
00185 int cx,cy;
00186 int vpab = borderRight() + borderLeft();
00187 int hpab = borderTop() + borderBottom();
00188
00189
00190
00191 int pixw = bg->pixmap_size().width();
00192 int pixh = bg->pixmap_size().height();
00193 if (sptr->backgroundAttachment())
00194 {
00195
00196 int pw = m_width - vpab;
00197 int ph = m_height - hpab;
00198 EBackgroundRepeat bgr = sptr->backgroundRepeat();
00199 if( (bgr == NO_REPEAT || bgr == REPEAT_Y) && w > pixw ) {
00200 cw = pixw;
00201 cx = _tx + sptr->backgroundXPosition().minWidth(pw-pixw);
00202 } else {
00203 cw = w-vpab;
00204 cx = _tx;
00205 sx = pixw - ((sptr->backgroundXPosition().minWidth(pw-pixw)) % pixw );
00206 }
00207
00208 cx += borderLeft();
00209
00210 if( (bgr == NO_REPEAT || bgr == REPEAT_X) && h > pixh ) {
00211 ch = pixh;
00212 cy = _ty + sptr->backgroundYPosition().minWidth(ph-pixh);
00213 } else {
00214 ch = h-hpab;
00215 cy = _ty;
00216 sy = pixh - ((sptr->backgroundYPosition().minWidth(ph-pixh)) % pixh );
00217 }
00218
00219 cy += borderTop();
00220 }
00221 else
00222 {
00223
00224 QRect vr = viewRect();
00225 int pw = vr.width();
00226 int ph = vr.height();
00227
00228 EBackgroundRepeat bgr = sptr->backgroundRepeat();
00229 if( (bgr == NO_REPEAT || bgr == REPEAT_Y) && w > pixw ) {
00230 cw = pixw;
00231 cx = vr.x() + sptr->backgroundXPosition().minWidth(pw-pixw);
00232 } else {
00233 cw = pw;
00234 cx = vr.x();
00235 sx = pixw - ((sptr->backgroundXPosition().minWidth(pw-pixw)) % pixw );
00236 }
00237
00238 if( (bgr == NO_REPEAT || bgr == REPEAT_X) && h > pixh ) {
00239 ch = pixh;
00240 cy = vr.y() + sptr->backgroundYPosition().minWidth(ph-pixh);
00241 } else {
00242 ch = ph;
00243 cy = vr.y();
00244 sy = pixh - ((sptr->backgroundYPosition().minWidth(ph-pixh)) % pixh );
00245 }
00246
00247 QRect fix(cx,cy,cw,ch);
00248 QRect ele(_tx+borderLeft(),_ty+borderTop(),w-vpab,h-hpab);
00249 QRect b = fix.intersect(ele);
00250 sx+=b.x()-cx;
00251 sy+=b.y()-cy;
00252 cx=b.x();cy=b.y();cw=b.width();ch=b.height();
00253 }
00254
00255
00256
00257 int diff = clipy - cy;
00258 if ( diff > 0 ) {
00259 cy += diff;
00260 sy += diff;
00261 sy %= pixh;
00262 ch -= diff;
00263 }
00264 ch = QMIN( ch, clipy + cliph - cy );
00265
00266
00267 if (cw>0 && ch>0)
00268 p->drawTiledPixmap(cx, cy, cw, ch, bg->tiled_pixmap(c), sx, sy);
00269
00270
00271 }
00272 }
00273
00274 void RenderBox::outlineBox(QPainter *p, int _tx, int _ty, const char *color)
00275 {
00276 p->setPen(QPen(QColor(color), 1, Qt::DotLine));
00277 p->setBrush( Qt::NoBrush );
00278 p->drawRect(_tx, _ty, m_width, m_height);
00279 }
00280
00281
00282 void RenderBox::calcClip(QPainter* p, int tx, int ty)
00283 {
00284 int clipw = m_width;
00285 int cliph = m_height;
00286
00287 bool rtl = (style()->direction() == RTL);
00288
00289 int clipleft = 0;
00290 int clipright = clipw;
00291 int cliptop = 0;
00292 int clipbottom = cliph;
00293
00294 if ( style()->clipSpecified() && style()->position() == ABSOLUTE ) {
00295
00296 if (!style()->clipLeft().isVariable()) {
00297 int c = style()->clipLeft().width(clipw);
00298 if ( rtl )
00299 clipleft = clipw - c;
00300 else
00301 clipleft = c;
00302 }
00303 if (!style()->clipRight().isVariable()) {
00304 int w = style()->clipRight().width(clipw);
00305 if ( rtl ) {
00306 clipright = clipw - w;
00307 } else {
00308 clipright = w;
00309 }
00310 }
00311 if (!style()->clipTop().isVariable())
00312 cliptop = style()->clipTop().width(cliph);
00313 if (!style()->clipBottom().isVariable())
00314 clipbottom = style()->clipBottom().width(cliph);
00315 }
00316 int clipx = tx + clipleft;
00317 int clipy = ty + cliptop;
00318 clipw = clipright-clipleft;
00319 cliph = clipbottom-cliptop;
00320
00321
00322 QRect cr(clipx,clipy,clipw,cliph);
00323 cr = p->xForm(cr);
00324 QRegion creg(cr);
00325 QRegion old = p->clipRegion();
00326 if (!old.isNull())
00327 creg = old.intersect(creg);
00328
00329 #ifdef CLIP_DEBUG
00330 kdDebug( 6040 ) << renderName() << ":" << this << ": setting clip("<<clipx<<","<<clipy<<","<<clipw<<","<<cliph<<") tx="<<tx<<" ty="<<ty<<endl;
00331 p->setPen(QPen(Qt::red, 1, Qt::DotLine));
00332 p->setBrush( Qt::NoBrush );
00333 p->drawRect(clipx, clipy, clipw, cliph);
00334 #endif
00335
00336 p->save();
00337 p->setClipRegion(creg);
00338 }
00339
00340 void RenderBox::close()
00341 {
00342 setMinMaxKnown(false);
00343 setLayouted( false );
00344 }
00345
00346 short RenderBox::containingBlockWidth() const
00347 {
00348 if ( ( style()->htmlHacks() || isTable() ) && style()->flowAroundFloats() && containingBlock()->isFlow()
00349 && style()->width().isVariable())
00350 return static_cast<RenderFlow*>(containingBlock())->lineWidth(m_y);
00351 else
00352 return containingBlock()->contentWidth();
00353 }
00354
00355 bool RenderBox::absolutePosition(int &xPos, int &yPos, bool f)
00356 {
00357 if ( style()->position() == FIXED )
00358 f = true;
00359 RenderObject *o = container();
00360 if( o && o->absolutePosition(xPos, yPos, f))
00361 {
00362 if(!isInline() || isReplaced())
00363 xPos += m_x, yPos += m_y;
00364
00365 if(isRelPositioned())
00366 relativePositionOffset(xPos, yPos);
00367 return true;
00368 }
00369 else
00370 {
00371 xPos = yPos = 0;
00372 return false;
00373 }
00374 }
00375
00376 void RenderBox::position(int x, int y, int, int, int, bool, bool, int)
00377 {
00378 m_x = x + marginLeft();
00379 m_y = y;
00380
00381
00382 }
00383
00384 void RenderBox::repaint()
00385 {
00386
00387 int ow = style() ? style()->outlineWidth() : 0;
00388 repaintRectangle(-ow, -ow, m_width+ow*2, m_height+ow*2);
00389 }
00390
00391 void RenderBox::repaintRectangle(int x, int y, int w, int h, bool f)
00392 {
00393 x += m_x;
00394 y += m_y;
00395
00396 if (style()->position()==FIXED) f=true;
00397
00398
00399 RenderObject *o = container();
00400 if( o ) o->repaintRectangle(x, y, w, h, f);
00401 }
00402
00403 void RenderBox::relativePositionOffset(int &tx, int &ty)
00404 {
00405 if(!style()->left().isVariable())
00406 tx += style()->left().width(containingBlockWidth());
00407 else if(!style()->right().isVariable())
00408 tx -= style()->right().width(containingBlockWidth());
00409 if(!style()->top().isVariable())
00410 {
00411 if (!style()->top().isPercent()
00412 || containingBlock()->style()->height().isFixed())
00413 ty += style()->top().width(containingBlockHeight());
00414 }
00415 else if(!style()->bottom().isVariable())
00416 {
00417 if (!style()->bottom().isPercent()
00418 || containingBlock()->style()->height().isFixed())
00419 ty -= style()->bottom().width(containingBlockHeight());
00420 }
00421 }
00422
00423 void RenderBox::calcWidth()
00424 {
00425 #ifdef DEBUG_LAYOUT
00426 kdDebug( 6040 ) << "RenderBox("<<renderName()<<")::calcWidth()" << endl;
00427 #endif
00428 if (isPositioned())
00429 {
00430 calcAbsoluteHorizontal();
00431 }
00432 else
00433 {
00434 Length w;
00435 if ( isReplaced () )
00436 w = Length( calcReplacedWidth(), Fixed );
00437 else
00438 w = style()->width();
00439
00440 Length ml = style()->marginLeft();
00441 Length mr = style()->marginRight();
00442
00443 int cw;
00444 RenderObject *cb = containingBlock();
00445 if ( style()->flowAroundFloats() && cb->isFlow() )
00446 cw = static_cast<RenderFlow *>(cb)->lineWidth( m_y );
00447 else
00448 cw = cb->contentWidth();
00449
00450 if (cw<0) cw = 0;
00451
00452 m_marginLeft = 0;
00453 m_marginRight = 0;
00454
00455 if (isInline())
00456 {
00457
00458 m_marginLeft = ml.minWidth(cw);
00459 m_marginRight = mr.minWidth(cw);
00460 if (isReplaced())
00461 {
00462 m_width = w.width(cw);
00463 m_width += paddingLeft() + paddingRight() + style()->borderLeftWidth() + style()->borderRightWidth();
00464
00465 if(m_width < m_minWidth) m_width = m_minWidth;
00466 }
00467
00468 return;
00469 }
00470 else if (w.type == Variable)
00471 {
00472
00473 m_marginLeft = ml.minWidth(cw);
00474 m_marginRight = mr.minWidth(cw);
00475 if (cw) m_width = cw - m_marginLeft - m_marginRight;
00476
00477
00478
00479
00480 if (isFloating()) {
00481 if(m_width < m_minWidth) m_width = m_minWidth;
00482 if(m_width > m_maxWidth) m_width = m_maxWidth;
00483 }
00484 }
00485 else
00486 {
00487
00488 m_width = w.width(cw);
00489 m_width += paddingLeft() + paddingRight() + style()->borderLeftWidth() + style()->borderRightWidth();
00490
00491 calcHorizontalMargins(ml,mr,cw);
00492 }
00493
00494 if (cw && cw != m_width + m_marginLeft + m_marginRight && !isFloating() && !isInline())
00495 {
00496 if (style()->direction()==LTR)
00497 m_marginRight = cw - m_width - m_marginLeft;
00498 else
00499 m_marginLeft = cw - m_width - m_marginRight;
00500 }
00501 }
00502
00503 #ifdef DEBUG_LAYOUT
00504 kdDebug( 6040 ) << "RenderBox::calcWidth(): m_width=" << m_width << " containingBlockWidth()=" << containingBlockWidth() << endl;
00505 kdDebug( 6040 ) << "m_marginLeft=" << m_marginLeft << " m_marginRight=" << m_marginRight << endl;
00506 #endif
00507 }
00508
00509 void RenderBox::calcHorizontalMargins(const Length& ml, const Length& mr, int cw)
00510 {
00511 if (isFloating())
00512 {
00513 m_marginLeft = ml.minWidth(cw);
00514 m_marginRight = mr.minWidth(cw);
00515 }
00516 else
00517 {
00518 if ( (ml.type == Variable && mr.type == Variable) ||
00519 (!(ml.type == Variable) &&
00520 containingBlock()->style()->textAlign() == KONQ_CENTER) )
00521 {
00522 m_marginLeft = (cw - m_width)/2;
00523 if (m_marginLeft<0) m_marginLeft=0;
00524 m_marginRight = cw - m_width - m_marginLeft;
00525 }
00526 else if (mr.type == Variable)
00527 {
00528 m_marginLeft = ml.width(cw);
00529 m_marginRight = cw - m_width - m_marginLeft;
00530 }
00531 else if (ml.type == Variable)
00532 {
00533 m_marginRight = mr.width(cw);
00534 m_marginLeft = cw - m_width - m_marginRight;
00535 }
00536 else
00537 {
00538 m_marginLeft = ml.minWidth(cw);
00539 m_marginRight = mr.minWidth(cw);
00540 }
00541 }
00542 }
00543
00544 void RenderBox::calcHeight()
00545 {
00546
00547 #ifdef DEBUG_LAYOUT
00548 kdDebug( 6040 ) << "RenderBox::calcHeight()" << endl;
00549 #endif
00550
00551
00552 if ( isTableCell() || (isInline() && !isReplaced()) )
00553 return;
00554
00555 if (isPositioned())
00556 calcAbsoluteVertical();
00557 else
00558 {
00559 Length h;
00560 if ( isReplaced() && !isFlow() )
00561 h = Length( calcReplacedHeight(), Fixed );
00562 else
00563 h = style()->height();
00564
00565 calcVerticalMargins();
00566
00567
00568 if (isTable())
00569 return;
00570
00571 if (!h.isVariable())
00572 {
00573 int fh=-1;
00574 if (h.isFixed())
00575 fh = h.value + borderTop() + paddingTop() + borderBottom() + paddingBottom();
00576 else if (h.isPercent()) {
00577 Length ch = containingBlock()->style()->height();
00578 if (ch.isFixed())
00579 fh = h.width(ch.value) + borderTop() + paddingTop() + borderBottom() + paddingBottom();
00580 }
00581 if (fh!=-1)
00582 {
00583 if (fh<m_height && !overhangingContents() && style()->overflow()==OVISIBLE)
00584 setOverhangingContents();
00585
00586 m_height = fh;
00587 }
00588 }
00589 }
00590 }
00591
00592 short RenderBox::calcReplacedWidth() const
00593 {
00594 Length w = style()->width();
00595
00596 switch( w.type ) {
00597 case Fixed:
00598 return w.value;
00599 case Percent:
00600 {
00601 const int cw = containingBlockWidth();
00602 if (cw > 0)
00603 return w.minWidth(cw);
00604 }
00605
00606 default:
00607 return intrinsicWidth();
00608 }
00609 }
00610
00611 int RenderBox::calcReplacedHeight() const
00612 {
00613 const Length& h = style()->height();
00614 switch( h.type ) {
00615 case Percent:
00616 return availableHeight();
00617 case Fixed:
00618 return h.value;
00619 default:
00620 return intrinsicHeight();
00621 };
00622 }
00623
00624 int RenderBox::availableHeight() const
00625 {
00626 Length h = style()->height();
00627
00628 if (h.isFixed())
00629 return h.value;
00630
00631 if (isRoot())
00632 return static_cast<const RenderRoot*>(this)->viewportHeight();
00633
00634 if (h.isPercent())
00635 return h.width(containingBlock()->availableHeight());
00636
00637 return containingBlock()->availableHeight();
00638 }
00639
00640 void RenderBox::calcVerticalMargins()
00641 {
00642 if( isTableCell() ) {
00643
00644 m_marginTop = TABLECELLMARGIN;
00645 m_marginBottom = TABLECELLMARGIN;
00646 return;
00647 }
00648
00649 Length tm = style()->marginTop();
00650 Length bm = style()->marginBottom();
00651
00652
00653
00654 int cw = containingBlock()->contentWidth();
00655
00656 m_marginTop = tm.minWidth(cw);
00657 m_marginBottom = bm.minWidth(cw);
00658 }
00659
00660 void RenderBox::calcAbsoluteHorizontal()
00661 {
00662 const int AUTO = -666666;
00663 int l,r,w,ml,mr,cw;
00664
00665 RenderObject* cb = containingBlock();
00666 int pab = borderLeft()+ borderRight()+ paddingLeft()+ paddingRight();
00667
00668 l=r=ml=mr=w=AUTO;
00669 cw = containingBlock()->width();
00670
00671 if(!style()->left().isVariable())
00672 l = style()->left().width(cw) + cb->borderLeft();
00673 if(!style()->right().isVariable())
00674 r = style()->right().width(cw) + cb->borderRight();
00675 if(!style()->width().isVariable())
00676 w = style()->width().width(cw);
00677 else if (isReplaced())
00678 w = intrinsicWidth();
00679 if(!style()->marginLeft().isVariable())
00680 ml = style()->marginLeft().width(cw);
00681 if(!style()->marginRight().isVariable())
00682 mr = style()->marginRight().width(cw);
00683
00684
00685
00686
00687 int static_distance=0;
00688 if ((style()->direction()==LTR && (l==AUTO && r==AUTO ))
00689 || style()->left().isStatic())
00690 {
00691
00692
00693
00694
00695
00696
00697
00698 for (RenderObject* po = parent(); po && po != cb; po = po->parent())
00699 static_distance += po->xPos();
00700
00701 static_distance += parent()->paddingLeft() + parent()->borderLeft();
00702
00703 if (l==AUTO || style()->left().isStatic())
00704 l = static_distance;
00705 }
00706
00707 else if ((style()->direction()==RTL && (l==AUTO && r==AUTO ))
00708 || style()->right().isStatic())
00709 {
00710 static_distance = cw - parent()->width();
00711
00712 for (RenderObject* po = parent(); po && po != cb; po = po->parent())
00713 static_distance -= po->xPos();
00714
00715 static_distance -= parent()->paddingRight() + parent()->borderRight();
00716 if (r==AUTO || style()->right().isStatic())
00717 r = static_distance;
00718 }
00719
00720
00721 if (l!=AUTO && w!=AUTO && r!=AUTO)
00722 {
00723
00724 int ot = l + w + r + pab;
00725
00726 if (ml==AUTO && mr==AUTO)
00727 {
00728
00729 ml = (cw - ot)/2;
00730 mr = cw - ot - ml;
00731 }
00732 else if (ml==AUTO)
00733
00734 ml = cw - ot - mr;
00735 else if (mr==AUTO)
00736
00737 mr = cw - ot - ml;
00738 else
00739 {
00740
00741 if (style()->direction()==LTR)
00742 r = cw - ( l + w + ml + mr + pab);
00743 else
00744 l = cw - ( r + w + ml + mr + pab);
00745 }
00746 }
00747 else
00748 {
00749
00750
00751
00752 if (ml==AUTO) ml = 0;
00753 if (mr==AUTO) mr = 0;
00754
00755
00756 if (l==AUTO && w==AUTO && r!=AUTO) {
00757 w = kMin( int ( m_maxWidth ), kMax(cw - ( r + ml + mr + pab), int ( m_minWidth ) ));
00758 l = cw - ( r + w + ml + mr + pab);
00759 }
00760 else
00761
00762 if (l==AUTO && w!=AUTO && r==AUTO) {
00763 if (style()->direction()==RTL) {
00764 r = static_distance;
00765 l = cw - ( r + w + ml + mr + pab);
00766 }
00767 else {
00768 l = static_distance;
00769 r = cw - ( l + w + ml + mr + pab);
00770 }
00771 }
00772 else
00773
00774 if (l!=AUTO && w==AUTO && r==AUTO) {
00775 w = kMin(int ( m_maxWidth ), kMax( int ( m_minWidth ), cw - ( l + ml + mr + pab)));
00776 r = cw - ( l + w + ml + mr + pab);
00777 }
00778 else
00779
00780
00781 if (l==AUTO && w!=AUTO && r!=AUTO)
00782 l = cw - ( r + w + ml + mr + pab);
00783 else
00784
00785
00786 if (l!=AUTO && w==AUTO && r!=AUTO)
00787 w = cw - ( r + l + ml + mr + pab);
00788 else
00789
00790
00791 if (l!=AUTO && w!=AUTO && r==AUTO)
00792 r = cw - ( l + w + ml + mr + pab);
00793 }
00794
00795 m_width = w + pab;
00796 m_marginLeft = ml;
00797 m_marginRight = mr;
00798 m_x = l + ml;
00799
00800
00801 }
00802
00803
00804 void RenderBox::calcAbsoluteVertical()
00805 {
00806
00807
00808
00809
00810
00811
00812
00813 const int AUTO = -666666;
00814 int t,b,h,mt,mb,ch;
00815
00816 t=b=h=mt=mb=AUTO;
00817
00818 int pab = borderTop()+borderBottom()+paddingTop()+paddingBottom();
00819 RenderObject* cb = containingBlock();
00820
00821 Length hl = cb->style()->height();
00822 if (hl.isFixed())
00823 ch = hl.value + cb->paddingTop() + cb->paddingBottom()
00824 + cb->borderTop() + cb->borderBottom();
00825 else if (cb->isHtml())
00826 ch = cb->availableHeight();
00827 else
00828 ch = cb->height();
00829
00830 if(!style()->top().isVariable())
00831 t = style()->top().width(ch) + cb->borderTop();
00832 if(!style()->bottom().isVariable())
00833 b = style()->bottom().width(ch) + cb->borderBottom();
00834 if(!style()->height().isVariable())
00835 {
00836 h = style()->height().width(ch);
00837 if (m_height-pab>h)
00838 h=m_height-pab;
00839 }
00840 else if (isReplaced())
00841 h = intrinsicHeight();
00842
00843 if(!style()->marginTop().isVariable())
00844 mt = style()->marginTop().width(ch);
00845 if(!style()->marginBottom().isVariable())
00846 mb = style()->marginBottom().width(ch);
00847
00848 int static_top=0;
00849 if ((t==AUTO && b==AUTO ) || style()->top().isStatic())
00850 {
00851
00852
00853
00854
00855
00856 RenderObject* ro = previousSibling();
00857 while ( ro && ro->isPositioned())
00858 ro = ro->previousSibling();
00859
00860 if (ro)
00861 static_top = ro->yPos()+ro->marginBottom()+ro->height();
00862 else {
00863
00864
00865 for (RenderObject* po = parent(); po && po != cb; po = po->parent())
00866 static_top += po->yPos();
00867
00868 static_top += parent()->paddingTop() + parent()->borderTop();
00869 }
00870
00871 if (h==AUTO || style()->top().isStatic())
00872 t = static_top;
00873 }
00874
00875 if (t!=AUTO && h!=AUTO && b!=AUTO)
00876 {
00877
00878 int ot = h + t + b + pab;
00879
00880 if (mt==AUTO && mb==AUTO)
00881 {
00882
00883 mt = (ch - ot)/2;
00884 mb = ch - ot - mt;
00885 }
00886 else if (mt==AUTO)
00887
00888 mt = ch - ot - mb;
00889 else if (mb==AUTO)
00890
00891 mb = ch - ot - mt;
00892 else
00893
00894 b = ch - ( h+t+mt+mb+pab);
00895 }
00896 else
00897 {
00898
00899
00900
00901 if (mt==AUTO) mt = 0;
00902 if (mb==AUTO) mb = 0;
00903
00904
00905 if (t==AUTO && h==AUTO && b!=AUTO)
00906 {
00907 h = m_height-pab;
00908 t = ch - ( h+b+mt+mb+pab);
00909 }
00910 else
00911
00912
00913 if (t==AUTO && h!=AUTO && b==AUTO)
00914 {
00915 t = static_top;
00916 b = ch - ( h+t+mt+mb+pab);
00917 }
00918 else
00919
00920
00921 if (t!=AUTO && h==AUTO && b==AUTO)
00922 {
00923 h = m_height-pab;
00924 b = ch - ( h+t+mt+mb+pab);
00925 }
00926 else
00927
00928
00929 if (t==AUTO && h!=AUTO && b!=AUTO)
00930 t = ch - ( h+b+mt+mb+pab);
00931 else
00932
00933
00934 if (t!=AUTO && h==AUTO && b!=AUTO)
00935 h = ch - ( t+b+mt+mb+pab);
00936 else
00937
00938
00939 if (t!=AUTO && h!=AUTO && b==AUTO)
00940 b = ch - ( h+t+mt+mb+pab);
00941 }
00942
00943
00944 if (m_height<h+pab)
00945 m_height = h+pab;
00946
00947 m_marginTop = mt;
00948 m_marginBottom = mb;
00949 m_y = t + mt;
00950
00951
00952
00953 }
00954
00955
00956 int RenderBox::lowestPosition() const
00957 {
00958 return m_height + marginBottom();
00959 }
00960
00961 int RenderBox::rightmostPosition() const
00962 {
00963 return m_width;
00964 }
00965
00966 #undef DEBUG_LAYOUT