khtml Library API Documentation

render_root.cpp

00001 
00021 #include "rendering/render_root.h"
00022 
00023 
00024 #include "khtmlview.h"
00025 #include <kdebug.h>
00026 
00027 using namespace khtml;
00028 
00029 //#define BOX_DEBUG
00030 //#define SPEED_DEBUG
00031 
00032 RenderRoot::RenderRoot(DOM::NodeImpl* node, KHTMLView *view)
00033     : RenderFlow(node)
00034 {
00035     // init RenderObject attributes
00036     setInline(false);
00037 
00038     m_view = view;
00039     // try to contrain the width to the views width
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); // to 0,0 :)
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     // exception: m_width is already known and set in layout()
00071 
00072     if (style()->marginLeft().isFixed())
00073         m_marginLeft = style()->marginLeft().value();
00074     else
00075         m_marginLeft = 0;
00076 
00077     if (style()->marginRight().isFixed())
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 //#define SPEED_DEBUG
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                                        0);
00136         setWidth( m_viewportWidth = s.width() );
00137         setHeight(  m_viewportHeight = s.height() );
00138     }
00139 
00140 
00141     // ### we could maybe do the call below better and only pass true if the docsize changed.
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     // add offset for relative positioning
00175     if(isRelPositioned())
00176         relativePositionOffset(_tx, _ty);
00177 
00178     // 1. paint background, borders etc
00179     if(hasSpecialObjects() && !isInline())
00180         paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
00181 
00182     // 2. paint contents
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     // 3. paint floats and other non-flow objects.
00192     // we have to do that after the contents otherwise they would get obscured by background settings.
00193     // it is anyway undefined if regular text is above fixed objects or the other way round.
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 //    kdDebug( 6040 ) << "updating views contents (" << x << "/" << y << ") (" << w << "/" << h << ")" << endl;
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     //printTree();
00241 }
00242 
00243 void RenderRoot::setSelection(RenderObject *s, int sp, RenderObject *e, int ep)
00244 {
00245     // Check we got valid renderobjects. www.msnbc.com and clicking around, to find the case where this happened.
00246     if ( !s || !e )
00247     {
00248         kdWarning(6040) << "RenderRoot::setSelection() called with start=" << s << " end=" << e << endl;
00249         return;
00250     }
00251     //kdDebug( 6040 ) << "RenderRoot::setSelection(" << s << "," << sp << "," << e << "," << ep << ")" << endl;
00252 
00253     clearSelection();
00254 
00255     while (s->firstChild())
00256         s = s->firstChild();
00257     while (e->lastChild())
00258         e = e->lastChild();
00259 
00260     // set selection start
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     // set selection end
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     // update selection status of all objects between m_selectionStart and m_selectionEnd
00277     RenderObject* o = s;
00278     while (o && o!=e)
00279     {
00280         o->setSelectionState(SelectionInside);
00281 //      kdDebug( 6040 ) << "setting selected " << o << ", " << o->isText() << endl;
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     // update selection status of all objects between m_selectionStart and m_selectionEnd
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     // set selection start & end to 0
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 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:16:40 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001