[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

mitz at apple.com mitz at apple.com
Fri Feb 26 22:20:15 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 4e3905b048a975f919efac3ac3105c9a878e1466
Author: mitz at apple.com <mitz at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Feb 15 19:48:38 2010 +0000

    <rdar://problem/7647300> Incorrect client rects for blocks the span multiple columns and their descendants
    https://bugs.webkit.org/show_bug.cgi?id=34923
    
    Reviewed by Simon Fraser.
    
    WebCore:
    
    Test: fast/multicol/client-rects.html
    
    In column layout, a different transform applies to different points in
    the block and its descendants, depending on their y coordinate within the
    block. offsetFromContainer() used to return the offset that applied to
    the origin. With this change, it returns the offset that applies to a
    given reference point. When mapping a quad from local to absolute
    coordinates, the top left of the quad’s bounding box is used as that
    reference point.
    
    * editing/SelectionController.cpp:
    (WebCore::SelectionController::layout): Pass the caret’s origin as the
    reference point to offsetFromContainer().
    * rendering/RenderBlock.cpp:
    (WebCore::RenderBlock::adjustForColumns): Adds the offset between the
    given point and its image under the column paint-time transform to the
    given offset. Used by offsetFromContainer() where it had previously used
    adjustRectForColumns(), which takes a rect and operates less efficiently.
    * rendering/RenderBlock.h:
    * rendering/RenderBox.cpp:
    (WebCore::RenderBox::mapLocalToContainer): Pass the transformed point as
    the reference point to offsetFromContainer().
    (WebCore::RenderBox::mapAbsoluteToLocalPoint): Pass a point to
    offsetFromContainer().
    (WebCore::RenderBox::offsetFromContainer): Use adjustForColumns() instead
    of adjustRectForColumns(), and use the reference point to get the right
    adjustment for the point of interest, instead of the origin, in case this
    box spans multiple columns.
    * rendering/RenderBox.h:
    * rendering/RenderInline.cpp:
    (WebCore::RenderInline::offsetFromContainer): Ditto. Actually apply the
    column offset to the computation, which previously this function didn’t
    do.
    (WebCore::RenderInline::mapLocalToContainer): Pass the transformed point
    as the reference point to offsetFromContainer().
    (WebCore::RenderInline::mapAbsoluteToLocalPoint): Pass a point to
    offsetFromContainer().
    * rendering/RenderInline.h:
    * rendering/RenderObject.cpp:
    (WebCore::RenderObject::mapLocalToContainer): Apply column adjustment,
    based on the reference point, to the transform if needed.
    (WebCore::RenderObject::localToContainerQuad): Initialize the
    TransformState with the top left corner of the quad’s bounding box. It
    is later used as the reference point when deciding on which column to
    base the calculations.
    (WebCore::RenderObject::offsetFromContainer): Adjust for columns.
    (WebCore::RenderObject::offsetFromAncestorContainer): Pass the origin
    as the reference point to offsetFromContainer().
    * rendering/RenderObject.h:
    (WebCore::RenderObject::adjustForColumns): Added.
    * rendering/RenderTableCell.cpp:
    (WebCore::RenderTableCell::offsetFromContainer): Pass the reference
    point through.
    * rendering/RenderTableCell.h:
    * rendering/RenderText.cpp:
    (WebCore::RenderText::absoluteRectsForRange): Map (the origin of) each
    rect to absolute coordinates individually.
    * rendering/RenderThemeMac.mm:
    (WebCore::RenderThemeMac::convertToPaintingRect): Pass a point to
    offsetFromContainer().
    
    LayoutTests:
    
    * fast/multicol/client-rects-expected.checksum: Added.
    * fast/multicol/client-rects-expected.png: Added.
    * fast/multicol/client-rects-expected.txt: Added.
    * fast/multicol/client-rects.html: Added.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54784 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index b21ce22..b96db8a 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-02-15  Dan Bernstein  <mitz at apple.com>
+
+        Reviewed by Simon Fraser.
+
+        <rdar://problem/7647300> Incorrect client rects for blocks the span multiple columns and their descendants
+        https://bugs.webkit.org/show_bug.cgi?id=34923
+
+        * fast/multicol/client-rects-expected.checksum: Added.
+        * fast/multicol/client-rects-expected.png: Added.
+        * fast/multicol/client-rects-expected.txt: Added.
+        * fast/multicol/client-rects.html: Added.
+
 2010-02-12  Alexey Proskuryakov  <ap at apple.com>
 
         Reviewed by Kevin Decker.
diff --git a/LayoutTests/fast/multicol/client-rects-expected.checksum b/LayoutTests/fast/multicol/client-rects-expected.checksum
new file mode 100644
index 0000000..355c14e
--- /dev/null
+++ b/LayoutTests/fast/multicol/client-rects-expected.checksum
@@ -0,0 +1 @@
+515437ffe482058606a444eb132d1255
\ No newline at end of file
diff --git a/LayoutTests/fast/multicol/client-rects-expected.png b/LayoutTests/fast/multicol/client-rects-expected.png
new file mode 100644
index 0000000..61690e7
Binary files /dev/null and b/LayoutTests/fast/multicol/client-rects-expected.png differ
diff --git a/LayoutTests/fast/multicol/client-rects-expected.txt b/LayoutTests/fast/multicol/client-rects-expected.txt
new file mode 100644
index 0000000..0080231
--- /dev/null
+++ b/LayoutTests/fast/multicol/client-rects-expected.txt
@@ -0,0 +1,88 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x582
+      RenderBlock {P} at (0,0) size 784x29
+        RenderText {#text} at (0,11) size 421x18
+          text run at (0,11) width 421: "The blue borders should coincide with light blue squares, like this: "
+        RenderBlock {SPAN} at (421,0) size 25x25 [bgcolor=#ADD8E6] [border: (3px solid #0000FF7F)]
+        RenderText {#text} at (446,11) size 196x18
+          text run at (446,11) width 8: ". "
+          text run at (454,11) width 188: "There should be none of this: "
+        RenderBlock {SPAN} at (642,0) size 25x25 [bgcolor=#ADD8E6]
+        RenderText {#text} at (667,11) size 51x18
+          text run at (667,11) width 4: " "
+          text run at (671,11) width 47: "or this: "
+        RenderBlock {SPAN} at (718,0) size 25x25 [border: (3px solid #0000FF7F)]
+        RenderText {#text} at (743,11) size 4x18
+          text run at (743,11) width 4: "."
+      RenderBlock {DIV} at (0,45) size 136x76 [color=#ADD8E6] [border: (3px solid #000000)]
+        RenderBR {BR} at (13,13) size 0x25
+        RenderText {#text} at (13,38) size 25x75
+          text run at (13,38) width 25: "x"
+          text run at (13,63) width 25: "y"
+          text run at (13,88) width 25: "z"
+      RenderBlock {DIV} at (0,131) size 136x76 [color=#ADD8E6] [border: (3px solid #000000)]
+        RenderBR {BR} at (13,13) size 0x25
+        RenderInline {SPAN} at (0,0) size 25x75
+          RenderText {#text} at (13,38) size 25x75
+            text run at (13,38) width 25: "x"
+            text run at (13,63) width 25: "y"
+            text run at (13,88) width 25: "z"
+        RenderText {#text} at (0,0) size 0x0
+      RenderBlock {DIV} at (0,217) size 136x76 [color=#ADD8E6] [border: (3px solid #000000)]
+        RenderBlock (anonymous) at (13,13) size 50x25
+          RenderBR {BR} at (0,0) size 0x25
+        RenderBlock {DIV} at (13,38) size 50x75
+          RenderText {#text} at (0,0) size 25x75
+            text run at (0,0) width 25: "x"
+            text run at (0,25) width 25: "y"
+            text run at (0,50) width 25: "z"
+      RenderBlock {DIV} at (0,303) size 136x76 [color=#ADD8E6] [border: (3px solid #000000)]
+        RenderBlock (anonymous) at (13,13) size 50x25
+          RenderBR {BR} at (0,0) size 0x25
+        RenderBlock {DIV} at (13,38) size 50x75
+          RenderBR {BR} at (0,0) size 0x25
+          RenderText {#text} at (0,25) size 25x50
+            text run at (0,25) width 25: "y"
+            text run at (0,50) width 25: "z"
+      RenderBlock {DIV} at (0,389) size 136x76 [color=#ADD8E6] [border: (3px solid #000000)]
+        RenderBlock (anonymous) at (13,13) size 50x25
+          RenderBR {BR} at (0,0) size 0x25
+        RenderBlock {DIV} at (13,38) size 50x54
+          RenderBR {BR} at (0,0) size 0x25
+          RenderSlider {INPUT} at (2,27) size 25x25 [color=#000000] [bgcolor=#ADD8E6]
+            RenderBlock {DIV} at (12,12) size 0x0
+      RenderBlock {DIV} at (0,475) size 136x76 [color=#ADD8E6] [border: (3px solid #000000)]
+        RenderBlock (anonymous) at (13,13) size 50x25
+          RenderBR {BR} at (0,0) size 0x25
+        RenderBlock {DIV} at (13,38) size 50x50
+          RenderBR {BR} at (0,0) size 0x25
+          RenderImage {IMG} at (0,25) size 25x25 [bgcolor=#ADD8E6]
+layer at (21,91) size 25x25
+  RenderBlock (positioned) {DIV} at (21,91) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,66) size 25x25
+  RenderBlock (positioned) {DIV} at (81,66) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,91) size 25x25
+  RenderBlock (positioned) {DIV} at (81,91) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (21,177) size 25x25
+  RenderBlock (positioned) {DIV} at (21,177) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,152) size 25x25
+  RenderBlock (positioned) {DIV} at (81,152) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,177) size 25x25
+  RenderBlock (positioned) {DIV} at (81,177) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (21,263) size 25x25
+  RenderBlock (positioned) {DIV} at (21,263) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,238) size 25x25
+  RenderBlock (positioned) {DIV} at (81,238) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,263) size 25x25
+  RenderBlock (positioned) {DIV} at (81,263) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,324) size 25x25
+  RenderBlock (positioned) {DIV} at (81,324) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,349) size 25x25
+  RenderBlock (positioned) {DIV} at (81,349) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (83,412) size 25x25
+  RenderBlock (positioned) {DIV} at (83,412) size 25x25 [border: (3px solid #0000FF7F)]
+layer at (81,521) size 25x25
+  RenderBlock (positioned) {DIV} at (81,521) size 25x25 [border: (3px solid #0000FF7F)]
diff --git a/LayoutTests/fast/multicol/client-rects.html b/LayoutTests/fast/multicol/client-rects.html
new file mode 100644
index 0000000..70578ff
--- /dev/null
+++ b/LayoutTests/fast/multicol/client-rects.html
@@ -0,0 +1,113 @@
+<style>
+    div.columns {
+        height: 50px;
+        width: 110px;
+        margin: 10px 0;
+        padding: 10px;
+        border: solid black;
+        font-family: ahem;
+        font-size: 25px;
+        color: lightblue;
+        -webkit-columns: 2;
+        -webkit-column-gap: 10px;
+    }
+
+    div.marker {
+        position: absolute;
+        border: solid rgba(0, 0, 255, 0.5);
+        -webkit-box-sizing: border-box;
+    }
+
+    input[type="range"] {
+        -webkit-appearance: none;
+        width: 25px;
+        height: 25px;
+        background-color: lightblue;
+    }
+
+    input[type="range"]::-webkit-slider-thumb {
+        -webkit-appearance: none;
+    }
+</style>
+<p>
+    The blue borders should coincide with light blue squares, like this:
+    <span style="display: inline-block; background-color: lightblue; border: solid rgba(0, 0, 255, 0.5); width: 19px; height: 19px;"></span>.
+    There should be none of this:
+    <span style="display: inline-block; background-color: lightblue; width: 25px; height: 25px;"></span>
+    or this:
+    <span style="display: inline-block; border: solid rgba(0, 0, 255, 0.5); width: 19px; height: 19px;"></span>.
+</p>
+<div class="columns" id="t1">
+    <br>x y z
+</div>
+
+<div class="columns">
+    <br><span id="t2">x y z</span>
+</div>
+
+<div class="columns">
+    <br><div id="t3">x y z</div>
+</div>
+
+<div class="columns">
+    <br><div id="t4"><br>y z</div>
+</div>
+
+<div class="columns">
+    <br><div><br><input id="t5" type="range"></div>
+</div>
+
+<div class="columns">
+    <br><div><br><img id="t6" style="width: 25px; height: 25px; background-color: lightblue;"></div>
+</div>
+
+<script>
+    function placeMarker(clientRect)
+    {
+        var marker = document.body.appendChild(document.createElement("div"));
+        marker.className = "marker";
+        marker.style.left = clientRect.left + "px";
+        marker.style.top = clientRect.top + "px";
+        marker.style.width = clientRect.width + "px";
+        marker.style.height = clientRect.height + "px";
+    }
+
+    function placeMarkersForRange(range, startOffset)
+    {
+        if (startOffset === undefined)
+            startOffset = 0;
+
+        var clientRects = range.getClientRects();
+        for (var i = startOffset; i < clientRects.length; ++i)
+            placeMarker(clientRects[i]);
+    }
+
+    var range = document.createRange();
+
+    var textNode = document.getElementById("t1").firstChild.nextSibling.nextSibling;
+    range.setStart(textNode, 0);
+    range.setEnd(textNode, 5);
+    placeMarkersForRange(range);
+
+    textNode = document.getElementById("t2").firstChild;
+    range.setStart(textNode, 0);
+    range.setEnd(textNode, 5);
+    placeMarkersForRange(range);
+
+    textNode = document.getElementById("t3").firstChild;
+    range.setStart(textNode, 0);
+    range.setEnd(textNode, 5);
+    placeMarkersForRange(range);
+
+    var block = document.getElementById("t4");
+    range.selectNode(block);
+    placeMarkersForRange(range, 1);
+
+    var slider = document.getElementById("t5");
+    range.selectNode(slider);
+    placeMarkersForRange(range);
+
+    var image = document.getElementById("t6");
+    range.selectNode(image);
+    placeMarkersForRange(range);
+</script>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index c408627..728cd2a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,71 @@
+2010-02-15  Dan Bernstein  <mitz at apple.com>
+
+        Reviewed by Simon Fraser.
+
+        <rdar://problem/7647300> Incorrect client rects for blocks the span multiple columns and their descendants
+        https://bugs.webkit.org/show_bug.cgi?id=34923
+
+        Test: fast/multicol/client-rects.html
+
+        In column layout, a different transform applies to different points in
+        the block and its descendants, depending on their y coordinate within the
+        block. offsetFromContainer() used to return the offset that applied to
+        the origin. With this change, it returns the offset that applies to a
+        given reference point. When mapping a quad from local to absolute
+        coordinates, the top left of the quad’s bounding box is used as that
+        reference point.
+
+        * editing/SelectionController.cpp:
+        (WebCore::SelectionController::layout): Pass the caret’s origin as the
+        reference point to offsetFromContainer().
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::adjustForColumns): Adds the offset between the
+        given point and its image under the column paint-time transform to the
+        given offset. Used by offsetFromContainer() where it had previously used
+        adjustRectForColumns(), which takes a rect and operates less efficiently.
+        * rendering/RenderBlock.h:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::mapLocalToContainer): Pass the transformed point as
+        the reference point to offsetFromContainer().
+        (WebCore::RenderBox::mapAbsoluteToLocalPoint): Pass a point to
+        offsetFromContainer().
+        (WebCore::RenderBox::offsetFromContainer): Use adjustForColumns() instead
+        of adjustRectForColumns(), and use the reference point to get the right
+        adjustment for the point of interest, instead of the origin, in case this
+        box spans multiple columns.
+        * rendering/RenderBox.h:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::offsetFromContainer): Ditto. Actually apply the
+        column offset to the computation, which previously this function didn’t
+        do.
+        (WebCore::RenderInline::mapLocalToContainer): Pass the transformed point
+        as the reference point to offsetFromContainer().
+        (WebCore::RenderInline::mapAbsoluteToLocalPoint): Pass a point to
+        offsetFromContainer().
+        * rendering/RenderInline.h:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::mapLocalToContainer): Apply column adjustment,
+        based on the reference point, to the transform if needed.
+        (WebCore::RenderObject::localToContainerQuad): Initialize the
+        TransformState with the top left corner of the quad’s bounding box. It
+        is later used as the reference point when deciding on which column to
+        base the calculations.
+        (WebCore::RenderObject::offsetFromContainer): Adjust for columns.
+        (WebCore::RenderObject::offsetFromAncestorContainer): Pass the origin
+        as the reference point to offsetFromContainer().
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::adjustForColumns): Added.
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::offsetFromContainer): Pass the reference
+        point through.
+        * rendering/RenderTableCell.h:
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::absoluteRectsForRange): Map (the origin of) each
+        rect to absolute coordinates individually.
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::convertToPaintingRect): Pass a point to
+        offsetFromContainer().
+
 2010-02-12  Alexey Proskuryakov  <ap at apple.com>
 
         Reviewed by Kevin Decker.
diff --git a/WebCore/editing/SelectionController.cpp b/WebCore/editing/SelectionController.cpp
index 5b2d0d0..786dcc1 100644
--- a/WebCore/editing/SelectionController.cpp
+++ b/WebCore/editing/SelectionController.cpp
@@ -840,7 +840,6 @@ void SelectionController::layout()
             RenderObject* caretPainter = caretRenderer();
 
             // Compute an offset between the renderer and the caretPainter
-            IntSize offsetFromPainter;
             bool unrooted = false;
             while (renderer != caretPainter) {
                 RenderObject* containerObject = renderer->container();
@@ -848,15 +847,12 @@ void SelectionController::layout()
                     unrooted = true;
                     break;
                 }
-                offsetFromPainter += renderer->offsetFromContainer(containerObject);
+                localRect.move(renderer->offsetFromContainer(containerObject, localRect.location()));
                 renderer = containerObject;
             }
             
-            if (!unrooted) {
-                // Move the caret rect to the coords of the painter
-                localRect.move(offsetFromPainter);
+            if (!unrooted)
                 m_caretRect = localRect;
-            }
             
             m_absCaretBoundsDirty = true;
         }
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 1bea8e3..143781c 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -3874,6 +3874,31 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
     r = result;
 }
 
+void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
+{
+    if (!hasColumns())
+        return;
+
+    // FIXME: This is incorrect for right-to-left columns.
+
+    Vector<IntRect>& columnRects = *this->columnRects();
+
+    int gapWidth = columnGap();
+    int xOffset = 0;
+    int yOffset = 0;
+    size_t columnCount = columnRects.size();
+    for (size_t i = 0; i < columnCount; ++i) {
+        IntRect columnRect = columnRects[i];
+        if (point.y() < columnRect.bottom() + yOffset) {
+            offset.expand(xOffset, -yOffset);
+            return;
+        }
+
+        xOffset += columnRect.width() + gapWidth;
+        yOffset += columnRect.height();
+    }
+}
+
 void RenderBlock::calcPrefWidths()
 {
     ASSERT(prefWidthsDirty());
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 9134a19..fa6224d 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -128,6 +128,7 @@ public:
     void clearTruncation();
 
     void adjustRectForColumns(IntRect&) const;
+    virtual void adjustForColumns(IntSize&, const IntPoint&) const;
 
     void addContinuationWithOutline(RenderInline*);
 
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index df925ba..1d8fb12 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -974,7 +974,7 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool
     } else
         fixed |= isFixedPos;
     
-    IntSize containerOffset = offsetFromContainer(o);
+    IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
 
     bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
     if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -1015,7 +1015,7 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
 
     o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
 
-    IntSize containerOffset = offsetFromContainer(o);
+    IntSize containerOffset = offsetFromContainer(o, IntPoint());
 
     bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
     if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -1026,7 +1026,7 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
         transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
 }
 
-IntSize RenderBox::offsetFromContainer(RenderObject* o) const
+IntSize RenderBox::offsetFromContainer(RenderObject* o, const IntPoint& point) const
 {
     ASSERT(o == container());
 
@@ -1035,14 +1035,9 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o) const
         offset += relativePositionOffset();
 
     if (!isInline() || isReplaced()) {
-        RenderBlock* cb;
-        if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition
-                && (cb = toRenderBlock(o))->hasColumns()) {
-            IntRect rect(x(), y(), 1, 1);
-            cb->adjustRectForColumns(rect);
-            offset.expand(rect.x(), rect.y());
-        } else
-            offset.expand(x(), y());
+        if (style()->position() != AbsolutePosition && style()->position() != FixedPosition)
+            o->adjustForColumns(offset, IntPoint(point.x() + x(), point.y() + y()));
+        offset.expand(x(), y());
     }
 
     if (o->hasOverflowClip())
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 961b7fa..9af1b56 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -173,7 +173,7 @@ public:
     int overrideHeight() const;
     virtual void setOverrideSize(int);
 
-    virtual IntSize offsetFromContainer(RenderObject*) const;
+    virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
     
     int calcBorderBoxWidth(int width) const;
     int calcBorderBoxHeight(int height) const;
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 9571751..d254835 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -710,7 +710,7 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
     o->computeRectForRepaint(repaintContainer, rect, fixed);
 }
 
-IntSize RenderInline::offsetFromContainer(RenderObject* container) const
+IntSize RenderInline::offsetFromContainer(RenderObject* container, const IntPoint& point) const
 {
     ASSERT(container == this->container());
 
@@ -718,13 +718,7 @@ IntSize RenderInline::offsetFromContainer(RenderObject* container) const
     if (isRelPositioned())
         offset += relativePositionOffset();
 
-    if (!isInline() || isReplaced()) {
-        RenderBlock* cb;
-        if (container->isBlockFlow() && (cb = toRenderBlock(container))->hasColumns()) {
-            IntRect rect(0, 0, 1, 1);
-            cb->adjustRectForColumns(rect);
-        }
-    }
+    container->adjustForColumns(offset, point);
 
     if (container->hasOverflowClip())
         offset -= toRenderBox(container)->layer()->scrolledContentOffset();
@@ -753,7 +747,7 @@ void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
     if (!o)
         return;
 
-    IntSize containerOffset = offsetFromContainer(o);
+    IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
 
     bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
     if (useTransforms && shouldUseTransformFromContainer(o)) {
@@ -785,7 +779,7 @@ void RenderInline::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Trans
 
     o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
 
-    IntSize containerOffset = offsetFromContainer(o);
+    IntSize containerOffset = offsetFromContainer(o, IntPoint());
 
     bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
     if (useTransforms && shouldUseTransformFromContainer(o)) {
diff --git a/WebCore/rendering/RenderInline.h b/WebCore/rendering/RenderInline.h
index d35aa85..7fcb516 100644
--- a/WebCore/rendering/RenderInline.h
+++ b/WebCore/rendering/RenderInline.h
@@ -44,7 +44,7 @@ public:
     virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
     virtual void absoluteQuads(Vector<FloatQuad>&);
 
-    virtual IntSize offsetFromContainer(RenderObject*) const;
+    virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
 
     IntRect linesBoundingBox() const;
     IntRect linesVisibleOverflowBoundingBox() const;
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 4a235d3..b99cd31 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -1762,6 +1762,11 @@ void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
     if (!o)
         return;
 
+    IntSize columnOffset;
+    o->adjustForColumns(columnOffset, roundedIntPoint(transformState.mappedPoint()));
+    if (!columnOffset.isZero())
+        transformState.move(columnOffset);
+
     if (o->hasOverflowClip())
         transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset());
 
@@ -1818,18 +1823,21 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject
 
 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed) const
 {
-    TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint(), &localQuad);
+    TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().location(), &localQuad);
     mapLocalToContainer(repaintContainer, fixed, true, transformState);
     transformState.flatten();
     
     return transformState.lastPlanarQuad();
 }
 
-IntSize RenderObject::offsetFromContainer(RenderObject* o) const
+IntSize RenderObject::offsetFromContainer(RenderObject* o, const IntPoint& point) const
 {
     ASSERT(o == container());
 
     IntSize offset;
+
+    o->adjustForColumns(offset, point);
+
     if (o->hasOverflowClip())
         offset -= toRenderBox(o)->layer()->scrolledContentOffset();
 
@@ -1839,6 +1847,7 @@ IntSize RenderObject::offsetFromContainer(RenderObject* o) const
 IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
 {
     IntSize offset;
+    IntPoint referencePoint;
     const RenderObject* currContainer = this;
     do {
         RenderObject* nextContainer = currContainer->container();
@@ -1846,7 +1855,9 @@ IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
         if (!nextContainer)
             break;
         ASSERT(!currContainer->hasTransform());
-        offset += currContainer->offsetFromContainer(nextContainer);
+        IntSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
+        offset += currentOffset;
+        referencePoint.move(currentOffset);
         currContainer = nextContainer;
     } while (currContainer != container);
 
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 6764818..3d24c43 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -562,8 +562,9 @@ public:
     // Convert a local quad into the coordinate system of container, taking transforms into account.
     FloatQuad localToContainerQuad(const FloatQuad&, RenderBoxModelObject* repaintContainer, bool fixed = false) const;
 
-    // Return the offset from the container() renderer (excluding transforms)
-    virtual IntSize offsetFromContainer(RenderObject*) const;
+    // Return the offset from the container() renderer (excluding transforms). In multi-column layout,
+    // different offsets apply at different points, so return the offset that applies to the given point.
+    virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
     // Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms.
     IntSize offsetFromAncestorContainer(RenderObject*) const;
     
@@ -642,6 +643,10 @@ public:
     // that rect in the coordinate space of repaintContainer.
     virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
 
+    // If multiple-column layout results in applying an offset to the given point, add the same
+    // offset to the given size.
+    virtual void adjustForColumns(IntSize&, const IntPoint&) const { }
+
     virtual unsigned int length() const { return 1; }
 
     bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); }
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index bfa865f..ede0f2c 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -154,11 +154,11 @@ void RenderTableCell::setOverrideSize(int size)
     RenderBlock::setOverrideSize(size);
 }
 
-IntSize RenderTableCell::offsetFromContainer(RenderObject* o) const
+IntSize RenderTableCell::offsetFromContainer(RenderObject* o, const IntPoint& point) const
 {
     ASSERT(o == container());
 
-    IntSize offset = RenderBlock::offsetFromContainer(o);
+    IntSize offset = RenderBlock::offsetFromContainer(o, point);
     if (parent())
         offset.expand(-parentBox()->x(), -parentBox()->y());
 
diff --git a/WebCore/rendering/RenderTableCell.h b/WebCore/rendering/RenderTableCell.h
index 89e2cbe..b6622f4 100644
--- a/WebCore/rendering/RenderTableCell.h
+++ b/WebCore/rendering/RenderTableCell.h
@@ -119,7 +119,7 @@ private:
     virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
     virtual void paintMask(PaintInfo&, int tx, int ty);
 
-    virtual IntSize offsetFromContainer(RenderObject*) const;
+    virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const;
     virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
     virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
 
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 2e696a9..4653273 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -230,27 +230,32 @@ void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
     start = min(start, static_cast<unsigned>(INT_MAX));
     end = min(end, static_cast<unsigned>(INT_MAX));
     
-    FloatPoint absPos = localToAbsolute(FloatPoint());
-
     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
         // Note: box->end() returns the index of the last character, not the index past it
         if (start <= box->start() && box->end() < end) {
-            IntRect r = IntRect(absPos.x() + box->x(), absPos.y() + box->y(), box->width(), box->height());
+            IntRect r = IntRect(box->x(), box->y(), box->width(), box->height());
             if (useSelectionHeight) {
-                IntRect selectionRect = box->selectionRect(absPos.x(), absPos.y(), start, end);
+                IntRect selectionRect = box->selectionRect(0, 0, start, end);
                 r.setHeight(selectionRect.height());
                 r.setY(selectionRect.y());
             }
+            FloatPoint origin = localToAbsolute(r.location());
+            r.setX(origin.x());
+            r.setY(origin.y());
             rects.append(r);
         } else {
             unsigned realEnd = min(box->end() + 1, end);
-            IntRect r = box->selectionRect(absPos.x(), absPos.y(), start, realEnd);
+            IntRect r = box->selectionRect(0, 0, start, realEnd);
             if (!r.isEmpty()) {
                 if (!useSelectionHeight) {
                     // change the height and y position because selectionRect uses selection-specific values
                     r.setHeight(box->height());
-                    r.setY(absPos.y() + box->y());
+                    r.setY(box->y());
                 }
+                FloatPoint origin = localToAbsolute(r.location());
+                localToAbsolute(origin);
+                r.setX(origin.x());
+                r.setY(origin.y());
                 rects.append(r);
             }
         }
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index ddb538b..b6ce93d 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -520,7 +520,7 @@ FloatRect RenderThemeMac::convertToPaintingRect(const RenderObject* inputRendere
     const RenderObject* renderer = partRenderer;
     while (renderer && renderer != inputRenderer) {
         RenderObject* containingRenderer = renderer->container();
-        offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer);
+        offsetFromInputRenderer -= renderer->offsetFromContainer(containingRenderer, IntPoint());
         renderer = containingRenderer;
     }
     // If the input renderer was not a container, something went wrong

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list