00001
00021 #include "rendering/render_root.h"
00022
00023
00024 #include "khtmlview.h"
00025 #include <kdebug.h>
00026
00027 using namespace khtml;
00028
00029
00030
00031
00032 RenderRoot::RenderRoot(DOM::NodeImpl* node, KHTMLView *view)
00033 : RenderFlow(node)
00034 {
00035
00036 setInline(false);
00037
00038 m_view = view;
00039
00040
00041 m_minWidth = 0;
00042 m_height = 0;
00043
00044 m_width = m_minWidth;
00045 m_maxWidth = m_minWidth;
00046
00047 m_rootWidth = m_rootHeight = 0;
00048 m_viewportWidth = m_viewportHeight = 0;
00049
00050 setPositioned(true);
00051
00052 m_printingMode = false;
00053 m_paintImages = true;
00054
00055 m_selectionStart = 0;
00056 m_selectionEnd = 0;
00057 m_selectionStartPos = -1;
00058 m_selectionEndPos = -1;
00059 }
00060
00061 RenderRoot::~RenderRoot()
00062 {
00063 }
00064
00065 void RenderRoot::calcWidth()
00066 {
00067 RenderBox::calcWidth();
00068 return;
00069
00070
00071
00072 if (style()->marginLeft().type==Fixed)
00073 m_marginLeft = style()->marginLeft().value;
00074 else
00075 m_marginLeft = 0;
00076
00077 if (style()->marginRight().type==Fixed)
00078 m_marginRight = style()->marginRight().value;
00079 else
00080 m_marginRight = 0;
00081 }
00082
00083 void RenderRoot::calcMinMaxWidth()
00084 {
00085 KHTMLAssert( !minMaxKnown() );
00086
00087 RenderFlow::calcMinMaxWidth();
00088
00089 m_maxWidth = m_minWidth;
00090
00091 setMinMaxKnown();
00092 }
00093
00094
00095
00096 void RenderRoot::layout()
00097 {
00098 if (m_printingMode)
00099 m_minWidth = m_width;
00100
00101 if(firstChild())
00102 firstChild()->setLayouted(false);
00103
00104 #ifdef SPEED_DEBUG
00105 QTime qt;
00106 qt.start();
00107 #endif
00108 if ( recalcMinMax() )
00109 recalcMinMaxWidths();
00110 #ifdef SPEED_DEBUG
00111 kdDebug() << "RenderRoot::calcMinMax time used=" << qt.elapsed() << endl;
00112 qt.start();
00113 #endif
00114
00115 #ifdef SPEED_DEBUG
00116 kdDebug() << "RenderRoot::layout time used=" << qt.elapsed() << endl;
00117 qt.start();
00118 #endif
00119 if (!m_printingMode) {
00120 QSize s = m_view->viewportSize(m_view->contentsWidth(),
00121 m_view->contentsHeight());
00122 m_width = s.width();
00123 m_height = s.height();
00124 }
00125 else {
00126 m_width = m_rootWidth;
00127 m_height = m_rootHeight;
00128 }
00129
00130 RenderFlow::layout();
00131
00132 if (!m_printingMode) {
00133 m_view->resizeContents(docWidth(), docHeight());
00134 QSize s = m_view->viewportSize(m_view->contentsWidth(),
00135 m_view->contentsHeight());
00136 setWidth( m_viewportWidth = s.width() );
00137 setHeight( m_viewportHeight = s.height() );
00138 }
00139
00140
00141
00142 layoutSpecialObjects( true );
00143
00144 #ifdef SPEED_DEBUG
00145 kdDebug() << "RenderRoot::end time used=" << qt.elapsed() << endl;
00146 #endif
00147
00148 setLayouted();
00149 }
00150
00151 bool RenderRoot::absolutePosition(int &xPos, int &yPos, bool f)
00152 {
00153 if ( f && m_view) {
00154 xPos = m_view->contentsX();
00155 yPos = m_view->contentsY();
00156 }
00157 else {
00158 xPos = yPos = 0;
00159 }
00160 return true;
00161 }
00162
00163 void RenderRoot::paint(QPainter *p, int _x, int _y, int _w, int _h, int _tx, int _ty)
00164 {
00165 paintObject(p, _x, _y, _w, _h, _tx, _ty);
00166 }
00167
00168 void RenderRoot::paintObject(QPainter *p, int _x, int _y,
00169 int _w, int _h, int _tx, int _ty)
00170 {
00171 #ifdef DEBUG_LAYOUT
00172 kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;
00173 #endif
00174
00175 if(isRelPositioned())
00176 relativePositionOffset(_tx, _ty);
00177
00178
00179 if(hasSpecialObjects() && !isInline())
00180 paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
00181
00182
00183 RenderObject *child = firstChild();
00184 while(child != 0) {
00185 if(!child->isFloating() && !child->isPositioned()) {
00186 child->paint(p, _x, _y, _w, _h, _tx, _ty);
00187 }
00188 child = child->nextSibling();
00189 }
00190
00191
00192
00193
00194 if (m_view)
00195 {
00196 _tx += m_view->contentsX();
00197 _ty += m_view->contentsY();
00198 }
00199
00200 if(specialObjects)
00201 paintSpecialObjects(p, _x, _y, _w, _h, _tx, _ty);
00202
00203 #ifdef BOX_DEBUG
00204 outlineBox(p, _tx, _ty);
00205 #endif
00206
00207 }
00208
00209
00210 void RenderRoot::repaintRectangle(int x, int y, int w, int h, bool f)
00211 {
00212 if (m_printingMode) return;
00213
00214
00215 if ( f && m_view ) {
00216 x += m_view->contentsX();
00217 y += m_view->contentsY();
00218 }
00219
00220 QRect vr = viewRect();
00221 QRect ur(x, y, w, h);
00222
00223 if (ur.intersects(vr))
00224 if (m_view) m_view->scheduleRepaint(x, y, w, h);
00225 }
00226
00227 void RenderRoot::repaint()
00228 {
00229 if (m_view && !m_printingMode)
00230 m_view->scheduleRepaint(m_view->contentsX(), m_view->contentsY(),
00231 m_view->visibleWidth(), m_view->visibleHeight());
00232 }
00233
00234 void RenderRoot::close()
00235 {
00236 setLayouted( false );
00237 if (m_view) {
00238 m_view->layout();
00239 }
00240
00241 }
00242
00243 void RenderRoot::setSelection(RenderObject *s, int sp, RenderObject *e, int ep)
00244 {
00245
00246 if ( !s || !e )
00247 {
00248 kdWarning(6040) << "RenderRoot::setSelection() called with start=" << s << " end=" << e << endl;
00249 return;
00250 }
00251
00252
00253 clearSelection();
00254
00255 while (s->firstChild())
00256 s = s->firstChild();
00257 while (e->lastChild())
00258 e = e->lastChild();
00259
00260
00261 if (m_selectionStart)
00262 m_selectionStart->setIsSelectionBorder(false);
00263 m_selectionStart = s;
00264 if (m_selectionStart)
00265 m_selectionStart->setIsSelectionBorder(true);
00266 m_selectionStartPos = sp;
00267
00268
00269 if (m_selectionEnd)
00270 m_selectionEnd->setIsSelectionBorder(false);
00271 m_selectionEnd = e;
00272 if (m_selectionEnd)
00273 m_selectionEnd->setIsSelectionBorder(true);
00274 m_selectionEndPos = ep;
00275
00276
00277 RenderObject* o = s;
00278 while (o && o!=e)
00279 {
00280 o->setSelectionState(SelectionInside);
00281
00282 RenderObject* no;
00283 if ( !(no = o->firstChild()) )
00284 if ( !(no = o->nextSibling()) )
00285 {
00286 no = o->parent();
00287 while (no && !no->nextSibling())
00288 no = no->parent();
00289 if (no)
00290 no = no->nextSibling();
00291 }
00292 o=no;
00293 }
00294 s->setSelectionState(SelectionStart);
00295 e->setSelectionState(SelectionEnd);
00296 if(s == e) s->setSelectionState(SelectionBoth);
00297 repaint();
00298 }
00299
00300
00301 void RenderRoot::clearSelection()
00302 {
00303
00304 RenderObject* o = m_selectionStart;
00305 while (o && o!=m_selectionEnd)
00306 {
00307 if (o->selectionState()!=SelectionNone)
00308 o->repaint();
00309 o->setSelectionState(SelectionNone);
00310 RenderObject* no;
00311 if ( !(no = o->firstChild()) )
00312 if ( !(no = o->nextSibling()) )
00313 {
00314 no = o->parent();
00315 while (no && !no->nextSibling())
00316 no = no->parent();
00317 if (no)
00318 no = no->nextSibling();
00319 }
00320 o=no;
00321 }
00322 if (m_selectionEnd)
00323 {
00324 m_selectionEnd->setSelectionState(SelectionNone);
00325 m_selectionEnd->repaint();
00326 }
00327
00328
00329 if (m_selectionStart)
00330 m_selectionStart->setIsSelectionBorder(false);
00331 m_selectionStart = 0;
00332 m_selectionStartPos = -1;
00333
00334 if (m_selectionEnd)
00335 m_selectionEnd->setIsSelectionBorder(false);
00336 m_selectionEnd = 0;
00337 m_selectionEndPos = -1;
00338 }
00339
00340 void RenderRoot::selectionStartEnd(int& spos, int& epos)
00341 {
00342 spos = m_selectionStartPos;
00343 epos = m_selectionEndPos;
00344 }
00345
00346 QRect RenderRoot::viewRect() const
00347 {
00348 if (m_printingMode)
00349 return QRect(0,0, m_width, m_height);
00350 else if (m_view)
00351 return QRect(m_view->contentsX(),
00352 m_view->contentsY(),
00353 m_view->visibleWidth(),
00354 m_view->visibleHeight());
00355 else return QRect(0,0,m_rootWidth,m_rootHeight);
00356 }
00357
00358 int RenderRoot::docHeight() const
00359 {
00360 int h;
00361 if (m_printingMode || !m_view)
00362 h = m_height;
00363 else
00364 h = 0;
00365
00366 RenderObject *fc = firstChild();
00367 if(fc) {
00368 int dh = fc->height() + fc->marginTop() + fc->marginBottom();
00369 int lowestPos = firstChild()->lowestPosition();
00370 if( lowestPos > dh )
00371 dh = lowestPos;
00372 if( dh > h )
00373 h = dh;
00374 }
00375 return h;
00376 }
00377
00378 int RenderRoot::docWidth() const
00379 {
00380 int w;
00381 if (m_printingMode || !m_view)
00382 w = m_width;
00383 else
00384 w = 0;
00385
00386 RenderObject *fc = firstChild();
00387 if(fc) {
00388 int dw = fc->width() + fc->marginLeft() + fc->marginRight();
00389 int rightmostPos = fc->rightmostPosition();
00390 if( rightmostPos > dw )
00391 dw = rightmostPos;
00392 if( dw > w )
00393 w = dw;
00394 }
00395 return w;
00396 }