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

trey trey at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:44:22 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 2e35f66e3f9bf26d905acd1eba7fb5a93374cbbc
Author: trey <trey at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jun 8 07:11:50 2004 +0000

    	WebCore will now generate a default drag image when an element serves as a drag
    	source.  The basic idea is the image contains the element and all its children.
    
    	As for the implementation, instead of adding a new paintAction I added a new
    	field to the paintInfo struct, "paintingRoot".  If this field is set, painting will
    	only paint that root's descendants.
    
    	Some code also moved from the bridge to the part, to be available within WebCore.
    
            Reviewed by hyatt.
    
            * khtml/rendering/render_block.cpp:
            (khtml::RenderBlock::paintObject):  Pass along paintingRoot to kids.
            (khtml::RenderBlock::paintFloats):  Pass along paintingRoot to kids.
            * khtml/rendering/render_box.cpp:
            (RenderBox::paintBoxDecorations):  Test paintingRoot before painting.
            * khtml/rendering/render_canvasimage.cpp:
            (RenderCanvasImage::paint):    Test paintingRoot before painting.
            * khtml/rendering/render_flow.cpp:
            (RenderFlow::paintLineBoxBackgroundBorder):    Test paintingRoot before painting.
            (RenderFlow::paintLineBoxDecorations):    Test paintingRoot before painting.
            * khtml/rendering/render_image.cpp:
            (RenderImage::paint):    Test paintingRoot before painting.
            * khtml/rendering/render_inline.cpp:
            (RenderInline::paint):    Pass along paintingRoot to kids.
            * khtml/rendering/render_layer.cpp:
            (RenderLayer::paint):   Pass along paintingRoot to kids.
            (RenderLayer:: paintLayer):  Pass along paintingRoot to kids.  Test if we are within the
    	paintingRoot to decide whether to pass the root to our renderer.
            * khtml/rendering/render_layer.h:
            * khtml/rendering/render_object.cpp:
            (RenderObject::hasAncestor):  New utility.
            (RenderObject::absoluteBoundingBoxRect): Helper for paintingRootRect
            (RenderObject::addAbsoluteRectForLayer):  Helper for paintingRootRect
            (RenderObject::paintingRootRect):  Return rect that will be painted if we are
    	the painting root.
            (RenderObject::draggableNode):  Add test to avoid rare NULL ptr crash.
            * khtml/rendering/render_object.h:
            (khtml::RenderObject::PaintInfo::PaintInfo):  Add paintingRoot field.
            (khtml::RenderObject::paintingRootForChildren):  New utility.  Return the current
    	paintingRoot, or nil if we are the root (so kids draw normally).
            (khtml::RenderObject::shouldPaintWithinRoot):  New utility.  We can paint if we
    	are the paintingRoot, or no root is set.
            * khtml/rendering/render_replaced.cpp:
            (RenderReplaced::shouldPaint):  Pass along paintingRoot to kids.
            * khtml/rendering/render_table.cpp:
            (RenderTable::paint):   Pass along paintingRoot to kids.
            * khtml/rendering/render_text.cpp:
            (RenderText::paint):  Test paintingRoot before painting.
            * kwq/KWQKHTMLPart.h:
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::KWQKHTMLPart):  Init new _elementToDraw member.
            (KWQKHTMLPart::paint):  Generalized to handle cases of painting selection or a
    	given element.
            (KWQKHTMLPart::khtmlMouseMoveEvent):  Make a default image if dragSrc didn't
    	provide one.
            (KWQKHTMLPart::selectionRect):  Moved from bridge.
            (KWQKHTMLPart::visibleSelectionRect):  Ditto.
            (KWQKHTMLPart::imageFromRect):  Newly factored code, from bridge.
            (KWQKHTMLPart::selectionImage):  Moved from bridge, wrapper around imageFromRect.
            (KWQKHTMLPart::elementImage):  New method, wrapper around imageFromRect.
            * kwq/WebCoreBridge.h:
            * kwq/WebCoreBridge.mm:
            (-[WebCoreBridge drawRect:withPainter:]):  Just call part to draw.
            (-[WebCoreBridge visibleSelectionRect]):  Guts moved to part.
            (-[WebCoreBridge selectionImage]):  Ditto.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6789 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 469718e..6a744d3 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,72 @@
