[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

hyatt hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:58:08 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 925e9aabe420204f5d0b7e8bd740c2b99d30470a
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Sep 26 00:57:15 2003 +0000

    	Landing the new repainting code.  This code eliminates many redundant layouts, makes
    	layout scheduling work properly when called from WebKit, cleans up relpositioned inlines
    	that act as containing blocks for absolute positioned children, and eliminates the
    	repaint timer.
    
            Reviewed by kocienda
    
            * ChangeLog:
            * khtml/html/html_documentimpl.cpp:
            (HTMLDocumentImpl::close):
            * khtml/khtmlview.cpp:
            (KHTMLView::KHTMLView):
            * khtml/khtmlview.h:
            * khtml/rendering/render_block.cpp:
            * khtml/rendering/render_block.h:
            * khtml/rendering/render_box.cpp:
            (RenderBox::setStyle):
            (RenderBox::setPixmap):
            (RenderBox::getAbsoluteRepaintRect):
            (RenderBox::computeAbsoluteRepaintRect):
            (RenderBox::repaintIfMoved):
            (RenderBox::calcAbsoluteHorizontal):
            (RenderBox::calcAbsoluteVertical):
            * khtml/rendering/render_box.h:
            * khtml/rendering/render_canvas.cpp:
            (RenderCanvas::layout):
            (RenderCanvas::repaintViewRectangle):
            (RenderCanvas::getAbsoluteRepaintRect):
            (RenderCanvas::computeAbsoluteRepaintRect):
            * khtml/rendering/render_canvas.h:
            * khtml/rendering/render_container.cpp:
            (RenderContainer::addChild):
            (RenderContainer::removeChildNode):
            (RenderContainer::removeChild):
            (RenderContainer::appendChildNode):
            (RenderContainer::insertChildNode):
            * khtml/rendering/render_flexbox.cpp:
            * khtml/rendering/render_flow.cpp:
            (RenderFlow::getAbsoluteRepaintRect):
            * khtml/rendering/render_flow.h:
            * khtml/rendering/render_image.cpp:
            (RenderImage::setPixmap):
            (RenderImage::layout):
            * khtml/rendering/render_inline.cpp:
            (RenderInline::addChildToFlow):
            * khtml/rendering/render_layer.cpp:
            (RenderLayer::convertToLayerCoords):
            * khtml/rendering/render_list.cpp:
            (RenderListMarker::setPixmap):
            * khtml/rendering/render_object.cpp:
            (RenderObject::RenderObject):
            (RenderObject::setNeedsLayout):
            (RenderObject::setChildNeedsLayout):
            (RenderObject::markContainingBlocksForLayout):
            (RenderObject::containingBlock):
            (RenderObject::repaint):
            (RenderObject::repaintRectangle):
            (RenderObject::repaintAfterLayoutIfNeeded):
            (RenderObject::repaintIfMoved):
            (RenderObject::repaintPositionedAndFloatingDescendants):
            (RenderObject::getAbsoluteRepaintRect):
            (RenderObject::getAbsoluteRepaintRectIncludingDescendants):
            (RenderObject::computeAbsoluteRepaintRect):
            (RenderObject::setStyle):
            (RenderObject::container):
            (RenderObject::detach):
            (RenderObject::scheduleRelayout):
            * khtml/rendering/render_object.h:
            * khtml/rendering/render_style.cpp:
            (RenderStyle::diff):
            * khtml/rendering/render_table.cpp:
            (RenderTable::layout):
            (RenderTableRow::getAbsoluteRepaintRect):
            (RenderTableCell::computeAbsoluteRepaintRect):
            * khtml/rendering/render_table.h:
            * khtml/xml/dom_nodeimpl.cpp:
            (NodeBaseImpl::insertBefore):
            (NodeBaseImpl::replaceChild):
            (NodeBaseImpl::appendChild):
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::clearTimers):
            * kwq/KWQRenderTreeDebug.cpp:
            (write):
            (externalRepresentation):
            * kwq/KWQRenderTreeDebug.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5068 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 558324d..3029511 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,173 @@
+2003-09-25  David Hyatt  <hyatt at apple.com>
+
+	Landing the new repainting code.  This code eliminates many redundant layouts, makes
+	layout scheduling work properly when called from WebKit, cleans up relpositioned inlines
+	that act as containing blocks for absolute positioned children, and eliminates the
+	repaint timer.
+	
+        Reviewed by kocienda
+
+        * ChangeLog:
+        * khtml/html/html_documentimpl.cpp:
+        (HTMLDocumentImpl::close):
+        * khtml/khtmlview.cpp:
+        (KHTMLView::KHTMLView):
+        * khtml/khtmlview.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::setStyle):
+        (RenderBox::setPixmap):
+        (RenderBox::getAbsoluteRepaintRect):
+        (RenderBox::computeAbsoluteRepaintRect):
+        (RenderBox::repaintIfMoved):
+        (RenderBox::calcAbsoluteHorizontal):
+        (RenderBox::calcAbsoluteVertical):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_canvas.cpp:
+        (RenderCanvas::layout):
+        (RenderCanvas::repaintViewRectangle):
+        (RenderCanvas::getAbsoluteRepaintRect):
+        (RenderCanvas::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_canvas.h:
+        * khtml/rendering/render_container.cpp:
+        (RenderContainer::addChild):
+        (RenderContainer::removeChildNode):
+        (RenderContainer::removeChild):
+        (RenderContainer::appendChildNode):
+        (RenderContainer::insertChildNode):
+        * khtml/rendering/render_flexbox.cpp:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::getAbsoluteRepaintRect):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::setPixmap):
+        (RenderImage::layout):
+        * khtml/rendering/render_inline.cpp:
+        (RenderInline::addChildToFlow):
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::convertToLayerCoords):
+        * khtml/rendering/render_list.cpp:
+        (RenderListMarker::setPixmap):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::RenderObject):
+        (RenderObject::setNeedsLayout):
+        (RenderObject::setChildNeedsLayout):
+        (RenderObject::markContainingBlocksForLayout):
+        (RenderObject::containingBlock):
+        (RenderObject::repaint):
+        (RenderObject::repaintRectangle):
+        (RenderObject::repaintAfterLayoutIfNeeded):
+        (RenderObject::repaintIfMoved):
+        (RenderObject::repaintPositionedAndFloatingDescendants):
+        (RenderObject::getAbsoluteRepaintRect):
+        (RenderObject::getAbsoluteRepaintRectIncludingDescendants):
+        (RenderObject::computeAbsoluteRepaintRect):
+        (RenderObject::setStyle):
+        (RenderObject::container):
+        (RenderObject::detach):
+        (RenderObject::scheduleRelayout):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_style.cpp:
+        (RenderStyle::diff):
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::layout):
+        (RenderTableRow::getAbsoluteRepaintRect):
+        (RenderTableCell::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_table.h:
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeBaseImpl::insertBefore):
+        (NodeBaseImpl::replaceChild):
+        (NodeBaseImpl::appendChild):
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::clearTimers):
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write):
+        (externalRepresentation):
+        * kwq/KWQRenderTreeDebug.h:
+
+2003-09-25  David Hyatt  <hyatt at apple.com>
+
+        Reviewed by NOBODY (OOPS!).
+
+        * khtml/html/html_documentimpl.cpp:
+        (HTMLDocumentImpl::close):
+        * khtml/khtmlview.cpp:
+        (KHTMLView::KHTMLView):
+        * khtml/khtmlview.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::setStyle):
+        (RenderBox::setPixmap):
+        (RenderBox::getAbsoluteRepaintRect):
+        (RenderBox::computeAbsoluteRepaintRect):
+        (RenderBox::repaintIfMoved):
+        (RenderBox::calcAbsoluteHorizontal):
+        (RenderBox::calcAbsoluteVertical):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_canvas.cpp:
+        (RenderCanvas::layout):
+        (RenderCanvas::repaintViewRectangle):
+        (RenderCanvas::getAbsoluteRepaintRect):
+        (RenderCanvas::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_canvas.h:
+        * khtml/rendering/render_container.cpp:
+        (RenderContainer::addChild):
+        (RenderContainer::removeChildNode):
+        (RenderContainer::removeChild):
+        (RenderContainer::appendChildNode):
+        (RenderContainer::insertChildNode):
+        * khtml/rendering/render_flexbox.cpp:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::getAbsoluteRepaintRect):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::setPixmap):
+        (RenderImage::layout):
+        * khtml/rendering/render_inline.cpp:
+        (RenderInline::addChildToFlow):
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::convertToLayerCoords):
+        * khtml/rendering/render_list.cpp:
+        (RenderListMarker::setPixmap):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::RenderObject):
+        (RenderObject::setNeedsLayout):
+        (RenderObject::setChildNeedsLayout):
+        (RenderObject::markContainingBlocksForLayout):
+        (RenderObject::containingBlock):
+        (RenderObject::repaint):
+        (RenderObject::repaintRectangle):
+        (RenderObject::repaintAfterLayoutIfNeeded):
+        (RenderObject::repaintIfMoved):
+        (RenderObject::repaintPositionedAndFloatingDescendants):
+        (RenderObject::getAbsoluteRepaintRect):
+        (RenderObject::getAbsoluteRepaintRectIncludingDescendants):
+        (RenderObject::computeAbsoluteRepaintRect):
+        (RenderObject::setStyle):
+        (RenderObject::container):
+        (RenderObject::detach):
+        (RenderObject::scheduleRelayout):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_style.cpp:
+        (RenderStyle::diff):
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::layout):
+        (RenderTableRow::getAbsoluteRepaintRect):
+        (RenderTableCell::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_table.h:
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeBaseImpl::insertBefore):
+        (NodeBaseImpl::replaceChild):
+        (NodeBaseImpl::appendChild):
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::clearTimers):
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write):
+        (externalRepresentation):
+        * kwq/KWQRenderTreeDebug.h:
+
 2003-09-25  Maciej Stachowiak  <mjs at apple.com>
 
         Reviewed by Darin.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 558324d..3029511 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,173 @@
