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