+2004-06-07  Trey Matteson  <trey at apple.com>
+
+	WebCore will now generate a default drag image when an element serves as a drag
+	source.  The basic idea is the image contains the element and all its children.
+
+	As for the implementation, instead of adding a new paintAction I added a new
+	field to the paintInfo struct, "paintingRoot".  If this field is set, painting will
+	only paint that root's descendants.
+
+	Some code also moved from the bridge to the part, to be available within WebCore.
+
+        Reviewed by hyatt.
+
+        * khtml/rendering/render_block.cpp:
+        (khtml::RenderBlock::paintObject):  Pass along paintingRoot to kids.
+        (khtml::RenderBlock::paintFloats):  Pass along paintingRoot to kids.
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::paintBoxDecorations):  Test paintingRoot before painting.
+        * khtml/rendering/render_canvasimage.cpp:
+        (RenderCanvasImage::paint):    Test paintingRoot before painting.
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::paintLineBoxBackgroundBorder):    Test paintingRoot before painting.
+        (RenderFlow::paintLineBoxDecorations):    Test paintingRoot before painting.
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::paint):    Test paintingRoot before painting.
+        * khtml/rendering/render_inline.cpp:
+        (RenderInline::paint):    Pass along paintingRoot to kids.
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::paint):   Pass along paintingRoot to kids.
+        (RenderLayer:: paintLayer):  Pass along paintingRoot to kids.  Test if we are within the
+	paintingRoot to decide whether to pass the root to our renderer.
+        * khtml/rendering/render_layer.h:
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::hasAncestor):  New utility.
+        (RenderObject::absoluteBoundingBoxRect): Helper for paintingRootRect
+        (RenderObject::addAbsoluteRectForLayer):  Helper for paintingRootRect
+        (RenderObject::paintingRootRect):  Return rect that will be painted if we are
+	the painting root.
+        (RenderObject::draggableNode):  Add test to avoid rare NULL ptr crash.
+        * khtml/rendering/render_object.h:
+        (khtml::RenderObject::PaintInfo::PaintInfo):  Add paintingRoot field.
+        (khtml::RenderObject::paintingRootForChildren):  New utility.  Return the current
+	paintingRoot, or nil if we are the root (so kids draw normally).
+        (khtml::RenderObject::shouldPaintWithinRoot):  New utility.  We can paint if we
+	are the paintingRoot, or no root is set.
+        * khtml/rendering/render_replaced.cpp:
+        (RenderReplaced::shouldPaint):  Pass along paintingRoot to kids.
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::paint):   Pass along paintingRoot to kids.
+        * khtml/rendering/render_text.cpp:
+        (RenderText::paint):  Test paintingRoot before painting.
+        * kwq/KWQKHTMLPart.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::KWQKHTMLPart):  Init new _elementToDraw member.
+        (KWQKHTMLPart::paint):  Generalized to handle cases of painting selection or a
+	given element.
+        (KWQKHTMLPart::khtmlMouseMoveEvent):  Make a default image if dragSrc didn't
+	provide one.
+        (KWQKHTMLPart::selectionRect):  Moved from bridge.
+        (KWQKHTMLPart::visibleSelectionRect):  Ditto.
+        (KWQKHTMLPart::imageFromRect):  Newly factored code, from bridge.
+        (KWQKHTMLPart::selectionImage):  Moved from bridge, wrapper around imageFromRect.
+        (KWQKHTMLPart::elementImage):  New method, wrapper around imageFromRect.
+        * kwq/WebCoreBridge.h:
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge drawRect:withPainter:]):  Just call part to draw.
+        (-[WebCoreBridge visibleSelectionRect]):  Guts moved to part.
+        (-[WebCoreBridge selectionImage]):  Ditto.
+
 2004-06-07  Darin Adler  <darin at apple.com>
 
         Reviewed by Chris.
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index a52b6a2..7416319 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -1257,7 +1257,7 @@ void RenderBlock::paintObject(PaintInfo& i, int _tx, int _ty)
     // We don't paint our own background, but we do let the kids paint their backgrounds.
     if (paintAction == PaintActionChildBackgrounds)
         paintAction = PaintActionChildBackground;
-    PaintInfo paintInfo(i.p, i.r, paintAction);
+    PaintInfo paintInfo(i.p, i.r, paintAction, paintingRootForChildren(i));
     
     paintLineBoxBackgroundBorder(paintInfo, _tx, _ty);
 