+2003-09-25  David Hyatt  <hyatt at apple.com>
+
+	Landing the new repainting code.  This code eliminates many redundant layouts, makes
+	layout scheduling work properly when called from WebKit, cleans up relpositioned inlines
+	that act as containing blocks for absolute positioned children, and eliminates the
+	repaint timer.
+	
+        Reviewed by kocienda
+
+        * ChangeLog:
+        * khtml/html/html_documentimpl.cpp:
+        (HTMLDocumentImpl::close):
+        * khtml/khtmlview.cpp:
+        (KHTMLView::KHTMLView):
+        * khtml/khtmlview.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::setStyle):
+        (RenderBox::setPixmap):
+        (RenderBox::getAbsoluteRepaintRect):
+        (RenderBox::computeAbsoluteRepaintRect):
+        (RenderBox::repaintIfMoved):
+        (RenderBox::calcAbsoluteHorizontal):
+        (RenderBox::calcAbsoluteVertical):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_canvas.cpp:
+        (RenderCanvas::layout):
+        (RenderCanvas::repaintViewRectangle):
+        (RenderCanvas::getAbsoluteRepaintRect):
+        (RenderCanvas::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_canvas.h:
+        * khtml/rendering/render_container.cpp:
+        (RenderContainer::addChild):
+        (RenderContainer::removeChildNode):
+        (RenderContainer::removeChild):
+        (RenderContainer::appendChildNode):
+        (RenderContainer::insertChildNode):
+        * khtml/rendering/render_flexbox.cpp:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::getAbsoluteRepaintRect):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::setPixmap):
+        (RenderImage::layout):
+        * khtml/rendering/render_inline.cpp:
+        (RenderInline::addChildToFlow):
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::convertToLayerCoords):
+        * khtml/rendering/render_list.cpp:
+        (RenderListMarker::setPixmap):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::RenderObject):
+        (RenderObject::setNeedsLayout):
+        (RenderObject::setChildNeedsLayout):
+        (RenderObject::markContainingBlocksForLayout):
+        (RenderObject::containingBlock):
+        (RenderObject::repaint):
+        (RenderObject::repaintRectangle):
+        (RenderObject::repaintAfterLayoutIfNeeded):
+        (RenderObject::repaintIfMoved):
+        (RenderObject::repaintPositionedAndFloatingDescendants):
+        (RenderObject::getAbsoluteRepaintRect):
+        (RenderObject::getAbsoluteRepaintRectIncludingDescendants):
+        (RenderObject::computeAbsoluteRepaintRect):
+        (RenderObject::setStyle):
+        (RenderObject::container):
+        (RenderObject::detach):
+        (RenderObject::scheduleRelayout):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_style.cpp:
+        (RenderStyle::diff):
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::layout):
+        (RenderTableRow::getAbsoluteRepaintRect):
+        (RenderTableCell::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_table.h:
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeBaseImpl::insertBefore):
+        (NodeBaseImpl::replaceChild):
+        (NodeBaseImpl::appendChild):
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::clearTimers):
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write):
+        (externalRepresentation):
+        * kwq/KWQRenderTreeDebug.h:
+
+2003-09-25  David Hyatt  <hyatt at apple.com>
+
+        Reviewed by NOBODY (OOPS!).
+
+        * khtml/html/html_documentimpl.cpp:
+        (HTMLDocumentImpl::close):
+        * khtml/khtmlview.cpp:
+        (KHTMLView::KHTMLView):
+        * khtml/khtmlview.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::setStyle):
+        (RenderBox::setPixmap):
+        (RenderBox::getAbsoluteRepaintRect):
+        (RenderBox::computeAbsoluteRepaintRect):
+        (RenderBox::repaintIfMoved):
+        (RenderBox::calcAbsoluteHorizontal):
+        (RenderBox::calcAbsoluteVertical):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_canvas.cpp:
+        (RenderCanvas::layout):
+        (RenderCanvas::repaintViewRectangle):
+        (RenderCanvas::getAbsoluteRepaintRect):
+        (RenderCanvas::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_canvas.h:
+        * khtml/rendering/render_container.cpp:
+        (RenderContainer::addChild):
+        (RenderContainer::removeChildNode):
+        (RenderContainer::removeChild):
+        (RenderContainer::appendChildNode):
+        (RenderContainer::insertChildNode):
+        * khtml/rendering/render_flexbox.cpp:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::getAbsoluteRepaintRect):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::setPixmap):
+        (RenderImage::layout):
+        * khtml/rendering/render_inline.cpp:
+        (RenderInline::addChildToFlow):
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::convertToLayerCoords):
+        * khtml/rendering/render_list.cpp:
+        (RenderListMarker::setPixmap):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::RenderObject):
+        (RenderObject::setNeedsLayout):
+        (RenderObject::setChildNeedsLayout):
+        (RenderObject::markContainingBlocksForLayout):
+        (RenderObject::containingBlock):
+        (RenderObject::repaint):
+        (RenderObject::repaintRectangle):
+        (RenderObject::repaintAfterLayoutIfNeeded):
+        (RenderObject::repaintIfMoved):
+        (RenderObject::repaintPositionedAndFloatingDescendants):
+        (RenderObject::getAbsoluteRepaintRect):
+        (RenderObject::getAbsoluteRepaintRectIncludingDescendants):
+        (RenderObject::computeAbsoluteRepaintRect):
+        (RenderObject::setStyle):
+        (RenderObject::container):
+        (RenderObject::detach):
+        (RenderObject::scheduleRelayout):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_style.cpp:
+        (RenderStyle::diff):
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::layout):
+        (RenderTableRow::getAbsoluteRepaintRect):
+        (RenderTableCell::computeAbsoluteRepaintRect):
+        * khtml/rendering/render_table.h:
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeBaseImpl::insertBefore):
+        (NodeBaseImpl::replaceChild):
+        (NodeBaseImpl::appendChild):
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::clearTimers):
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write):
+        (externalRepresentation):
+        * kwq/KWQRenderTreeDebug.h:
+
 2003-09-25  Maciej Stachowiak  <mjs at apple.com>
 
         Reviewed by Darin.
diff --git a/WebCore/khtml/html/html_documentimpl.cpp b/WebCore/khtml/html/html_documentimpl.cpp
index 9c213ef..4fc7ea9 100644
--- a/WebCore/khtml/html/html_documentimpl.cpp
+++ b/WebCore/khtml/html/html_documentimpl.cpp
@@ -346,11 +346,9 @@ void HTMLDocumentImpl::close()
     if (body() && doload) {
         updateRendering();
         
-        // Always do a layout/repaint after loading.
-        if (renderer()) {
-            renderer()->layoutIfNeeded();
-            renderer()->repaint();
-        }
+        // Always do a layout after loading if needed.
+        if (renderer() && renderer()->needsLayout())
+            view()->layout();
     }
 }
 
diff --git a/WebCore/khtml/khtmlview.cpp b/WebCore/khtml/khtmlview.cpp
index 0b8faa3..0003b55 100644
--- a/WebCore/khtml/khtmlview.cpp
+++ b/WebCore/khtml/khtmlview.cpp
@@ -96,8 +96,7 @@ public:
         paintBuffer=0;
         formCompletions=0;
         prevScrollbarVisible = true;
-	timerId = 0;
-        repaintTimerId = 0;
+	layoutTimerId = 0;
         complete = false;
         mousePressed = false;
 	tooltip = 0;
@@ -139,13 +138,10 @@ public:
 	clickCount = 0;
 	isDoubleClick = false;
 	scrollingSelf = false;
-	timerId = 0;
-        repaintTimerId = 0;
+	layoutTimerId = 0;
         complete = false;
         mousePressed = false;
-        firstRelayout = true;
         layoutSchedulingEnabled = true;
-        updateRect = QRect();
     }
 
     QPainter *tp;
@@ -174,14 +170,11 @@ public:
 
     int prevMouseX, prevMouseY;
     bool scrollingSelf;
-    int timerId;
+    int layoutTimerId;
 
-    int repaintTimerId;
     bool complete;
-    bool firstRelayout;
     bool layoutSchedulingEnabled;
     bool mousePressed;
-    QRect updateRect;
     KHTMLToolTip *tooltip;
 };
 
