render_root.cpp Source File (khtml Library)

| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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 }

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:34:39 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001