@@ -1338,7 +1338,7 @@ void RenderBlock::paintFloats(PaintInfo& i, int _tx, int _ty, bool paintSelectio
     for ( ; (r = it.current()); ++it) {
         // Only paint the object if our noPaint flag isn't set.
         if (!r->noPaint && !r->node->layer()) {
-            PaintInfo info(i.p, i.r, paintSelection ? PaintActionSelection : PaintActionElementBackground);
+            PaintInfo info(i.p, i.r, paintSelection ? PaintActionSelection : PaintActionElementBackground, i.paintingRoot);
             int tx = _tx + r->left - r->node->xPos() + r->node->marginLeft();
             int ty = _ty + r->startY - r->node->yPos() + r->node->marginTop();
             r->node->paint(info, tx, ty);
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index 964055f..f57718a 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -280,6 +280,9 @@ void RenderBox::paintRootBoxDecorations(PaintInfo& i, int _tx, int _ty)
 
 void RenderBox::paintBoxDecorations(PaintInfo& i, int _tx, int _ty)
 {
+    if (!shouldPaintWithinRoot(i))
+        return;
+
     //kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl;
     if (isRoot())
         return paintRootBoxDecorations(i, _tx, _ty);
diff --git a/WebCore/khtml/rendering/render_canvasimage.cpp b/WebCore/khtml/rendering/render_canvasimage.cpp
index 6866bbb..797a327 100644
--- a/WebCore/khtml/rendering/render_canvasimage.cpp
+++ b/WebCore/khtml/rendering/render_canvasimage.cpp
@@ -159,6 +159,9 @@ void RenderCanvasImage::paint(PaintInfo& i, int _tx, int _ty)
     if (i.phase != PaintActionForeground && i.phase != PaintActionSelection)
         return;
 
+    if (!shouldPaintWithinRoot(i))
+        return;
+
     bool drawSelectionTint = selectionState() != SelectionNone;
     if (i.phase == PaintActionSelection) {
         if (selectionState() == SelectionNone) {
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index 317466e..eee92be 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -309,6 +309,9 @@ InlineBox* RenderFlow::createInlineBox(bool makePlaceHolderBox, bool isRootLineB
 
 void RenderFlow::paintLineBoxBackgroundBorder(PaintInfo& i, int _tx, int _ty)
 {
+    if (!shouldPaintWithinRoot(i))
+        return;
+
     if (!firstLineBox())
         return;
  
@@ -336,6 +339,9 @@ void RenderFlow::paintLineBoxBackgroundBorder(PaintInfo& i, int _tx, int _ty)
 
 void RenderFlow::paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty, bool paintedChildren)
 {
+    if (!shouldPaintWithinRoot(i))
+        return;
+
     // We only paint line box decorations in strict or almost strict mode.
     // Otherwise we let the InlineTextBoxes paint their own decorations.
     if (style()->htmlHacks() || !firstLineBox())
diff --git a/WebCore/khtml/rendering/render_image.cpp b/WebCore/khtml/rendering/render_image.cpp
index c757c78..b3e5e1d 100644
--- a/WebCore/khtml/rendering/render_image.cpp
+++ b/WebCore/khtml/rendering/render_image.cpp
@@ -238,6 +238,9 @@ void RenderImage::paint(PaintInfo& i, int _tx, int _ty)
     if (i.phase != PaintActionForeground && i.phase != PaintActionSelection)
         return;
 
+    if (!shouldPaintWithinRoot(i))
+        return;
+        
 #if APPLE_CHANGES
     bool drawSelectionTint = selectionState() != SelectionNone;
     if (i.phase == PaintActionSelection) {
diff --git a/WebCore/khtml/rendering/render_inline.cpp b/WebCore/khtml/rendering/render_inline.cpp
index 1e3a1a0..69fe29a 100644
--- a/WebCore/khtml/rendering/render_inline.cpp
+++ b/WebCore/khtml/rendering/render_inline.cpp
@@ -267,7 +267,7 @@ void RenderInline::paint(PaintInfo& i, int _tx, int _ty)
         return;
     
     // We don't paint our own background, but we do let the kids paint their backgrounds.
-    PaintInfo paintInfo(i.p, i.r, i.phase);
+    PaintInfo paintInfo(i.p, i.r, i.phase, paintingRootForChildren(i));
     if (i.phase == PaintActionChildBackgrounds)
         paintInfo.phase = PaintActionChildBackground;
 
diff --git a/WebCore/khtml/rendering/render_layer.cpp b/WebCore/khtml/rendering/render_layer.cpp
index 39279d9..6cd406b 100644
--- a/WebCore/khtml/rendering/render_layer.cpp
+++ b/WebCore/khtml/rendering/render_layer.cpp
@@ -703,9 +703,9 @@ RenderLayer::paintScrollbars(QPainter* p, const QRect& damageRect)
 #endif
 
 void
-RenderLayer::paint(QPainter *p, const QRect& damageRect, bool selectionOnly)
+RenderLayer::paint(QPainter *p, const QRect& damageRect, bool selectionOnly, RenderObject *paintingRoot)
 {
-    paintLayer(this, p, damageRect, false, selectionOnly);
+    paintLayer(this, p, damageRect, false, selectionOnly, paintingRoot);
 }
 
 static void setClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
@@ -737,7 +737,8 @@ static void restoreClip(QPainter* p, const QRect& paintDirtyRect, const QRect& c
 
 void
 RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
-                        const QRect& paintDirtyRect, bool haveTransparency, bool selectionOnly)
+                        const QRect& paintDirtyRect, bool haveTransparency, bool selectionOnly,
+                        RenderObject *paintingRoot)
 {
     // Calculate the clip rects we should use.
     QRect layerBounds, damageRect, clipRectToApply;
@@ -753,6 +754,15 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
         haveTransparency = true;
 #endif
 
+    // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
+    // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
+    // Else, our renderer tree may or may not contain the painting root, so we pass that root along
+    // so it will be tested against as we decend through the renderers.
+    RenderObject *paintingRootForRenderer = 0;
+    if (paintingRoot && !m_object->hasAncestor(paintingRoot)) {
+        paintingRootForRenderer = paintingRoot;
+    }
+    
     // We want to paint our layer, but only if we intersect the damage rect.
     bool shouldPaint = intersectsDamageRect(layerBounds, damageRect);
     if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
@@ -767,7 +777,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
         setClip(p, paintDirtyRect, damageRect);
 
         // Paint the background.
-        RenderObject::PaintInfo info = RenderObject::PaintInfo(p, damageRect, PaintActionElementBackground);
+        RenderObject::PaintInfo info(p, damageRect, PaintActionElementBackground, paintingRootForRenderer);
         renderer()->paint(info, x - renderer()->xPos(), y - renderer()->yPos());        
 #if APPLE_CHANGES
         // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
@@ -784,7 +794,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
         uint count = m_negZOrderList->count();
         for (uint i = 0; i < count; i++) {
             RenderLayer* child = m_negZOrderList->at(i);
-            child->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, selectionOnly);
+            child->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, selectionOnly, paintingRoot);
         }
     }
     
@@ -802,7 +812,8 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
         int tx = x - renderer()->xPos();
         int ty = y - renderer()->yPos();
         RenderObject::PaintInfo info(p, clipRectToApply, 
-                                     selectionOnly ? PaintActionSelection : PaintActionChildBackgrounds);
+                                     selectionOnly ? PaintActionSelection : PaintActionChildBackgrounds,
+                                     paintingRootForRenderer);
         renderer()->paint(info, tx, ty);
         if (!selectionOnly) {
             info.phase = PaintActionFloat;
@@ -822,7 +833,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
         uint count = m_posZOrderList->count();
         for (uint i = 0; i < count; i++) {
             RenderLayer* child = m_posZOrderList->at(i);
-            child->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, selectionOnly);
+            child->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, selectionOnly, paintingRoot);
         }
     }
     
diff --git a/WebCore/khtml/rendering/render_layer.h b/WebCore/khtml/rendering/render_layer.h
index df40d29..2d50bc6 100644
--- a/WebCore/khtml/rendering/render_layer.h
+++ b/WebCore/khtml/rendering/render_layer.h
@@ -232,7 +232,7 @@ public:
     // paints the layers that intersect the damage rect from back to
     // front.  The nodeAtPoint method looks for mouse events by walking
     // layers that intersect the point from front to back.
-    void paint(QPainter *p, const QRect& damageRect, bool selectionOnly=false);
+    void paint(QPainter *p, const QRect& damageRect, bool selectionOnly=false, RenderObject *paintingRoot=0);
     bool nodeAtPoint(RenderObject::NodeInfo& info, int x, int y);
 
     // This method figures out our layerBounds in coordinates relative to
@@ -273,7 +273,7 @@ private:
     void collectLayers(QPtrVector<RenderLayer>*&, QPtrVector<RenderLayer>*&);
 
     void paintLayer(RenderLayer* rootLayer, QPainter *p, const QRect& paintDirtyRect, 
-                    bool haveTransparency=false, bool selectionOnly=false);
+                    bool haveTransparency, bool selectionOnly, RenderObject *paintingRoot);
     RenderLayer* nodeAtPointForLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
                                      int x, int y, const QRect& hitTestRect);
 
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 88d1b35..65816a5 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -158,6 +158,14 @@ RenderObject::~RenderObject()
 {
 }
 
+bool RenderObject::hasAncestor(const RenderObject *obj) const
+{
+    for (const RenderObject *r = this; r; r = r->m_parent)
+        if (r == obj)
+            return true;
+    return false;
+}
+
 bool RenderObject::isRoot() const
 {
     return element() && element()->renderer() == this &&
@@ -1061,6 +1069,40 @@ void RenderObject::absoluteRects(QValueList<QRect>& rects, int _tx, int _ty)
         rects.append(QRect(_tx, _ty, width(), height()));
 }
 
+QRect RenderObject::absoluteBoundingBoxRect()
+{
+    int x, y;
+    absolutePosition(x, y);
+    QValueList<QRect> rects;
+    absoluteRects(rects, x, y);
+    
+    QValueList<QRect>::ConstIterator it = rects.begin();
+    QRect result = *it;
+    while (++it != rects.end()) {
+        result = result.unite(*it);
+    }
+    return result;
+}
+
+void RenderObject::addAbsoluteRectForLayer(QRect& result)
+{
+    if (layer()) {
+        result = result.unite(absoluteBoundingBoxRect());
+    }
+    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
+        current->addAbsoluteRectForLayer(result);
+    }
+}
+
+QRect RenderObject::paintingRootRect()
+{
+    QRect result = absoluteBoundingBoxRect();
+    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
+        current->addAbsoluteRectForLayer(result);
+    }
+    return result;
+}
+
 #if APPLE_CHANGES
 void RenderObject::addFocusRingRects(QPainter *p, int _tx, int _ty)
 {
@@ -1338,7 +1380,8 @@ DOM::NodeImpl* RenderObject::draggableNode() const
 {
     const RenderObject* curr = this;
     while (curr) {
-        if (curr->element()->nodeType() == Node::TEXT_NODE) {
+        DOM::NodeImpl *elt = curr->element();
+        if (elt && elt->nodeType() == Node::TEXT_NODE) {
             // Since there's no way for the author to address the -khtml-user-drag style for a text node,
             // we use our own judgement.
             if (canvas()->view()->part()->shouldDragAutoNode(curr->node()))
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index da8afef..446fa1e 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -114,6 +114,7 @@ public:
     virtual ~RenderObject();
 
     RenderObject *parent() const { return m_parent; }
+    bool hasAncestor(const RenderObject *obj) const;
 
     RenderObject *previousSibling() const { return m_previous; }
     RenderObject *nextSibling() const { return m_next; }
@@ -187,6 +188,9 @@ private:
     void setNextSibling(RenderObject *next) { m_next = next; }
     void setParent(RenderObject *parent) { m_parent = parent; }
     //////////////////////////////////////////
+    
+    QRect absoluteBoundingBoxRect();
+    void addAbsoluteRectForLayer(QRect& result);
 
 public:
     virtual const char *renderName() const { return "RenderObject"; }
@@ -356,11 +360,12 @@ public:
      * (tx|ty) is the calculated position of the parent
      */
     struct PaintInfo {
-        PaintInfo(QPainter* _p, const QRect& _r, PaintAction _phase)
-        : p(_p), r(_r), phase(_phase) {}
+        PaintInfo(QPainter* _p, const QRect& _r, PaintAction _phase, RenderObject *_paintingRoot)
+        : p(_p), r(_r), phase(_phase), paintingRoot(_paintingRoot) {}
         QPainter* p;
         QRect     r;
         PaintAction phase;
+        RenderObject *paintingRoot;      // used to draw just one element and its visual kids
     };
     virtual void paint(PaintInfo& i, int tx, int ty);
     void paintBorder(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style, bool begin=true, bool end=true);
@@ -602,6 +607,9 @@ public:
 
     virtual void absoluteRects(QValueList<QRect>& rects, int _tx, int _ty);
 
+    // the rect that will be painted if this object is passed as the paintingRoot
+    QRect paintingRootRect();
+
 #if APPLE_CHANGES
     virtual void addFocusRingRects(QPainter *painter, int _tx, int _ty);
 #endif
@@ -754,6 +762,14 @@ protected:
     
     void arenaDelete(RenderArena *arena);
 
+    RenderObject *paintingRootForChildren(PaintInfo &i) const {
+        // if we're the painting root, kids draw normally, and see root of 0
+        return (!i.paintingRoot || i.paintingRoot == this) ? 0 : i.paintingRoot;
+    }
+    bool shouldPaintWithinRoot(PaintInfo &i) const {
+        return !i.paintingRoot || i.paintingRoot == this;
+    }
+
 private:
     RenderStyle* m_style;
 
diff --git a/WebCore/khtml/rendering/render_replaced.cpp b/WebCore/khtml/rendering/render_replaced.cpp
index 4e3e8c8..39a444e 100644
--- a/WebCore/khtml/rendering/render_replaced.cpp
+++ b/WebCore/khtml/rendering/render_replaced.cpp
@@ -59,6 +59,9 @@ bool RenderReplaced::shouldPaint(PaintInfo& i, int& _tx, int& _ty)
 {
     if (i.phase != PaintActionForeground && i.phase != PaintActionOutline && i.phase != PaintActionSelection)
         return false;
+
+    if (!shouldPaintWithinRoot(i))
+        return false;
         
     // if we're invisible or haven't received a layout yet, then just bail.
     if (style()->visibility() != VISIBLE || m_y <=  -500000)  return false;
diff --git a/WebCore/khtml/rendering/render_table.cpp b/WebCore/khtml/rendering/render_table.cpp
index 618d765..0cbf9ad 100644
--- a/WebCore/khtml/rendering/render_table.cpp
+++ b/WebCore/khtml/rendering/render_table.cpp
@@ -425,7 +425,7 @@ void RenderTable::paint(PaintInfo& i, int _tx, int _ty)
     // We don't paint our own background, but we do let the kids paint their backgrounds.
     if (paintAction == PaintActionChildBackgrounds)
         paintAction = PaintActionChildBackground;
-    PaintInfo paintInfo(i.p, i.r, paintAction);
+    PaintInfo paintInfo(i.p, i.r, paintAction, paintingRootForChildren(i));
     
     for (RenderObject *child = firstChild(); child; child = child->nextSibling())
         if (child->isTableSection() || child == tCaption)
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index fcb9e76..477b0a6 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -611,6 +611,9 @@ void RenderText::paint(PaintInfo& i, int tx, int ty)
     if (i.phase != PaintActionForeground && i.phase != PaintActionSelection)
         return;
     
+    if (!shouldPaintWithinRoot(i))
+        return;
+        
     if (style()->visibility() != VISIBLE || !firstTextBox())
         return;
     
diff --git a/WebCore/kwq/KWQKHTMLPart.h b/WebCore/kwq/KWQKHTMLPart.h
index b0ebebb..2cf1305 100644
--- a/WebCore/kwq/KWQKHTMLPart.h
+++ b/WebCore/kwq/KWQKHTMLPart.h
@@ -189,7 +189,6 @@ public:
     void sendResizeEvent();
     void sendScrollEvent();
     void paint(QPainter *, const QRect &);
-    void paintSelectionOnly(QPainter *p, const QRect &rect);
 
     void adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit);
 
@@ -210,7 +209,10 @@ public:
     int selectionEndOffset() const;
 
     QRect selectionRect() const;
-    
+    NSRect visibleSelectionRect() const;
+    NSImage *selectionImage() const;
+    NSImage *elementImage(DOM::Node node, NSRect *imageRect) const;
+
     NSFont *fontForCurrentPosition() const;
 
     NSFileWrapper *fileWrapperForElement(DOM::ElementImpl *);
@@ -329,6 +331,8 @@ private:
     bool dragHysteresisExceeded(float dragLocationX, float dragLocationY) const;
     bool dispatchDragSrcEvent(int eventId, const QPoint &loc, bool declareTypes, NSImage **dragImage, NSPoint *dragLoc, unsigned *op) const;
 
+    NSImage *KWQKHTMLPart::imageFromRect(NSRect rect) const;
+
     WebCoreBridge *_bridge;
     
     KWQSignal _started;
@@ -357,7 +361,8 @@ private:
 
     bool _usesInactiveTextBackgroundColor;
     bool _showsFirstResponder;
-
+    mutable bool _drawSelectionOnly;
+    
     QDict<char> urlsBridgeKnowsAbout;
 
     friend class KHTMLPart;
@@ -371,6 +376,8 @@ private:
     bool _dragSrcIsLink;
     bool _dragSrcIsImage;
     bool _dragSrcInSelection;
+    
+    mutable DOM::Node _elementToDraw;
 };
 
 inline KWQKHTMLPart *KWQ(KHTMLPart *part) { return static_cast<KWQKHTMLPart *>(part); }
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index 0bbd128..0129070 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -181,9 +181,11 @@ KWQKHTMLPart::KWQKHTMLPart()
     , _windowWidget(NULL)
     , _usesInactiveTextBackgroundColor(false)
     , _showsFirstResponder(true)
+    , _drawSelectionOnly(false)
     , _bindingRoot(0)
     , _windowScriptObject(0)
     , _dragSrc(0)
+    , _elementToDraw(0)
 {
     // Must init the cache before connecting to any signals
     Cache::init();
@@ -895,6 +897,10 @@ void KWQKHTMLPart::paint(QPainter *p, const QRect &rect)
         fillWithRed = false; // Subframe, don't fill with red.
     else if (view() && view()->isTransparent())
         fillWithRed = false; // Transparent, don't fill with red.
+    else if (_drawSelectionOnly)
+        fillWithRed = false; // Selections are transparent, don't fill with red.
+    else if (_elementToDraw != 0)
+        fillWithRed = false; // Element images are transparent, don't fill with red.
     else
         fillWithRed = true;
 
@@ -904,21 +910,14 @@ void KWQKHTMLPart::paint(QPainter *p, const QRect &rect)
 #endif
 
     if (renderer()) {
-        renderer()->layer()->paint(p, rect);
+        // _elementToDraw is used to draw only one element
+        RenderObject *eltRenderer = (_elementToDraw != 0) ? _elementToDraw.handle()->renderer() : 0;
+        renderer()->layer()->paint(p, rect, _drawSelectionOnly, eltRenderer);
     } else {
         ERROR("called KWQKHTMLPart::paint with nil renderer");
     }
 }
 
-void KWQKHTMLPart::paintSelectionOnly(QPainter *p, const QRect &rect)
-{
-    if (renderer()) {
-        renderer()->layer()->paint(p, rect, true);
-    } else {
-        ERROR("called KWQKHTMLPart::paintSelectionOnly with nil renderer");
-    }
-}
-
 void KWQKHTMLPart::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
 {
     RenderCanvas *root = static_cast<RenderCanvas *>(xmlDocImpl()->renderer());
@@ -1985,6 +1984,14 @@ void KWQKHTMLPart::khtmlMouseMoveEvent(MouseMoveEvent *event)
                 NSPoint dragLoc = NSZeroPoint;
                 NSDragOperation srcOp = NSDragOperationNone;
                 if (dispatchDragSrcEvent(EventImpl::DRAGSTART_EVENT, QPoint(dragLocation), true, &dragImage, &dragLoc, &srcOp)) {
+                    if (!dragImage && !_dragSrcIsLink && !_dragSrcIsImage && !_dragSrcInSelection) {
+                        // Element accepted, but didn't supply an image, and WebKit won't be making one
+                        // either - so we make a default one
+                        NSRect imageRect;
+                        dragImage = elementImage(_dragSrc, &imageRect);
+                        dragLoc.x = _mouseDownX - imageRect.origin.x;
+                        dragLoc.y = imageRect.size.height - (_mouseDownY - imageRect.origin.y);
+                    }
                     if ([_bridge startDraggingImage:dragImage at:dragLoc operation:srcOp event:_currentEvent]) {
                         // Prevent click handling from taking place once we start dragging.
                         d->m_view->invalidateClick();
@@ -2900,6 +2907,72 @@ QRect KWQKHTMLPart::selectionRect() const
     return root->selectionRect();
 }
 
+// returns NSRect because going through QRect would truncate any floats
+NSRect KWQKHTMLPart::visibleSelectionRect() const
+{
+    if (!d->m_view) {
+        return NSZeroRect;
+    }
+    NSView *documentView = d->m_view->getDocumentView();
+    if (!documentView) {
+        return NSZeroRect;
+    }
+    return NSIntersectionRect(selectionRect(), [documentView visibleRect]);     
+}
+
+NSImage *KWQKHTMLPart::imageFromRect(NSRect rect) const
+{
+    NSView *view = d->m_view->getDocumentView();
+    if (!view) {
+        return nil;
+    }
+    
+    NSImage *resultImage = nil;
+    
+    KWQ_BLOCK_EXCEPTIONS;
+    
+    NSRect bounds = [view bounds];
+    resultImage = [[[NSImage alloc] initWithSize:rect.size] autorelease];
+    [resultImage setFlipped:YES];
+    [resultImage lockFocus];
+    
+    [NSGraphicsContext saveGraphicsState];
+    CGContextTranslateCTM((CGContext *)[[NSGraphicsContext currentContext] graphicsPort],
+                          -(NSMinX(rect) - NSMinX(bounds)), -(NSMinY(rect) - NSMinY(bounds)));
+    [view drawRect:rect];
+    [NSGraphicsContext restoreGraphicsState];
+    
+    [resultImage unlockFocus];
+    [resultImage setFlipped:NO];
+    
+    KWQ_UNBLOCK_EXCEPTIONS;
+    
+    return resultImage;
+}
+
+NSImage *KWQKHTMLPart::selectionImage() const
+{
+    _drawSelectionOnly = true;  // invoke special drawing mode
+    NSImage *result = imageFromRect(visibleSelectionRect());
+    _drawSelectionOnly = false;
+    return result;
+}
+
+NSImage *KWQKHTMLPart::elementImage(DOM::Node node, NSRect *imageRect) const
+{
+    RenderObject *renderer = node.handle()->renderer();
+    if (!renderer) {
+        return nil;
+    }
+    
+    *imageRect = renderer->paintingRootRect();
+    _elementToDraw = node;  // invoke special drawing mode
+    NSImage *result = imageFromRect(*imageRect);
+    _elementToDraw = 0;
+
+    return result;
+}
+
 NSFont *KWQKHTMLPart::fontForCurrentPosition() const
 {
     if (d->m_selection.state() == Selection::NONE)
diff --git a/WebCore/kwq/WebCoreBridge.h b/WebCore/kwq/WebCoreBridge.h
index 9cc8b42..2fed699 100644
--- a/WebCore/kwq/WebCoreBridge.h
+++ b/WebCore/kwq/WebCoreBridge.h
@@ -123,7 +123,6 @@ typedef enum {
     KWQKHTMLPart *_part;
     KHTMLRenderPart *_renderPart;
     RenderArena *_renderPartArena;
-    BOOL _drawSelectionOnly;
     BOOL _shouldCreateRenderers;
 }
 
diff --git a/WebCore/kwq/WebCoreBridge.mm b/WebCore/kwq/WebCoreBridge.mm
index c1347ff..465f638 100644
--- a/WebCore/kwq/WebCoreBridge.mm
+++ b/WebCore/kwq/WebCoreBridge.mm
@@ -605,11 +605,7 @@ static BOOL nowPrinting(WebCoreBridge *self)
 - (void)drawRect:(NSRect)rect withPainter:(QPainter *)p
 {
     [self _setupRootForPrinting:YES];
-    if (_drawSelectionOnly) {
-        _part->paintSelectionOnly(p, QRect(rect));
-    } else {
-        _part->paint(p, QRect(rect));
-    }
+    _part->paint(p, QRect(rect));
     [self _setupRootForPrinting:NO];
 }
 
@@ -1147,44 +1143,12 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 
 - (NSRect)visibleSelectionRect
 {
-    KHTMLView *view = _part->view();
-    if (!view) {
-        return NSZeroRect;
-    }
-    NSView *documentView = view->getDocumentView();
-    if (!documentView) {
-        return NSZeroRect;
-    }
-    return NSIntersectionRect(_part->selectionRect(), [documentView visibleRect]); 
+    return _part->visibleSelectionRect(); 
 }
 
 - (NSImage *)selectionImage
 {
-    NSView *view = _part->view()->getDocumentView();
-    if (!view) {
-        return nil;
-    }
-
-    NSRect rect = [self visibleSelectionRect];
-    NSRect bounds = [view bounds];
-    NSImage *selectionImage = [[[NSImage alloc] initWithSize:rect.size] autorelease];
-    [selectionImage setFlipped:YES];
-    [selectionImage lockFocus];
-
-    [NSGraphicsContext saveGraphicsState];
-    CGContextTranslateCTM((CGContext *)[[NSGraphicsContext currentContext] graphicsPort],
-                          -(NSMinX(rect) - NSMinX(bounds)), -(NSMinY(rect) - NSMinY(bounds)));
-
-    _drawSelectionOnly = YES;
-    [view drawRect:rect];
-    _drawSelectionOnly = NO;
-
-    [NSGraphicsContext restoreGraphicsState];
-        
-    [selectionImage unlockFocus];
-    [selectionImage setFlipped:NO];
-
-    return selectionImage;
+    return _part->selectionImage();
 }
 
 - (void)setName:(NSString *)name
@@ -1600,7 +1564,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
             clipboard->ref();
             NSDragOperation srcOp = [info draggingSourceOperationMask];
             clipboard->setSourceOperation(srcOp);
-            
+
             if (v->updateDragAndDrop(QPoint([info draggingLocation]), clipboard)) {
                 // *op unchanged if no source op was set
                 if (!clipboard->destinationOperation(&op)) {
@@ -1621,7 +1585,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
                     op = NSDragOperationNone;
                 }
             }
-            
+
             clipboard->deref();
             v->deref();
             return op;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list