@@ -210,7 +203,9 @@ KHTMLView::KHTMLView( KHTMLPart *part, QWidget *parent, const char *name)
 {
     m_medium = "screen";
 
+#ifndef INCREMENTAL_REPAINTING
     m_layoutObject = 0;
+#endif
     
     m_part = part;
 #if APPLE_CHANGES
@@ -416,35 +411,61 @@ void KHTMLView::adjustViewSize()
 
 void KHTMLView::layout()
 {
+    d->layoutSchedulingEnabled=false;
+    khtml::RenderCanvas* root = 0;
     if( m_part->xmlDocImpl() ) {
         DOM::DocumentImpl *document = m_part->xmlDocImpl();
 
-        khtml::RenderCanvas* root = static_cast<khtml::RenderCanvas *>(document->renderer());
+        root = static_cast<khtml::RenderCanvas *>(document->renderer());
         if ( !root ) return;
 
-         if (document->isHTMLDocument()) {
+        if (document->isHTMLDocument()) {
              NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
              if(body && body->renderer() && body->id() == ID_FRAMESET) {
                  QScrollView::setVScrollBarMode(AlwaysOff);
                  QScrollView::setHScrollBarMode(AlwaysOff);
                  body->renderer()->setNeedsLayout(true);
              }
-         }
+        }
 
         _height = visibleHeight();
         _width = visibleWidth();
 
-        //QTime qt;
-        //qt.start();
-        root->setNeedsLayoutAndMinMaxRecalc();
-        // avoid recursing into relayouts because of scrollbar-flicker
-
         root->layout();
 
         //kdDebug( 6000 ) << "TIME: layout() dt=" << qt.elapsed() << endl;
     } else {
         _width = visibleWidth();
     }
+
+    d->layoutSchedulingEnabled=true;
+    killTimer(d->layoutTimerId);
+    d->layoutTimerId = 0;
+
+    if (!root)
+        return;
+    
+#ifdef INCREMENTAL_REPAINTING
+    if (root->needsLayout()) {
+#else
+    // Do not allow a full layout if we had a clip object set.
+    if ( root->needsLayout() && !m_layoutObject) {
+#endif
+        //qDebug("needs layout, delaying repaint");
+        scheduleRelayout();
+        return;
+    }
+    resizeContents(root->docWidth(), root->docHeight());
+    setStaticBackground(d->useSlowRepaints);
+
+#ifndef INCREMENTAL_REPAINTING
+    if (m_layoutObject) {
+        m_layoutObject->repaint();
+        m_layoutObject = 0;
+    }
+    else
+        root->repaint();
+#endif
 }
 
 //
@@ -1535,152 +1556,61 @@ void KHTMLView::slotScrollBarMoved()
         d->scrollBarMoved = true;
 }
 
+void KHTMLView::repaintRectangle(const QRect& r, bool immediate)
+{
+#ifndef INCREMENTAL_REPAINTING
+    if (d->layoutTimerId) // Don't bother scheduling a repaint when a layout is pending.
+        return;
+#endif
+
+    updateContents(r, immediate);
+}
+
 void KHTMLView::timerEvent ( QTimerEvent *e )
 {
 //    kdDebug() << "timer event " << e->timerId() << endl;
-    if (e->timerId()==d->timerId)
-    {
-        d->firstRelayout = false;
-        killTimer(d->timerId);
-
-        d->layoutSchedulingEnabled=false;
+    if (e->timerId()==d->layoutTimerId)
         layout();
-        d->layoutSchedulingEnabled=true;
-
-        d->timerId = 0;
-
-        //scheduleRepaint(contentsX(),contentsY(),visibleWidth(),visibleHeight());
-        d->updateRect = QRect(contentsX(),contentsY(),visibleWidth(),visibleHeight());
-    }
-
-    if( m_part && m_part->xmlDocImpl() ) {
-        DOM::DocumentImpl *document = m_part->xmlDocImpl();
-        khtml::RenderCanvas* root = static_cast<khtml::RenderCanvas *>(document->renderer());
-        if (root){
-            // Do not allow a full layout if we had a clip object set.
-            if ( root->needsLayout() && !m_layoutObject) {
-                killTimer(d->repaintTimerId);
-                d->repaintTimerId = 0;
-                //qDebug("needs layout, delaying repaint");
-                scheduleRelayout();
-                return;
-            }
-            resizeContents(root->docWidth(), root->docHeight());
-        }
-    }
-    setStaticBackground(d->useSlowRepaints);
-
-//        kdDebug() << "scheduled repaint "<< d->repaintTimerId  << endl;
-    // If we have an overflow:hidden object, we cache the current update rect and then
-    // clear the update rect, so that when we call repaint(), the union of the layout
-    // object's rect and the current update rect is just the layout object's' rect.
-    QRect oldUpdateRect = d->updateRect;
-    bool hasRepaintTimer = d->repaintTimerId;
-    if (m_layoutObject) {
-        d->updateRect = QRect();
-        m_layoutObject->repaint();
-    }
-    
-    // Now we paint.  This will be either a full paint or just the paint of a clipped
-    // object's area.
-    updateContents( d->updateRect );
-    killTimer(d->repaintTimerId);
-    d->repaintTimerId = 0;
-
-    if (m_layoutObject) {
-        // Restore the update rect, and if we had a repaint pending before the clipped
-        // object did its paint, go ahead and reschedule that paint to occur as soon
-        // as possible.
-        d->updateRect = oldUpdateRect;
-        if (hasRepaintTimer)
-            scheduleRepaint(d->updateRect.x(), d->updateRect.y(), d->updateRect.width(),
-                            d->updateRect.height());
-        m_layoutObject = 0;
-    }
 }
 
+#ifdef INCREMENTAL_REPAINTING
+void KHTMLView::scheduleRelayout()
+#else
 void KHTMLView::scheduleRelayout(khtml::RenderObject* clippedObj)
+#endif
 {
     if (!d->layoutSchedulingEnabled)
         return;
-        
+
+#ifndef INCREMENTAL_REPAINTING
     if (m_layoutObject != clippedObj)
-        m_layoutObject = 0;
+      m_layoutObject = 0;
+#endif
     
-    if (d->timerId)
+    if (d->layoutTimerId)
         return;
 
+#ifndef INCREMENTAL_REPAINTING
     m_layoutObject = clippedObj;
-    
+#endif
+
     bool parsing = false;
     if( m_part->xmlDocImpl() ) {
         parsing = m_part->xmlDocImpl()->parsing();
     }
 
-    d->timerId = startTimer( parsing ? 1000 : 0 );
+    d->layoutTimerId = startTimer( parsing ? 1000 : 0 );
 }
 
 void KHTMLView::unscheduleRelayout()
 {
-    if (!d->timerId)
+    if (!d->layoutTimerId)
         return;
 
-    killTimer(d->timerId);
-    d->timerId = 0;
+    killTimer(d->layoutTimerId);
+    d->layoutTimerId = 0;
 }
 
-void KHTMLView::unscheduleRepaint()
-{
-    if (!d->repaintTimerId)
-        return;
-
-    killTimer(d->repaintTimerId);
-    d->repaintTimerId = 0;
-}
-
-void KHTMLView::scheduleRepaint(int x, int y, int w, int h)
-{
-
-    //kdDebug() << "scheduleRepaint(" << x << "," << y << "," << w << "," << h << ")" << endl;
-
-
-    bool parsing = false;
-    if( m_part->xmlDocImpl() ) {
-        parsing = m_part->xmlDocImpl()->parsing();
-    }
-
-//     kdDebug() << "parsing " << parsing << endl;
-//     kdDebug() << "complete " << d->complete << endl;
-
-    int time;
-
-    // if complete...
-    if (d->complete)
-        // ...repaint immediatly
-        time = 0;
-    else
-    {
-        if (parsing)
-            // not complete and still parsing
-            time = 300;
-        else
-            // not complete, not parsing, extend the timer if it exists
-            // otherwise, repaint immediatly
-            time = d->repaintTimerId ? 400 : 0;
-    }
-
-    if (d->repaintTimerId) {
-        killTimer(d->repaintTimerId);
-        d->updateRect = d->updateRect.unite(QRect(x,y,w,h));
-    } else
-        d->updateRect = QRect(x,y,w,h);
-
-    d->repaintTimerId = startTimer( time );
-
-//     kdDebug() << "starting timer " << time << endl;
-}
-
-
 void KHTMLView::complete()
 {
 //     kdDebug() << "KHTMLView::complete()" << endl;
@@ -1688,20 +1618,11 @@ void KHTMLView::complete()
     d->complete = true;
 
     // is there a relayout pending?
-    if (d->timerId)
+    if (d->layoutTimerId)
     {
 //         kdDebug() << "requesting relayout now" << endl;
         // do it now
-        killTimer(d->timerId);
-        d->timerId = startTimer( 0 );
-    }
-
-    // is there a repaint pending?
-    if (d->repaintTimerId)
-    {
-//         kdDebug() << "requesting repaint now" << endl;
-        // do it now
-        killTimer(d->repaintTimerId);
-        d->repaintTimerId = startTimer( 1 );
+        killTimer(d->layoutTimerId);
+        d->layoutTimerId = startTimer( 0 );
     }
 }
diff --git a/WebCore/khtml/khtmlview.h b/WebCore/khtml/khtmlview.h
index a05d79e..12c827b 100644
--- a/WebCore/khtml/khtmlview.h
+++ b/WebCore/khtml/khtmlview.h
@@ -187,6 +187,8 @@ public:
 
     void timerEvent ( QTimerEvent * );
 
+    void repaintRectangle(const QRect& r, bool immediate);
+    
 #if APPLE_CHANGES
     QWidget *topLevelWidget() const;
     QPoint mapToGlobal(const QPoint &) const;
@@ -204,12 +206,13 @@ private:
 
     void resetCursor();
 
+#ifdef INCREMENTAL_REPAINTING
+    void scheduleRelayout();
+#else
     void scheduleRelayout(khtml::RenderObject* clippedObj=0);
+#endif
     void unscheduleRelayout();
 
-    void scheduleRepaint(int x, int y, int w, int h);
-    void unscheduleRepaint();
-    
     /**
      * Paints the HTML document to a QPainter.
      * The document will be scaled to match the width of
@@ -256,9 +259,11 @@ private:
 
     void complete();
 
+#ifndef INCREMENTAL_REPAINTING
     // Returns the clipped object we will repaint when we perform our scheduled layout.
     khtml::RenderObject* layoutObject() { return m_layoutObject; }
-
+#endif
+    
     // ------------------------------------- member variables ------------------------------------
  private:
     unsigned _refCount;
@@ -273,10 +278,12 @@ private:
     KHTMLViewPrivate *d;
 
     QString m_medium;   // media type
-    
+
+#ifndef INCREMENTAL_REPAINTING
     // An overflow: hidden clipped object.  If this is set, a scheduled layout will only repaint
     // the object's clipped area, and it will not do a full repaint.
     khtml::RenderObject* m_layoutObject;
+#endif
 };
 
 #endif
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index bb97360..55b4589 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -100,8 +100,6 @@ void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChi
     if (!beforeChild && lastChild() && lastChild()->style()->styleType() == RenderStyle::AFTER)
         beforeChild = lastChild();
     
-    setNeedsLayout(true);
-
     bool madeBoxesNonInline = FALSE;
 
     RenderStyle* pseudoStyle=0;
@@ -311,10 +309,7 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
         box->appendChildNode(removeChildNode(inlineRunEnd));
         box->close();
         box->setPos(box->xPos(), -500000);
-        box->setNeedsLayout(true);
     }
-
-    setNeedsLayout(true);
 }
 
 void RenderBlock::removeChild(RenderObject *oldChild)
@@ -360,7 +355,6 @@ void RenderBlock::removeChild(RenderObject *oldChild)
             appendChildNode(anonBlock->removeChildNode(no));
             no->setNeedsLayoutAndMinMaxRecalc();
         }
-        setNeedsLayoutAndMinMaxRecalc();
         
         // Nuke the now-empty block.
         anonBlock->detach(renderArena());
@@ -415,12 +409,28 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
     //     t.start();
     KHTMLAssert( needsLayout() );
     KHTMLAssert( minMaxKnown() );
-    
+
     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
         return;	    		                     // cause us to come in here.  Just bail. -dwh
 
-    int oldWidth = m_width;
+    if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {
+        // All we have to is lay out our positioned objects.
+        layoutPositionedObjects(relayoutChildren);
+        setNeedsLayout(false);
+        return;
+    }
+
+#ifdef INCREMENTAL_REPAINTING
+    // FIXME: For now, if we have dirty inline children, we just always repaint.
+    if (normalChildNeedsLayout() && childrenInline())
+        repaint();
+    
+    QRect oldBounds, oldFullBounds;
+    getAbsoluteRepaintRectIncludingDescendants(oldBounds, oldFullBounds);
+#endif
 
+    int oldWidth = m_width;
+    
     calcWidth();
     m_overflowWidth = m_width;
 
@@ -524,14 +534,22 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
 
     //kdDebug() << renderName() << " layout width=" << m_width << " height=" << m_height << endl;
 
-    // Always ensure our overflow width is at least as large as our width.
+    // Always ensure our overflow width/height are at least as large as our width/height.
     if (m_overflowWidth < m_width)
         m_overflowWidth = m_width;
-
+    if (m_overflowHeight < m_height)
+        m_overflowHeight = m_height;
+    
     // Update our scrollbars if we're overflow:auto/scroll now that we know if
     // we overflow or not.
     if (style()->scrollsOverflow() && m_layer)
         m_layer->checkScrollbarsAfterLayout();
+
+#ifdef INCREMENTAL_REPAINTING
+    // Repaint with our new bounds if they are different from our old bounds.
+    if (!isCanvas())
+        repaintAfterLayoutIfNeeded(oldBounds, oldFullBounds);
+#endif
     
     setNeedsLayout(false);
 }
@@ -638,7 +656,7 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
         if (relayoutChildren || floatBottom() > m_y ||
             (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) ||
             (child->isRenderBlock() && child->style()->height().isPercent()))
-            child->setNeedsLayout(true);
+            child->setChildNeedsLayout(true);
 
         //         kdDebug( 6040 ) << "   " << child->renderName() << " loop " << child << ", " << child->isInline() << ", " << child->needsLayout() << endl;
         //         kdDebug( 6040 ) << t.elapsed() << endl;
@@ -774,12 +792,17 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
 
         // take care in case we inherited floats
         if (child && floatBottom() > m_height)
-            child->setNeedsLayout(true);
+            child->setChildNeedsLayout(true);
         
         child->calcVerticalMargins();
 
         //kdDebug(0) << "margin = " << margin << " yPos = " << m_height << endl;
 
+#ifdef INCREMENTAL_REPAINTING
+        int oldChildX = child->xPos();
+        int oldChildY = child->yPos();
+#endif
+        
         // Try to guess our correct y position.  In most cases this guess will
         // be correct.  Only if we're wrong (when we compute the real y position)
         // will we have to relayout.
@@ -788,7 +811,7 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
         {
             yPosEstimate += QMAX(prevFlow->collapsedMarginBottom(), child->marginTop());
             if (prevFlow->yPos()+prevFlow->floatBottom() > yPosEstimate)
-                child->setNeedsLayout(true);
+                child->setChildNeedsLayout(true);
             else
                 prevFlow=0;
         }
@@ -910,7 +933,7 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
                     // property set, when the child shifts to clear an item, its width can
                     // change (because it has more available line width).
                     // So go ahead and mark the item as dirty.
-                    child->setNeedsLayout(true);
+                    child->setChildNeedsLayout(true);
 
                 if (child->containsFloats() || containsFloats())
                     child->markAllDescendantsWithFloatsForLayout();
@@ -962,7 +985,7 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
                 // property set, when the child shifts to clear an item, its width can
                 // change (because it has more available line width).
                 // So go ahead an mark the item as dirty.
-                child->setNeedsLayout(true);
+                child->setChildNeedsLayout(true);
             if (child->containsFloats())
                 child->markAllDescendantsWithFloatsForLayout();
             child->layoutIfNeeded();
@@ -1048,6 +1071,14 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
             child->style()->setDisplay(COMPACT);
             treatCompactAsBlock = false;
         }
+
+        // If the child moved, we have to repaint it as well as any floating/positioned
+        // descendants.  An exception is if we need a layout.  In this case, we know we're going to
+        // repaint ourselves (and the child) anyway.
+#ifdef INCREMENTAL_REPAINTING
+        if (!selfNeedsLayout())
+            child->repaintIfMoved(oldChildX, oldChildY);
+#endif
         
         child = child->nextSibling();
     }
@@ -1106,12 +1137,67 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
         for ( ; (r = it.current()); ++it ) {
             //kdDebug(6040) << "   have a positioned object" << endl;
             if ( relayoutChildren )
-                r->setNeedsLayout(true);
+                r->setChildNeedsLayout(true);
             r->layoutIfNeeded();
         }
     }
 }
 
+#ifdef INCREMENTAL_REPAINTING
+void RenderBlock::getAbsoluteRepaintRectIncludingDescendants(QRect& bounds, QRect& fullBounds)
+{
+    bounds = fullBounds = getAbsoluteRepaintRect();
+    if (m_positionedObjects) {
+        RenderObject* r;
+        QPtrListIterator<RenderObject> it(*m_positionedObjects);
+        for ( ; (r = it.current()); ++it ) {
+            QRect childRect, childFullRect;
+            r->getAbsoluteRepaintRectIncludingDescendants(childRect, childFullRect);
+            fullBounds = fullBounds.unite(childFullRect);
+        }
+    }
+
+    // Include any overhanging floats (if we know we're the one to paint them).
+    if (hasOverhangingFloats()) {
+        FloatingObject* r;
+        QPtrListIterator<FloatingObject> it(*m_floatingObjects);
+        for ( ; (r = it.current()); ++it) {
+            // Only repaint the object if our noPaint flag isn't set.
+            if (!r->noPaint) {
+                QRect childRect, childFullRect;
+                r->node->getAbsoluteRepaintRectIncludingDescendants(childRect, childFullRect);
+                fullBounds = fullBounds.unite(childFullRect);
+            }
+        }
+    }
+}
+
+void RenderBlock::repaintPositionedAndFloatingDescendants()
+{
+    if (m_positionedObjects) {
+        RenderObject* r;
+        QPtrListIterator<RenderObject> it(*m_positionedObjects);
+        for ( ; (r = it.current()); ++it ) {
+            r->repaint();
+            r->repaintPositionedAndFloatingDescendants();
+        }
+    }
+
+    // Repaint any overhanging floats (if we know we're the one to paint them).
+    if (hasOverhangingFloats()) {
+        FloatingObject* r;
+        QPtrListIterator<FloatingObject> it(*m_floatingObjects);
+        for ( ; (r = it.current()); ++it) {
+            // Only repaint the object if our noPaint flag isn't set.
+            if (!r->noPaint) {
+                r->node->repaint();
+                r->node->repaintPositionedAndFloatingDescendants();
+            }
+        }
+    }
+}
+#endif
+
 void RenderBlock::paint(QPainter* p, int _x, int _y, int _w, int _h, int _tx, int _ty, PaintAction paintAction)
 {
     _tx += m_x;
@@ -1210,7 +1296,7 @@ void RenderBlock::paintFloats(QPainter *p, int _x, int _y,
     QPtrListIterator<FloatingObject> it(*m_floatingObjects);
     for ( ; (r = it.current()); ++it) {
         // Only paint the object if our noPaint flag isn't set.
-        if (r->node->isFloating() && !r->noPaint && !r->node->layer()) {
+        if (!r->noPaint && !r->node->layer()) {
             if (paintSelection) {
                 r->node->paint(p, _x, _y, _w, _h,
                                _tx + r->left - r->node->xPos() + r->node->marginLeft(),
@@ -2345,14 +2431,6 @@ void RenderBlock::calcBlockMinMaxWidth()
     }
 }
 
-void RenderBlock::close()
-{
-    if (lastChild() && lastChild()->isAnonymousBox())
-        lastChild()->close();
-
-    RenderFlow::close();
-}
-
 short RenderBlock::lineHeight(bool b, bool isRootLineBox) const
 {
     // Inline blocks are replaced elements. Otherwise, just pass off to
diff --git a/WebCore/khtml/rendering/render_block.h b/WebCore/khtml/rendering/render_block.h
index 6675b74..77d8a93 100644
--- a/WebCore/khtml/rendering/render_block.h
+++ b/WebCore/khtml/rendering/render_block.h
@@ -92,7 +92,12 @@ public:
 
     virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
     virtual void removeChild(RenderObject *oldChild);
-        
+
+#ifdef INCREMENTAL_REPAINTING
+    virtual void repaintPositionedAndFloatingDescendants();
+    virtual void getAbsoluteRepaintRectIncludingDescendants(QRect& bounds, QRect& fullBounds);
+#endif
+
     virtual void setStyle(RenderStyle* _style);
 
     virtual void layout();
@@ -167,8 +172,6 @@ public:
     void calcInlineMinMaxWidth();
     void calcBlockMinMaxWidth();
 
-    virtual void close();
-
     virtual int getBaselineOfFirstLineBox();
     virtual InlineFlowBox* getFirstLineBox();
     
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index 4ad3b97..b26a319 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -71,7 +71,7 @@ void RenderBox::setStyle(RenderStyle *_style)
     // The root always paints its background/border.
     if (isRoot())
         setShouldPaintBackgroundOrBorder(true);
-    
+
     setInline(_style->isDisplayInlineType());
     
     switch(_style->position())
@@ -189,8 +189,12 @@ void RenderBox::paint(QPainter *p, int _x, int _y, int _w, int _h,
 
 void RenderBox::setPixmap(const QPixmap &, const QRect&, CachedImage *image)
 {
-    if(image && image->pixmap_size() == image->valid_rect().size() && parent())
-        repaint();      //repaint bg when it finished loading
+    if (image && image->pixmap_size() == image->valid_rect().size() && parent()) {
+        if (element() && (element()->id() == ID_HTML || element()->id() == ID_BODY))
+            canvas()->repaint(); // repaint the entire canvas, since the background gets propagated up.
+        else
+            repaint();      //repaint bg when it finished loading
+    }
 }
 
 void RenderBox::paintRootBoxDecorations(QPainter *p,int, int _y,
@@ -498,11 +502,6 @@ QRect RenderBox::getClipRect(int tx, int ty)
     return cr;
 }
 
-void RenderBox::close()
-{
-    setNeedsLayoutAndMinMaxRecalc();
-}
-
 short RenderBox::containingBlockWidth() const
 {
     if (isRoot() && canvas()->view())
@@ -569,24 +568,19 @@ void RenderBox::position(InlineBox* box, int from, int len, bool reverse)
     }
 }
 
-void RenderBox::repaint(bool immediate)
+QRect RenderBox::getAbsoluteRepaintRect()
 {
-    //kdDebug( 6040 ) << "repaint!" << endl;
-    if (isRoot() || isBody()) {
-        RenderObject *cb = containingBlock();
-        if(cb != this)
-            cb->repaint(immediate);
-        return;
-    }
     int ow = style() ? style()->outlineWidth() : 0;
-    repaintRectangle(-ow, -ow, overflowWidth(false)+ow*2, overflowHeight(false)+ow*2, immediate);
+    QRect r(-ow, -ow, overflowWidth(false)+ow*2, overflowHeight(false)+ow*2);
+    computeAbsoluteRepaintRect(r);
+    return r;
 }
 
-void RenderBox::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
+void RenderBox::computeAbsoluteRepaintRect(QRect& r, bool f)
 {
-    x += m_x;
-    y += m_y;
-    
+    int x = r.x() + m_x;
+    int y = r.y() + m_y;
+     
     // Apply the relative position offset when invalidating a rectangle.  The layer
     // is translated, but the render box isn't, so we need to do this to get the
     // right dirty rect.  Since this is called from RenderObject::setStyle, the relative position
@@ -594,7 +588,8 @@ void RenderBox::repaintRectangle(int x, int y, int w, int h, bool immediate, boo
     if (style()->position() == RELATIVE)
         relativePositionOffset(x,y);
     
-    if (style()->position()==FIXED) f=true;
+    if (style()->position()==FIXED)
+        f = true;
 
     RenderObject* o = container();
     if (o) {
@@ -603,19 +598,42 @@ void RenderBox::repaintRectangle(int x, int y, int w, int h, bool immediate, boo
             QRect boxRect(-ow, -ow, o->width()+ow*2, o->height()+ow*2);
             if (o->layer())
                 o->layer()->subtractScrollOffset(x,y); // For overflow:auto/scroll/hidden.
-            QRect repaintRect(x, y, w, h);
-            if (!repaintRect.intersects(boxRect))
+            QRect repaintRect(x, y, r.width(), r.height());
+            if (!repaintRect.intersects(boxRect)) {
+                r = QRect();
                 return;
-            repaintRect = repaintRect.intersect(boxRect);
-            x = repaintRect.x();
-            y = repaintRect.y();
-            w = repaintRect.width();
-            h = repaintRect.height();
+            }
+            r = repaintRect.intersect(boxRect);
         }
-        o->repaintRectangle(x, y, w, h, immediate, f);
+        else {
+            r.setX(x);
+            r.setY(y);
+        }
+        o->computeAbsoluteRepaintRect(r, f);
     }
 }
 
+#ifdef INCREMENTAL_REPAINTING
+void RenderBox::repaintIfMoved(int oldX, int oldY)
+{
+    if (isCanvas())
+        return;
+    
+    int newX = m_x;
+    int newY = m_y;
+    if (oldX != newX || oldY != newY) {
+        // The child moved.  Invalidate the object's old and new positions.  We have to do this
+        // since the object may not have gotten a layout.
+        m_x = oldX; m_y = oldY;
+        repaint();
+        repaintPositionedAndFloatingDescendants();
+        m_x = newX; m_y = newY;
+        repaint();
+        repaintPositionedAndFloatingDescendants();
+    }
+}
+#endif
+
 void RenderBox::relativePositionOffset(int &tx, int &ty)
 {
     if(!style()->left().isVariable())
@@ -1003,8 +1021,9 @@ void RenderBox::calcAbsoluteHorizontal()
     int pab = borderLeft()+ borderRight()+ paddingLeft()+ paddingRight();
 
     l=r=ml=mr=w=AUTO;
-
-    RenderBlock* cb = containingBlock();
+ 
+    // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
+    RenderObject* cb = container();
     cw = containingBlockWidth() + cb->paddingLeft() + cb->paddingRight();
 
     if(!style()->left().isVariable())
@@ -1040,7 +1059,6 @@ void RenderBox::calcAbsoluteHorizontal()
             || style()->right().isStatic())
     {
         RenderObject* po = parent();
-        RenderBlock* cb = containingBlock();
         static_distance = m_staticX - cb->borderLeft(); // Should already have been set through layout of the parent().
         while (po && po!=containingBlock()) {
             static_distance+=po->xPos();
@@ -1158,7 +1176,8 @@ void RenderBox::calcAbsoluteVertical()
 
     int pab = borderTop()+borderBottom()+paddingTop()+paddingBottom();
 
-    RenderObject* cb = containingBlock();
+    // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
+    RenderObject* cb = container();
     Length hl = cb->style()->height();
     if (hl.isFixed())
         ch = hl.value + cb->paddingTop()
diff --git a/WebCore/khtml/rendering/render_box.h b/WebCore/khtml/rendering/render_box.h
index 1023b82..b9bfa30 100644
--- a/WebCore/khtml/rendering/render_box.h
+++ b/WebCore/khtml/rendering/render_box.h
@@ -50,8 +50,6 @@ public:
     virtual void paint(QPainter *p, int _x, int _y, int _w, int _h,
                        int _tx, int _ty, PaintAction paintAction);
 
-    virtual void close();
-
     virtual void detach(RenderArena* renderArena);
     
     virtual short minWidth() const { return m_minWidth; }
@@ -88,10 +86,13 @@ public:
     virtual int lowestPosition(bool includeOverflowInterior=true) const;
     virtual int rightmostPosition(bool includeOverflowInterior=true) const;
 
-    virtual void repaint(bool immediate=false);
-
-    virtual void repaintRectangle(int x, int y, int w, int h, bool immediate=false, bool f=false);
+    virtual QRect getAbsoluteRepaintRect();
+    virtual void computeAbsoluteRepaintRect(QRect& r, bool f=false);
 
+#ifdef INCREMENTAL_REPAINTING
+    virtual void repaintIfMoved(int oldX, int oldY);
+#endif
+    
     virtual void setPixmap(const QPixmap &, const QRect&, CachedImage *);
 
     virtual short containingBlockWidth() const;
diff --git a/WebCore/khtml/rendering/render_canvas.cpp b/WebCore/khtml/rendering/render_canvas.cpp
index bb4d70f..9c3108d 100644
--- a/WebCore/khtml/rendering/render_canvas.cpp
+++ b/WebCore/khtml/rendering/render_canvas.cpp
@@ -122,11 +122,17 @@ void RenderCanvas::calcMinMaxWidth()
 
 void RenderCanvas::layout()
 {
+#ifdef INCREMENTAL_REPAINTING
+    QRect oldBounds(m_x, m_y, m_width, m_height);
+#endif
+
     if (m_printingMode)
        m_minWidth = m_width;
 
+    setChildNeedsLayout(true);
+    setMinMaxKnown(false);
     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
-        c->setNeedsLayout(true);
+        c->setChildNeedsLayout(true);
 
 #ifdef SPEED_DEBUG
     QTime qt;
@@ -173,6 +179,12 @@ void RenderCanvas::layout()
     layer()->setHeight(QMAX(doch, m_height));
     layer()->setWidth(QMAX(docw, m_width));
 
+#ifdef INCREMENTAL_REPAINTING
+    QRect newBounds(m_x, m_y, m_width, m_height);
+    if (oldBounds != newBounds)
+        repaint();
+#endif
+    
     setNeedsLayout(false);
 }
 
@@ -255,54 +267,52 @@ void RenderCanvas::paintBoxDecorations(QPainter *p,int _x, int _y,
         p->fillRect(_x,_y,_w,_h, view()->palette().active().color(QColorGroup::Base));
 }
 
-void RenderCanvas::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
+void RenderCanvas::repaintViewRectangle(const QRect& ur, bool immediate)
 {
-    if (m_printingMode) return;
-//    kdDebug( 6040 ) << "updating views contents (" << x << "/" << y << ") (" << w << "/" << h << ")" << endl;
-
-    if ( f && m_view ) {
-        x += m_view->contentsX();
-        y += m_view->contentsY();
-    }
+    if (m_printingMode || ur.width() == 0 || ur.height() == 0) return;
 
     QRect vr = viewRect();
-    QRect ur(x, y, w, h);
-
-    if (m_view && ur.intersects(vr))
-        if (immediate)
-            m_view->updateContents(ur, true);
-        else
-            m_view->scheduleRepaint(x, y, w, h);
+    if (m_view && ur.intersects(vr)) {
+        // We always just invalidate the root view, since we could be an iframe that is clipped out
+        // or even invisible.
+        QRect r = ur.intersect(vr);
+        DOM::ElementImpl* elt = element()->getDocument()->ownerElement();
+        if (!elt)
+            m_view->repaintRectangle(r, immediate);
+        else {
+            // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
+            // rectangle.
+            r.setX(r.x() - m_view->contentsX());
+            r.setY(r.y() - m_view->contentsY());
+
+            RenderObject* obj = elt->renderer();
+            r.setX(r.x() + obj->borderLeft()+obj->paddingLeft());
+            r.setY(r.y() + obj->borderTop()+obj->paddingTop());
+            obj->repaintRectangle(r, immediate);
+        }
+    }
 }
 
-void RenderCanvas::repaint(bool immediate)
+QRect RenderCanvas::getAbsoluteRepaintRect()
 {
-    if (m_view && !m_printingMode) {
-        if (immediate) {
-            m_view->resizeContents(docWidth(), docHeight());
-            m_view->unscheduleRepaint();
-            if (needsLayout()) {
-                m_view->scheduleRelayout();
-                return;
-            }
-            m_view->updateContents(m_view->contentsX(), m_view->contentsY(),
-                                   m_view->visibleWidth(), m_view->visibleHeight(), true);
-        }
-        else
-            m_view->scheduleRepaint(m_view->contentsX(), m_view->contentsY(),
-                                    m_view->visibleWidth(), m_view->visibleHeight());
-    }
+    QRect result;
+    if (m_view && !m_printingMode)
+        result = QRect(m_view->contentsX(), m_view->contentsY(),
+                       m_view->visibleWidth(), m_view->visibleHeight());
+    return result;
 }
 
-void RenderCanvas::close()
+void RenderCanvas::computeAbsoluteRepaintRect(QRect& r, bool f)
 {
-    setNeedsLayout(true);
-    if (m_view) {
-        m_view->layout();
+    if (m_printingMode) return;
+
+    if (f && m_view) {
+        r.setX(r.x() + m_view->contentsX());
+        r.setY(r.y() + m_view->contentsY());
     }
-    //printTree();
 }
 
+
 static QRect enclosingPositionedRect (RenderObject *n)
 {
     RenderObject *enclosingParent =  n->containingBlock();
diff --git a/WebCore/khtml/rendering/render_canvas.h b/WebCore/khtml/rendering/render_canvas.h
index f2aef68..04350bc 100644
--- a/WebCore/khtml/rendering/render_canvas.h
+++ b/WebCore/khtml/rendering/render_canvas.h
@@ -44,15 +44,16 @@ public:
     virtual void calcHeight();
     virtual void calcMinMaxWidth();
     virtual bool absolutePosition(int &xPos, int&yPos, bool f = false);
-    virtual void close();
-
+    
     int docHeight() const;
     int docWidth() const;
 
     KHTMLView *view() const { return m_view; }
 
-    virtual void repaint(bool immediate=false);
-    virtual void repaintRectangle(int x, int y, int w, int h, bool immediate = false, bool f=false);
+    virtual QRect getAbsoluteRepaintRect();
+    virtual void computeAbsoluteRepaintRect(QRect& r, bool f=false);
+    virtual void repaintViewRectangle(const QRect& r, bool immediate = false);
+    
     virtual void paint(QPainter *, int x, int y, int w, int h, int tx, int ty,
                        PaintAction paintAction);
     void paintObject(QPainter *p, int _x, int _y,
diff --git a/WebCore/khtml/rendering/render_container.cpp b/WebCore/khtml/rendering/render_container.cpp
index bff9de3..b1018ca 100644
--- a/WebCore/khtml/rendering/render_container.cpp
+++ b/WebCore/khtml/rendering/render_container.cpp
@@ -149,13 +149,20 @@ void RenderContainer::addChild(RenderObject *newChild, RenderObject *beforeChild
 	// just add it...
 	insertChildNode(newChild, beforeChild);
     }
-    newChild->setNeedsLayoutAndMinMaxRecalc();
 }
 
 RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild)
 {
     KHTMLAssert(oldChild->parent() == this);
 
+    // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
+    // that a positioned child got yanked).  We also repaint, so that the area exposed when the child
+    // disappears gets repainted properly.
+    oldChild->setNeedsLayoutAndMinMaxRecalc();
+#ifdef INCREMENTAL_REPAINTING
+    oldChild->repaint();
+#endif
+    
     // Keep our layer hierarchy updated.
     oldChild->removeLayers(enclosingLayer());
    
@@ -192,15 +199,12 @@ RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild)
     oldChild->setNextSibling(0);
     oldChild->setParent(0);
 
-    setNeedsLayoutAndMinMaxRecalc();
-    
     return oldChild;
 }
 
 void RenderContainer::removeChild(RenderObject *oldChild)
 {
     removeChildNode(oldChild);
-    setNeedsLayout(true);
 }
 
 void RenderContainer::updatePseudoChild(RenderStyle::PseudoId type, RenderObject* child)
@@ -349,7 +353,8 @@ void RenderContainer::appendChildNode(RenderObject* newChild)
     RenderLayer* layer = enclosingLayer();
     newChild->addLayers(layer, newChild);
 
-    newChild->setNeedsLayoutAndMinMaxRecalc();
+    newChild->setNeedsLayoutAndMinMaxRecalc(); // Goes up the containing block hierarchy.
+    setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
 }
 
 void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild)
@@ -380,6 +385,7 @@ void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeC
     child->addLayers(layer, child);
 
     child->setNeedsLayoutAndMinMaxRecalc();
+    setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
 }
 
 
diff --git a/WebCore/khtml/rendering/render_flexbox.cpp b/WebCore/khtml/rendering/render_flexbox.cpp
index 6bab9dd..76bcb2c 100644
--- a/WebCore/khtml/rendering/render_flexbox.cpp
+++ b/WebCore/khtml/rendering/render_flexbox.cpp
@@ -240,6 +240,13 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
     KHTMLAssert(needsLayout());
     KHTMLAssert(minMaxKnown());
 
+    if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {
+        // All we have to is lay out our positioned objects.
+        layoutPositionedObjects(relayoutChildren);
+        setNeedsLayout(false);
+        return;
+    }
+    
     int oldWidth = m_width;
     int oldHeight = m_height;
     
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index 58807d1..b4233d6 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -229,7 +229,7 @@ void RenderFlow::paintLineBoxDecorations(QPainter *p, int _x, int _y,
     }
 }
 
-void RenderFlow::repaint(bool immediate)
+QRect RenderFlow::getAbsoluteRepaintRect()
 {
     if (isInlineFlow()) {
         // Find our leftmost position.
@@ -243,19 +243,22 @@ void RenderFlow::repaint(bool immediate)
         int ow = style() ? style()->outlineWidth() : 0;
         if (isCompact())
             left -= m_x;
-        containingBlock()->repaintRectangle(-ow+left, -ow+top,
-                                            width()+ow*2, height()+ow*2, immediate);
+        QRect r(-ow+left, -ow+top, width()+ow*2, height()+ow*2);
+        containingBlock()->computeAbsoluteRepaintRect(r);
+        return r;
     }
     else {
         if (firstLineBox() && firstLineBox()->topOverflow() < 0) {
             int ow = style() ? style()->outlineWidth() : 0;
-            repaintRectangle(-ow, -ow+firstLineBox()->topOverflow(),
-                             overflowWidth(false)+ow*2,
-                             overflowHeight(false)+ow*2-firstLineBox()->topOverflow(), immediate);
+            QRect r(-ow, -ow+firstLineBox()->topOverflow(),
+                    overflowWidth(false)+ow*2,
+                    overflowHeight(false)+ow*2-firstLineBox()->topOverflow());
+            computeAbsoluteRepaintRect(r);
+            return r;
         }
-        else
-            return RenderBox::repaint(immediate);
     }
+
+    return RenderBox::getAbsoluteRepaintRect();
 }
 
 int
diff --git a/WebCore/khtml/rendering/render_flow.h b/WebCore/khtml/rendering/render_flow.h
index 0ef9399..4c9b6aa 100644
--- a/WebCore/khtml/rendering/render_flow.h
+++ b/WebCore/khtml/rendering/render_flow.h
@@ -69,8 +69,8 @@ public:
     void paintLineBoxDecorations(QPainter *p, int _x, int _y,
                                  int _w, int _h, int _tx, int _ty, PaintAction paintAction);
 
-    virtual void repaint(bool immediate = false);
-
+    virtual QRect getAbsoluteRepaintRect();
+    
     virtual int lowestPosition(bool includeOverflowInterior=true) const;
     virtual int rightmostPosition(bool includeOverflowInterior=true) const;
     
diff --git a/WebCore/khtml/rendering/render_image.cpp b/WebCore/khtml/rendering/render_image.cpp
index 4ed65bc..c287cbd 100644
--- a/WebCore/khtml/rendering/render_image.cpp
+++ b/WebCore/khtml/rendering/render_image.cpp
@@ -157,16 +157,13 @@ void RenderImage::setPixmap( const QPixmap &p, const QRect& r, CachedImage *o)
     
     pix = p;
 
-    if(needlayout)
-    {
-        setNeedsLayout(true);
-        setMinMaxKnown(false);
-
-//         kdDebug( 6040 ) << "m_width: : " << m_width << " height: " << m_height << endl;
-//         kdDebug( 6040 ) << "Image: size " << m_width << "/" << m_height << endl;
+    if (needlayout) {
+        if (!selfNeedsLayout())
+            setNeedsLayout(true);
+        if (minMaxKnown())
+            setMinMaxKnown(false);
     }
-    else
-    {
+    else {
         bool completeRepaint = !resizeCache.isNull();
         int cHeight = contentHeight();
         int scaledHeight = intrinsicHeight() ? ((o->valid_rect().height()*cHeight)/intrinsicHeight()) : 0;
@@ -178,11 +175,11 @@ void RenderImage::setPixmap( const QPixmap &p, const QRect& r, CachedImage *o)
 
         resizeCache = QPixmap(); // for resized animations
         if(completeRepaint)
-            repaintRectangle(borderLeft()+paddingLeft(), borderTop()+paddingTop(), contentWidth(), contentHeight());
+            repaintRectangle(QRect(borderLeft()+paddingLeft(), borderTop()+paddingTop(), contentWidth(), contentHeight()));
         else
         {
-            repaintRectangle(r.x() + borderLeft() + paddingLeft(), r.y() + borderTop() + paddingTop(),
-                             r.width(), r.height());
+            repaintRectangle(QRect(r.x() + borderLeft() + paddingLeft(), r.y() + borderTop() + paddingTop(),
+                             r.width(), r.height()));
         }
     }
 }
@@ -354,6 +351,10 @@ void RenderImage::layout()
     KHTMLAssert(needsLayout());
     KHTMLAssert( minMaxKnown() );
 
+#ifdef INCREMENTAL_PAINTING
+    QRect oldBounds(getAbsoluteRepaintRect());
+#endif
+    
     short oldwidth = m_width;
     int oldheight = m_height;
 
@@ -381,10 +382,14 @@ void RenderImage::layout()
 	m_height = (int) (m_height/scale);
     }
 #endif
-    
+
     if ( m_width != oldwidth || m_height != oldheight )
         resizeCache = QPixmap();
 
+#ifdef INCREMENTAL_PAINTING
+    repaintAfterLayoutIfNeeded(oldBounds, oldBounds);
+#endif
+    
     setNeedsLayout(false);
 }
 
diff --git a/WebCore/khtml/rendering/render_inline.cpp b/WebCore/khtml/rendering/render_inline.cpp
index 69fa098..d6b0f85 100644
--- a/WebCore/khtml/rendering/render_inline.cpp
+++ b/WebCore/khtml/rendering/render_inline.cpp
@@ -75,8 +75,6 @@ void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeCh
     if (!beforeChild && lastChild() && lastChild()->style()->styleType() == RenderStyle::AFTER)
         beforeChild = lastChild();
     
-    setNeedsLayout(true);
-    
     if (!newChild->isText() && newChild->style()->position() != STATIC)
         setOverhangingContents();
     
diff --git a/WebCore/khtml/rendering/render_layer.cpp b/WebCore/khtml/rendering/render_layer.cpp
index 6ce9152..2aba1fb 100644
--- a/WebCore/khtml/rendering/render_layer.cpp
+++ b/WebCore/khtml/rendering/render_layer.cpp
@@ -323,6 +323,21 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int&
     
     parentLayer->convertToLayerCoords(ancestorLayer, x, y);
 
+    if (m_object->style()->position() == ABSOLUTE && parentLayer->renderer()->style()->position() == RELATIVE &&
+        parentLayer->renderer()->isInline() && !parentLayer->renderer()->isReplaced()) {
+        // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
+        // box from the rest of the content, but only in the cases where we know we're positioned
+        // relative to the inline itself.
+        RenderFlow* flow = static_cast<RenderFlow*>(parentLayer->renderer());
+        if (flow->firstLineBox()) {
+            bool isInlineType = m_object->style()->isOriginalDisplayInlineType();
+            if (!m_object->hasStaticX() || (m_object->hasStaticX() && !isInlineType))
+                x += flow->firstLineBox()->xPos();
+            if (!m_object->hasStaticY())
+                y += flow->firstLineBox()->yPos();
+        }
+    }
+    
     x += xPos();
     y += yPos();
 }
diff --git a/WebCore/khtml/rendering/render_list.cpp b/WebCore/khtml/rendering/render_list.cpp
index a68c93e..69d7eab 100644
--- a/WebCore/khtml/rendering/render_list.cpp
+++ b/WebCore/khtml/rendering/render_list.cpp
@@ -495,10 +495,10 @@ void RenderListMarker::setPixmap( const QPixmap &p, const QRect& r, CachedImage
         return;
     }
 
-    if(m_width != m_listImage->pixmap_size().width() || m_height != m_listImage->pixmap_size().height())
+    if (m_width != m_listImage->pixmap_size().width() || m_height != m_listImage->pixmap_size().height())
         setNeedsLayoutAndMinMaxRecalc();
     else
-        repaintRectangle(0, 0, m_width, m_height);
+        repaint();
 }
 
 void RenderListMarker::calcMinMaxWidth()
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 5a8679e..d974bf6 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -122,8 +122,9 @@ m_parent( 0 ),
 m_previous( 0 ),
 m_next( 0 ),
 m_verticalPosition( PositionUndefined ),
-m_needsLayout( true ),
-m_unused( false ),
+m_needsLayout( false ),
+m_normalChildNeedsLayout( false ),
+m_posChildNeedsLayout( false ),
 m_minMaxKnown( false ),
 m_floating( false ),
 
@@ -420,32 +421,81 @@ void RenderObject::markAllDescendantsWithFloatsForLayout(RenderObject*)
 
 void RenderObject::setNeedsLayout(bool b) 
 {
+#ifdef INCREMENTAL_REPAINTING
+    bool alreadyNeededLayout = m_needsLayout;
+#else
+    bool alreadyNeededLayout = false;
+#endif
     m_needsLayout = b;
     if (b) {
-        RenderObject *o = container();
-        RenderObject *root = this;
+        if (!alreadyNeededLayout)
+            markContainingBlocksForLayout();
+    }
+    else {
+        m_posChildNeedsLayout = false;
+        m_normalChildNeedsLayout = false;
+    }
+}
 
-        // If an attempt is made to
-        // setNeedsLayout(true) an object inside a clipped (overflow:hidden) object, we 
-        // have to make sure to repaint only the clipped rectangle.
-        // We do this by passing an argument to scheduleRelayout.  This hint really
-        // shouldn't be needed, and it's unfortunate that it is necessary.  -dwh
+void RenderObject::setChildNeedsLayout(bool b)
+{
+#ifdef INCREMENTAL_REPAINTING
+    bool alreadyNeededLayout = m_normalChildNeedsLayout;
+#else
+    bool alreadyNeededLayout = false;
+#endif
+    m_normalChildNeedsLayout = b;
+    if (b) {
+        if (!alreadyNeededLayout)
+            markContainingBlocksForLayout();
+    }
+    else {
+        m_posChildNeedsLayout = false;
+        m_normalChildNeedsLayout = false;
+    }
+}
 
-        RenderObject* clippedObj = 
-            (style()->hidesOverflow() && !isText()) ? this : 0;
-        
-        while( o ) {
-            root = o;
-            o->m_needsLayout = true;
-            if (o->style()->hidesOverflow() && !clippedObj)
-                clippedObj = o;
-            o = o->container();
+void RenderObject::markContainingBlocksForLayout()
+{
+#ifndef INCREMENTAL_REPAINTING
+    RenderObject* clippedObj = (style()->hidesOverflow() && !isText()) ? this : 0;
+#endif
+    
+    RenderObject *o = container();
+    RenderObject *last = this;
+
+    while (o) {
+        if (last->style()->position() == FIXED || last->style()->position() == ABSOLUTE) {
+#ifdef INCREMENTAL_REPAINTING
+            if (o->m_posChildNeedsLayout)
+                return;
+#endif
+            o->m_posChildNeedsLayout = true;
         }
-        
-        root->scheduleRelayout(clippedObj);
+        else {
+#ifdef INCREMENTAL_REPAINTING
+            if (o->m_normalChildNeedsLayout)
+                return;
+#endif
+            o->m_normalChildNeedsLayout = true;
+        }
+
+#ifndef INCREMENTAL_REPAINTING
+        if (o->style()->hidesOverflow() && !clippedObj)
+            clippedObj = o;
+#endif
+
+        last = o;
+        o = o->container();
     }
+
+#ifdef INCREMENTAL_REPAINTING
+    last->scheduleRelayout();
+#else
+    last->scheduleRelayout(clippedObj);
+#endif
 }
-    
+
 RenderBlock* RenderObject::containingBlock() const
 {
     if(isTableCell())
@@ -460,8 +510,16 @@ RenderBlock* RenderObject::containingBlock() const
     }
     else if (m_style->position() == ABSOLUTE) {
         while (o && (o->style()->position() == STATIC || (o->isInline() && !o->isReplaced()))
-               && !o->isRoot() && !o->isCanvas())
+               && !o->isRoot() && !o->isCanvas()) {
+            // For relpositioned inlines, we return the nearest enclosing block.  We don't try
+            // to return the inline itself.  This allows us to avoid having a positioned objects
+            // list in all RenderInlines and lets us return a strongly-typed RenderBlock* result
+            // from this method.  The container() method can actually be used to obtain the
+            // inline directly.
+            if (o->style()->position() == RELATIVE && o->isInline() && !o->isReplaced())
+                return o->containingBlock();
             o = o->parent();
+        }
     } else {
         while (o && ((o->isInline() && !o->isReplaced()) || o->isTableRow() || o->isTableSection()
                      || o->isTableCol()))
@@ -844,9 +902,80 @@ void RenderObject::paint(QPainter *p, int x, int y, int w, int h, int tx, int ty
     paintObject(p, x, y, w, h, tx, ty, paintAction);
 }
 
-void RenderObject::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
+void RenderObject::repaint(bool immediate)
+{
+    RenderObject* c = canvas();
+    if (!c || !c->isCanvas())
+        return;
+    RenderCanvas* canvasObj = static_cast<RenderCanvas*>(c);
+    if (canvasObj->printingMode())
+        return; // Don't repaint if we're printing.
+
+    canvasObj->repaintViewRectangle(getAbsoluteRepaintRect(), immediate);    
+}
+
+void RenderObject::repaintRectangle(const QRect& r, bool immediate)
 {
-    if(parent()) parent()->repaintRectangle(x, y, w, h, immediate, f);
+    RenderObject* c = canvas();
+    if (!c || !c->isCanvas())
+        return;
+    RenderCanvas* canvasObj = static_cast<RenderCanvas*>(c);
+    if (canvasObj->printingMode())
+        return; // Don't repaint if we're printing.
+
+    QRect absRect(r);
+    computeAbsoluteRepaintRect(absRect);
+    canvasObj->repaintViewRectangle(absRect, immediate);
+}
+
+#ifdef INCREMENTAL_REPAINTING
+void RenderObject::repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds)
+{
+    if (!isFloatingOrPositioned() && parent() && parent()->selfNeedsLayout())
+        return;
+    
+    QRect newBounds, newFullBounds;
+    getAbsoluteRepaintRectIncludingDescendants(newBounds, newFullBounds);
+    if (newBounds != oldBounds || selfNeedsLayout()) {
+        RenderObject* c = canvas();
+        if (!c || !c->isCanvas())
+            return;
+        RenderCanvas* canvasObj = static_cast<RenderCanvas*>(c);
+        if (canvasObj->printingMode())
+            return; // Don't repaint if we're printing.
+        canvasObj->repaintViewRectangle(oldFullBounds);
+        if (newBounds != oldBounds)
+            canvasObj->repaintViewRectangle(newFullBounds);
+    }
+}
+
+void RenderObject::repaintIfMoved(int x, int y)
+{
+}
+
+void RenderObject::repaintPositionedAndFloatingDescendants()
+{
+}
+#endif
+
+QRect RenderObject::getAbsoluteRepaintRect()
+{
+    if (parent())
+        return parent()->getAbsoluteRepaintRect();
+    return QRect();
+}
+
+#ifdef INCREMENTAL_REPAINTING
+void RenderObject::getAbsoluteRepaintRectIncludingDescendants(QRect& bounds, QRect& fullBounds)
+{
+    bounds = fullBounds = getAbsoluteRepaintRect();
+}
+#endif
+
+void RenderObject::computeAbsoluteRepaintRect(QRect& r, bool f)
+{
+    if (parent())
+        return parent()->computeAbsoluteRepaintRect(r, f);
 }
 
 #ifndef NDEBUG
@@ -998,7 +1127,12 @@ void RenderObject::setStyle(RenderStyle *style)
 
     RenderStyle::Diff d = m_style ? m_style->diff( style ) : RenderStyle::Layout;
 
-    if (m_style && m_parent && d == RenderStyle::Visible && !isText())
+    // The background of the root element or the body element could propagate up to
+    // the canvas.  Just dirty the entire canvas when our style changes substantially.
+    if (m_style && d >= RenderStyle::Visible && element() &&
+        (element()->id() == ID_HTML || element()->id() == ID_BODY))
+        canvas()->repaint();
+    else if (m_style && m_parent && d == RenderStyle::Visible && !isText())
         // Do a repaint with the old style first, e.g., for example if we go from
         // having an outline to not having an outline.
         repaint();
@@ -1058,7 +1192,7 @@ void RenderObject::setStyle(RenderStyle *style)
     if ( d >= RenderStyle::Position && m_parent ) {
         //qDebug("triggering relayout");
         setNeedsLayoutAndMinMaxRecalc();
-    } else if ( m_parent && !isText()) {
+    } else if ( m_parent && !isText() && d == RenderStyle::Visible ) {
         //qDebug("triggering repaint");
     	repaint();
     }
@@ -1178,6 +1312,15 @@ RenderCanvas* RenderObject::canvas() const
 
 RenderObject *RenderObject::container() const
 {
+    // This method is extremely similar to containingBlock(), but with a few notable
+    // exceptions.
+    // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when
+    // the object is not part of the primary document subtree yet.
+    // (2) For normal flow elements, it just returns the parent.
+    // (3) For absolute positioned elements, it will return a relative positioned inline.
+    // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle
+    // the layout of the positioned object.  This does mean that calcAbsoluteHorizontal and
+    // calcAbsoluteVertical have to use container().
     EPosition pos = m_style->position();
     RenderObject *o = 0;
     if( pos == FIXED ) {
@@ -1253,6 +1396,7 @@ RenderArena* RenderObject::renderArena() const
 
 void RenderObject::detach(RenderArena* renderArena)
 {
+#ifndef INCREMENTAL_REPAINTING
     // If we're an overflow:hidden object that currently needs layout, we need
     // to make sure the view isn't holding on to us.
     if (needsLayout() && style()->hidesOverflow()) {
@@ -1260,7 +1404,8 @@ void RenderObject::detach(RenderArena* renderArena)
         if (r && r->view()->layoutObject() == this)
             r->view()->unscheduleRelayout();
     }
-    
+#endif
+
     remove();
     
     m_next = m_previous = 0;
@@ -1557,12 +1702,20 @@ void RenderObject::recalcMinMaxWidths()
     m_recalcMinMax = false;
 }
 
+#ifdef INCREMENTAL_REPAINTING
+void RenderObject::scheduleRelayout()
+#else
 void RenderObject::scheduleRelayout(RenderObject* clippedObj)
+#endif
 {
     if (!isCanvas()) return;
     KHTMLView *view = static_cast<RenderCanvas *>(this)->view();
-    if ( view )
+    if (view)
+#ifdef INCREMENTAL_REPAINTING
+        view->scheduleRelayout();
+#else
         view->scheduleRelayout(clippedObj);
+#endif
 }
 
 
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index cab0c0f..f443266 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -35,6 +35,9 @@
 #include "rendering/render_style.h"
 #include "khtml_events.h"
 
+// Uncomment to turn on incremental repainting.
+// #define INCREMENTAL_REPAINTING 1
+
 class QPainter;
 class QTextStream;
 class CSSStyle;
@@ -237,7 +240,10 @@ public:
     bool mouseInside() const;
     bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS)
     bool shouldPaintBackgroundOrBorder() const { return m_paintBackground; }
-    bool needsLayout() const   { return m_needsLayout; }
+    bool needsLayout() const   { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout; }
+    bool selfNeedsLayout() const { return m_needsLayout; }
+    bool posChildNeedsLayout() const { return m_posChildNeedsLayout; }
+    bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; }
     bool minMaxKnown() const{ return m_minMaxKnown; }
     bool overhangingContents() const { return m_overhangingContents; }
     bool hasFirstLine() const { return m_hasFirstLine; }
@@ -259,8 +265,9 @@ public:
     void setOverhangingContents(bool p=true);
 
     virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0);
+    void markContainingBlocksForLayout();
     void setNeedsLayout(bool b);
-
+    void setChildNeedsLayout(bool b);
     void setMinMaxKnown(bool b=true) {
 	m_minMaxKnown = b;
 	if ( !b ) {
@@ -289,8 +296,12 @@ public:
     void setReplaced(bool b=true) { m_replaced = b; }
     void setIsSelectionBorder(bool b=true) { m_isSelectionBorder = b; }
 
-    void scheduleRelayout(RenderObject* clippedObj = 0);
-
+#ifdef INCREMENTAL_REPAINTING
+    void scheduleRelayout();
+#else
+    void scheduleRelayout(RenderObject* clippedObj);
+#endif
+    
     virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox);
     
     // for discussion of lineHeight see CSS2 spec
@@ -559,13 +570,37 @@ public:
 
     virtual void setTable(RenderTable*) {};
 
-    // force a complete repaint
-    virtual void repaint(bool immediate = false) { if(m_parent) m_parent->repaint(immediate); }
-    virtual void repaintRectangle(int x, int y, int w, int h, bool immediate = false, bool f=false);
+    // Repaint the entire object.  Called when, e.g., the color of a border changes, or when a border
+    // style changes.
+    void repaint(bool immediate = false);
 
-    virtual unsigned int length() const { return 1; }
+    // Repaint a specific subrectangle within a given object.  The rect |r| is in the object's coordinate space.
+    void repaintRectangle(const QRect& r, bool immediate = false);
+
+#ifdef INCREMENTAL_REPAINTING
+    // Repaint only if our old bounds and new bounds are different.
+    virtual void repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds);
 
-    virtual bool isHidden() const { return isFloating() || isPositioned(); }
+    // Repaint only if the object moved.
+    virtual void repaintIfMoved(int oldX, int oldY);
+
+    // Called to repaint a block's positioned objects and floats.
+    virtual void repaintPositionedAndFloatingDescendants();
+#endif
+
+    // Returns the rect that should be repainted whenever this object changes.  The rect is in the view's
+    // coordinate space.  This method deals with outlines and overflow.
+    virtual QRect getAbsoluteRepaintRect();
+
+#ifdef INCREMENTAL_REPAINTING
+    virtual void getAbsoluteRepaintRectIncludingDescendants(QRect& bounds, QRect& boundsWithChildren);
+#endif
+
+    // Given a rect in the object's coordinate space, this method converts the rectangle to the view's
+    // coordinate space.
+    virtual void computeAbsoluteRepaintRect(QRect& r, bool f=false);
+    
+    virtual unsigned int length() const { return 1; }
 
     bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); };
     virtual bool containsFloats() { return false; }
@@ -650,12 +685,13 @@ private:
     short m_verticalPosition;
 
     bool m_needsLayout               : 1;
-    bool m_unused                    : 1;
+    bool m_normalChildNeedsLayout    : 1;
+    bool m_posChildNeedsLayout       : 1;
     bool m_minMaxKnown               : 1;
     bool m_floating                  : 1;
 
     bool m_positioned                : 1;
-    bool m_overhangingContents : 1;
+    bool m_overhangingContents       : 1;
     bool m_relPositioned             : 1;
     bool m_paintBackground           : 1; // if the box has something to paint in the
                                           // background painting phase (background, border, etc)
@@ -665,9 +701,9 @@ private:
     bool m_isText                    : 1;
     bool m_inline                    : 1;
     bool m_replaced                  : 1;
-    bool m_mouseInside : 1;
+    bool m_mouseInside               : 1;
     bool m_hasFirstLine              : 1;
-    bool m_isSelectionBorder          : 1;
+    bool m_isSelectionBorder         : 1;
 
     void arenaDelete(RenderArena *arena, void *objectBase);
 
diff --git a/WebCore/khtml/rendering/render_style.cpp b/WebCore/khtml/rendering/render_style.cpp
index 978fa0f..5e65f12 100644
--- a/WebCore/khtml/rendering/render_style.cpp
+++ b/WebCore/khtml/rendering/render_style.cpp
@@ -420,7 +420,8 @@ RenderStyle::Diff RenderStyle::diff( const RenderStyle *other ) const
 //     DataRef<StyleInheritedData> inherited;
 
     if ( *box.get() != *other->box.get() ||
-        *surround.get() != *other->surround.get() ||
+         !(surround->margin == other->surround->margin) ||
+         !(surround->padding == other->surround->padding) ||
          *css3NonInheritedData->flexibleBox.get() != *other->css3NonInheritedData->flexibleBox.get() ||
         !(inherited->indent == other->inherited->indent) ||
         !(inherited->line_height == other->inherited->line_height) ||
@@ -491,6 +492,25 @@ RenderStyle::Diff RenderStyle::diff( const RenderStyle *other ) const
          !(noninherited_flags._vertical_align == other->noninherited_flags._vertical_align))
         return Layout;
 
+    // If our border widths change, then we need to layout.  Other changes to borders
+    // only necessitate a repaint.
+    if (borderLeftWidth() != other->borderLeftWidth() ||
+        borderTopWidth() != other->borderTopWidth() ||
+        borderBottomWidth() != other->borderBottomWidth() ||
+        borderRightWidth() != other->borderRightWidth())
+        return Layout;
+
+    // Make sure these left/top/right/bottom checks stay below all layout checks and above
+    // all visible checks.
+    if (other->position() != STATIC && !(surround->offset == other->surround->offset)) {
+     // FIXME: would like to do this at some point, but will need a new hint that indicates
+     // descendants need to be repainted too.
+     //   if (other->position() == RELATIVE)
+     //       return Visible;
+     //   else
+            return Layout;
+    }
+
     // Visible:
 // 	EVisibility _visibility : 2;
 //     EOverflow _overflow : 4 ;
@@ -504,6 +524,7 @@ RenderStyle::Diff RenderStyle::diff( const RenderStyle *other ) const
         !(noninherited_flags._bg_repeat == other->noninherited_flags._bg_repeat) ||
         !(noninherited_flags._bg_attachment == other->noninherited_flags._bg_attachment) ||
         !(inherited_flags._text_decorations == other->inherited_flags._text_decorations) ||
+        !(surround->border == other->surround->border) ||
         *background.get() != *other->background.get() ||
         !(visual->clip == other->visual->clip) ||
         visual->hasClip != other->visual->hasClip ||
diff --git a/WebCore/khtml/rendering/render_table.cpp b/WebCore/khtml/rendering/render_table.cpp
index 6faf172..32bd820 100644
--- a/WebCore/khtml/rendering/render_table.cpp
+++ b/WebCore/khtml/rendering/render_table.cpp
@@ -214,8 +214,21 @@ void RenderTable::layout()
     KHTMLAssert( minMaxKnown() );
     KHTMLAssert( !needSectionRecalc );
 
+    if (posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {
+        // All we have to is lay out our positioned objects.
+        layoutPositionedObjects(true);
+        setNeedsLayout(false);
+        return;
+    }
+    
     //kdDebug( 6040 ) << renderName() << "(Table)"<< this << " ::layout0() width=" << width() << ", needsLayout=" << needsLayout() << endl;
 
+#ifdef INCREMENTAL_REPAINTING
+    // FIXME: We should be smarter about this, but for now just always repaint a table whenever it
+    // does a layout.
+    repaint();
+#endif
+    
     m_height = 0;
     initMaxMarginValues();
     
@@ -344,6 +357,12 @@ void RenderTable::layout()
     // ### only pass true if width or height changed.
     layoutPositionedObjects( true );
 
+#ifdef INCREMENTAL_REPAINTING
+    // FIXME: We should be smarter about this, but for now just always repaint a table whenever it
+    // does a layout.
+    repaint();
+#endif
+    
     setNeedsLayout(false);
 }
 
@@ -1383,13 +1402,15 @@ void RenderTableRow::layout()
     setNeedsLayout(false);
 }
 
-void RenderTableRow::repaint(bool immediate)
+QRect RenderTableRow::getAbsoluteRepaintRect()
 {
     // For now, just repaint the whole table.
     // FIXME: Find a better way to do this.
     RenderTable* parentTable = table();
     if (parentTable)
-        parentTable->repaint(immediate);
+        return parentTable->getAbsoluteRepaintRect();
+    else
+        return QRect();
 }
 
 // -------------------------------------------------------------------------
@@ -1482,10 +1503,10 @@ void RenderTableCell::close()
 }
 
 
-void RenderTableCell::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
+void RenderTableCell::computeAbsoluteRepaintRect(QRect& r, bool f)
 {
-    y += _topExtra;
-    RenderBlock::repaintRectangle(x, y, w, h, immediate, f);
+    r.setY(r.y() + _topExtra);
+    RenderBlock::computeAbsoluteRepaintRect(r, f);
 }
 
 bool RenderTableCell::absolutePosition(int &xPos, int &yPos, bool f)
diff --git a/WebCore/khtml/rendering/render_table.h b/WebCore/khtml/rendering/render_table.h
index b2d89e7..82f3b3c 100644
--- a/WebCore/khtml/rendering/render_table.h
+++ b/WebCore/khtml/rendering/render_table.h
@@ -280,7 +280,7 @@ public:
     virtual void position(int, int, int, int, int, bool, bool, int) {}
 
     virtual void layout();
-    virtual void repaint(bool immediate=false);
+    virtual QRect getAbsoluteRepaintRect();
     
     RenderTable *table() const { return static_cast<RenderTable *>(parent()->parent()); }
     RenderTableSection *section() const { return static_cast<RenderTableSection *>(parent()); }
@@ -341,7 +341,7 @@ public:
     // lie position to outside observers
     virtual int yPos() const { return m_y + _topExtra; }
 
-    virtual void repaintRectangle(int x, int y, int w, int h, bool immediate = false, bool f=false);
+    virtual void computeAbsoluteRepaintRect(QRect& r, bool f=false);
     virtual bool absolutePosition(int &xPos, int &yPos, bool f = false);
 
     virtual short baselinePosition( bool = false ) const;
diff --git a/WebCore/khtml/xml/dom_nodeimpl.cpp b/WebCore/khtml/xml/dom_nodeimpl.cpp
index 0ba429c..dc8dbd2 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.cpp
+++ b/WebCore/khtml/xml/dom_nodeimpl.cpp
@@ -1228,14 +1228,8 @@ NodeImpl *NodeBaseImpl::insertBefore ( NodeImpl *newChild, NodeImpl *refChild, i
 
         // Add child to the rendering tree
         // ### should we detach() it first if it's already attached?
-        if (attached() && !child->attached()) {
+        if (attached() && !child->attached())
             child->attach();
-            // This is extremely important, as otherwise a fresh layout
-            // isn't scheduled, and you end up with stale data (especially
-            // with inline runs of text). -dwh
-            if (child->renderer())
-                child->renderer()->setNeedsLayout(true);
-        }
 
         // Dispatch the mutation events
         dispatchChildInsertedEvents(child,exceptioncode);
@@ -1302,14 +1296,8 @@ NodeImpl *NodeBaseImpl::replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, i
 
         // Add child to the rendering tree
         // ### should we detach() it first if it's already attached?
-        if (attached() && !child->attached()) {
+        if (attached() && !child->attached())
             child->attach();
-            // This is extremely important, as otherwise a fresh layout
-            // isn't scheduled, and you end up with stale data (especially
-            // with inline runs of text). -dwh
-            if (child->renderer())
-                child->renderer()->setNeedsLayout(true);
-        }
 
         // Dispatch the mutation events
         dispatchChildInsertedEvents(child,exceptioncode);
@@ -1455,14 +1443,8 @@ NodeImpl *NodeBaseImpl::appendChild ( NodeImpl *newChild, int &exceptioncode )
 
         // Add child to the rendering tree
         // ### should we detach() it first if it's already attached?
-        if (attached() && !child->attached()) {
+        if (attached() && !child->attached())
             child->attach();
-            // This is extremely important, as otherwise a fresh layout
-            // isn't scheduled, and you end up with stale data (especially
-            // with inline runs of text). -dwh
-            if (child->renderer())
-                child->renderer()->setNeedsLayout(true);
-        }
           
         // Dispatch the mutation events
         dispatchChildInsertedEvents(child,exceptioncode);
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index 468d009..44517f6 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -1577,10 +1577,8 @@ void KWQKHTMLPart::khtmlMouseReleaseEvent(MouseReleaseEvent *event)
 
 void KWQKHTMLPart::clearTimers(KHTMLView *view)
 {
-    if (view) {
+    if (view)
         view->unscheduleRelayout();
-        view->unscheduleRepaint();
-    }
 }
 
 void KWQKHTMLPart::clearTimers()
diff --git a/WebCore/kwq/KWQRenderTreeDebug.cpp b/WebCore/kwq/KWQRenderTreeDebug.cpp
index 751b9de..f103e5c 100644
--- a/WebCore/kwq/KWQRenderTreeDebug.cpp
+++ b/WebCore/kwq/KWQRenderTreeDebug.cpp
@@ -147,6 +147,7 @@ static void write(QTextStream &ts, const RenderObject &o, int indent = 0)
         if (view) {
             RenderObject *root = KWQ(view->part())->renderer();
             if (root) {
+	        root->layoutIfNeeded();
                 RenderLayer* l = root->layer();
                 if (l)
                     writeLayers(ts, l, l, QRect(l->xPos(), l->yPos(), l->width(), l->height()), indent+1);
@@ -210,12 +211,13 @@ static void writeLayers(QTextStream &ts, const RenderLayer* rootLayer, RenderLay
     }
 }
 
-QString externalRepresentation(const RenderObject *o)
+QString externalRepresentation(RenderObject *o)
 {
     QString s;
     {
         QTextStream ts(&s);
         if (o) {
+	    o->layoutIfNeeded();
             RenderLayer* l = o->layer();
             if (l)
                 writeLayers(ts, l, l, QRect(l->xPos(), l->yPos(), l->width(), l->height()));
diff --git a/WebCore/kwq/KWQRenderTreeDebug.h b/WebCore/kwq/KWQRenderTreeDebug.h
index f0e9317..dc0ceb7 100644
--- a/WebCore/kwq/KWQRenderTreeDebug.h
+++ b/WebCore/kwq/KWQRenderTreeDebug.h
@@ -29,4 +29,4 @@ namespace khtml {
     class RenderObject;
 }
 
-QString externalRepresentation(const khtml::RenderObject *);
+QString externalRepresentation(khtml::RenderObject *);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list