2006-12-28 Mitz Pettel <mitz@webkit.org>
authorap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Dec 2006 18:29:22 +0000 (18:29 +0000)
committerap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Dec 2006 18:29:22 +0000 (18:29 +0000)
        Reviewed by Darin.

        - fix http://bugs.webkit.org/show_bug.cgi?id=11359
          Incomplete repaint of table cell's collapsed border when changing only the cell

        Test: fast/repaint/table-cell-collapsed-border.html

        * rendering/RenderTableCell.cpp:
        (WebCore::RenderTableCell::getAbsoluteRepaintRect): Overloaded to add the
        outer half of any collapsed borders. This function checks the cell's borders'
        widths but also the widths of the adjoining cells' borders, since they can
        contribute to the length of this cell's borders perpendicular to them, making
        such a border overflow the cell in both dimensions.
        (WebCore::RenderTableCell::borderLeft): Split the collapsing borders case off to
        borderHalfLeft().
        (WebCore::RenderTableCell::borderRight): Ditto.
        (WebCore::RenderTableCell::borderTop): Ditto.
        (WebCore::RenderTableCell::borderBottom): Ditto.
        (WebCore::RenderTableCell::borderHalfLeft): Added. Takes an 'outer' boolean
        parameter. When true, this function returns the width of the part of the border
        that is outside the cell (different from the inner width when the total width is odd).
        (WebCore::RenderTableCell::borderHalfRight): Ditto.
        (WebCore::RenderTableCell::borderHalfTop): Ditto.
        (WebCore::RenderTableCell::borderHalfBottom): Ditto.
        * rendering/RenderTableCell.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@18454 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/repaint/table-cell-collapsed-border-expected.checksum [new file with mode: 0644]
LayoutTests/fast/repaint/table-cell-collapsed-border-expected.png [new file with mode: 0644]
LayoutTests/fast/repaint/table-cell-collapsed-border-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/table-cell-collapsed-border.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/rendering/RenderTableCell.cpp
WebCore/rendering/RenderTableCell.h

index b7ecaee..0011371 100644 (file)
@@ -1,5 +1,17 @@
 2006-12-28  Mitz Pettel  <mitz@webkit.org>
 
+        Reviewed by Darin.
+
+        - repaint test for http://bugs.webkit.org/show_bug.cgi?id=11359
+          Incomplete repaint of table cell's collapsed border when changing only the cell
+
+        * fast/repaint/table-cell-collapsed-border-expected.checksum: Added.
+        * fast/repaint/table-cell-collapsed-border-expected.png: Added.
+        * fast/repaint/table-cell-collapsed-border-expected.txt: Added.
+        * fast/repaint/table-cell-collapsed-border.html: Added.
+
+2006-12-28  Mitz Pettel  <mitz@webkit.org>
+
         Reviewed by Alexey.
 
         - test for http://bugs.webkit.org/show_bug.cgi?id=11671
diff --git a/LayoutTests/fast/repaint/table-cell-collapsed-border-expected.checksum b/LayoutTests/fast/repaint/table-cell-collapsed-border-expected.checksum
new file mode 100644 (file)
index 0000000..a66f9de
--- /dev/null
@@ -0,0 +1 @@
+fa53790628d94e98e37705bb72b9e758
\ No newline at end of file
diff --git a/LayoutTests/fast/repaint/table-cell-collapsed-border-expected.png b/LayoutTests/fast/repaint/table-cell-collapsed-border-expected.png
new file mode 100644 (file)
index 0000000..e439949
Binary files /dev/null and b/LayoutTests/fast/repaint/table-cell-collapsed-border-expected.png differ
diff --git a/LayoutTests/fast/repaint/table-cell-collapsed-border-expected.txt b/LayoutTests/fast/repaint/table-cell-collapsed-border-expected.txt
new file mode 100644 (file)
index 0000000..a07ad13
--- /dev/null
@@ -0,0 +1,40 @@
+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 784x584
+      RenderBlock {P} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 100x18
+          text run at (0,0) width 100: "Repaint test for "
+        RenderInline {I} at (0,0) size 759x36
+          RenderInline {A} at (0,0) size 301x18 [color=#0000EE]
+            RenderText {#text} at (100,0) size 301x18
+              text run at (100,0) width 301: "http://bugs.webkit.org/show_bug.cgi?id=11359"
+          RenderText {#text} at (401,0) size 759x36
+            text run at (401,0) width 4: " "
+            text run at (405,0) width 354: "Incomplete repaint of table cell's collapsed border when"
+            text run at (0,18) width 139: "changing only the cell"
+        RenderText {#text} at (139,18) size 4x18
+          text run at (139,18) width 4: "."
+      RenderTable {TABLE} at (0,52) size 436x405 [border: (5px none #808080)]
+        RenderTableSection {TBODY} at (0,5) size 436x400
+          RenderTableRow {TR} at (0,0) size 436x100
+            RenderTableCell {TD} at (0,49) size 110x2 [bgcolor=#C0C0C0] [r=0 c=0 rs=1 cs=1]
+            RenderTableCell {TD} at (110,45) size 107x9 [bgcolor=#C0C0C0] [border: (5px solid #FFFFFF) (5px none #000000) (2px solid #FFFFFF) none] [r=0 c=1 rs=1 cs=1]
+            RenderTableCell {TD} at (217,49) size 112x2 [bgcolor=#C0C0C0] [border: none (5px solid #008000) none (5px solid #008000)] [r=0 c=2 rs=1 cs=1]
+            RenderTableCell {TD} at (329,45) size 107x10 [bgcolor=#C0C0C0] [border: (5px solid #FFFFFF) none (3px solid #FFFFFF) (5px none #000000)] [r=0 c=3 rs=1 cs=1]
+          RenderTableRow {TR} at (0,100) size 436x100
+            RenderTableCell {TD} at (0,146) size 110x7 [bgcolor=#C0C0C0] [border: none (2px solid #FFFFFF) (5px none #000000) (5px solid #FFFFFF)] [r=1 c=0 rs=1 cs=1]
+            RenderTableCell {TD} at (110,148) size 107x4 [bgcolor=#C0C0C0] [border: (2px none #000000)] [r=1 c=1 rs=1 cs=1]
+            RenderTableCell {TD} at (217,146) size 112x7 [bgcolor=#C0C0C0] [border: none] [r=1 c=2 rs=1 cs=1]
+            RenderTableCell {TD} at (329,147) size 107x5 [bgcolor=#C0C0C0] [border: (3px none #000000)] [r=1 c=3 rs=1 cs=1]
+          RenderTableRow {TR} at (0,200) size 436x100
+            RenderTableCell {TD} at (0,244) size 110x12 [bgcolor=#C0C0C0] [border: (5px solid #008000) none (5px solid #008000) none] [r=2 c=0 rs=1 cs=1]
+            RenderTableCell {TD} at (110,249) size 107x2 [bgcolor=#C0C0C0] [border: none] [r=2 c=1 rs=1 cs=1]
+            RenderTableCell {TD} at (217,244) size 112x12 [bgcolor=#C0C0C0] [border: (5px solid #008000)] [r=2 c=2 rs=1 cs=1]
+            RenderTableCell {TD} at (329,249) size 107x2 [bgcolor=#C0C0C0] [border: none] [r=2 c=3 rs=1 cs=1]
+          RenderTableRow {TR} at (0,300) size 436x100
+            RenderTableCell {TD} at (0,346) size 110x7 [bgcolor=#C0C0C0] [border: (5px none #000000) (3px solid #FFFFFF) none (5px solid #FFFFFF)] [r=3 c=0 rs=1 cs=1]
+            RenderTableCell {TD} at (110,349) size 107x2 [bgcolor=#C0C0C0] [border: none] [r=3 c=1 rs=1 cs=1]
+            RenderTableCell {TD} at (217,346) size 112x7 [bgcolor=#C0C0C0] [border: (5px none #000000)] [r=3 c=2 rs=1 cs=1]
+            RenderTableCell {TD} at (329,349) size 107x2 [bgcolor=#C0C0C0] [r=3 c=3 rs=1 cs=1]
diff --git a/LayoutTests/fast/repaint/table-cell-collapsed-border.html b/LayoutTests/fast/repaint/table-cell-collapsed-border.html
new file mode 100644 (file)
index 0000000..6eb05d2
--- /dev/null
@@ -0,0 +1,48 @@
+<html>
+<head>
+    <style>
+        table { border-collapse: collapse; }
+        td { background: silver; width: 100px; height: 100px; }
+    </style>
+    <script src="repaint.js" type="text/javascript"></script>
+    <script type="text/javascript">
+       function repaintTest()
+       {
+            for (i = 1; i < 4; i++)
+                document.getElementById("t" + i).style.borderColor = "green";
+       }
+    </script>
+</head>
+<body onload="runRepaintTest()">
+    <p>
+        Repaint test for <i><a href="http://bugs.webkit.org/show_bug.cgi?id=11359">http://bugs.webkit.org/show_bug.cgi?id=11359</a>
+        Incomplete repaint of table cell's collapsed border when changing only the cell</i>.
+    </p>
+    <table>
+        <tr>
+            <td></td>
+            <td style="border-bottom: 4px solid white; border-top: 10px solid white;"></td>
+            <td id="t1" style="border-left: 10px solid red; border-right: 10px solid red;"></td>
+            <td style="border-bottom: 6px solid white; border-top: 10px solid white;"></td>
+        </tr>
+        <tr>
+            <td style="border-left: 10px solid white; border-right: 4px solid white;"></td>
+            <td></td>
+            <td></td>
+            <td></td>
+        </tr>
+        <tr>
+            <td id="t2" style="border-top: 10px solid red; border-bottom: 10px solid red;"></td>
+            <td></td>
+            <td id="t3" style="border: 10px solid red;"></td>
+            <td></td>
+        </tr>
+        <tr>
+            <td style="border-left: 10px solid white; border-right: 6px solid white;"></td>
+            <td></td>
+            <td></td>
+            <td></td>
+        </tr>
+    </table>
+</body>
+</html>
index f26072a..e5cb455 100644 (file)
@@ -1,5 +1,33 @@
 2006-12-28  Mitz Pettel  <mitz@webkit.org>
 
+        Reviewed by Darin.
+
+        - fix http://bugs.webkit.org/show_bug.cgi?id=11359
+          Incomplete repaint of table cell's collapsed border when changing only the cell
+
+        Test: fast/repaint/table-cell-collapsed-border.html
+
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::getAbsoluteRepaintRect): Overloaded to add the
+        outer half of any collapsed borders. This function checks the cell's borders'
+        widths but also the widths of the adjoining cells' borders, since they can
+        contribute to the length of this cell's borders perpendicular to them, making
+        such a border overflow the cell in both dimensions.
+        (WebCore::RenderTableCell::borderLeft): Split the collapsing borders case off to
+        borderHalfLeft().
+        (WebCore::RenderTableCell::borderRight): Ditto.
+        (WebCore::RenderTableCell::borderTop): Ditto.
+        (WebCore::RenderTableCell::borderBottom): Ditto.
+        (WebCore::RenderTableCell::borderHalfLeft): Added. Takes an 'outer' boolean
+        parameter. When true, this function returns the width of the part of the border
+        that is outside the cell (different from the inner width when the total width is odd).
+        (WebCore::RenderTableCell::borderHalfRight): Ditto.
+        (WebCore::RenderTableCell::borderHalfTop): Ditto.
+        (WebCore::RenderTableCell::borderHalfBottom): Ditto.
+        * rendering/RenderTableCell.h:
+
+2006-12-28  Mitz Pettel  <mitz@webkit.org>
+
         Reviewed by Alexey.
 
         - fix http://bugs.webkit.org/show_bug.cgi?id=11671
index 0ae248d..5f9c3f3 100644 (file)
@@ -135,6 +135,48 @@ void RenderTableCell::layout()
     m_widthChanged = false;
 }
 
+IntRect RenderTableCell::getAbsoluteRepaintRect()
+{
+    if (table()->collapseBorders()) {
+        bool rtl = table()->style()->direction() == RTL;
+        int outlineSize = style()->outlineSize();
+        int left = max(borderHalfLeft(true), outlineSize);
+        int right = max(borderHalfRight(true), outlineSize);
+        int top = max(borderHalfTop(true), outlineSize);
+        int bottom = max(borderHalfBottom(true), outlineSize);
+        if (left && !rtl || right && rtl) {
+            if (RenderTableCell* before = table()->cellBefore(this)) {
+                top = max(top, before->borderHalfTop(true));
+                bottom = max(bottom, before->borderHalfBottom(true));
+            }
+        }
+        if (left && rtl || right && !rtl) {
+            if (RenderTableCell* after = table()->cellAfter(this)) {
+                top = max(top, after->borderHalfTop(true));
+                bottom = max(bottom, after->borderHalfBottom(true));
+            }
+        }
+        if (top) {
+            if (RenderTableCell* above = table()->cellAbove(this)) {
+                left = max(left, above->borderHalfLeft(true));
+                right = max(right, above->borderHalfRight(true));
+            }
+        }
+        if (bottom) {
+            if (RenderTableCell* below = table()->cellBelow(this)) {
+                left = max(left, below->borderHalfLeft(true));
+                right = max(right, below->borderHalfRight(true));
+            }
+        }
+        left = max(left, -overflowLeft(false));
+        top = max(top, -overflowTop(false) - borderTopExtra());
+        IntRect r(-left, -borderTopExtra() - top, left + max(width() + right, overflowWidth(false)), borderTopExtra() + top + max(height() + bottom + borderBottomExtra(), overflowHeight(false)));
+        computeAbsoluteRepaintRect(r);
+        return r;
+    }
+    return RenderBlock::getAbsoluteRepaintRect();
+}
+
 void RenderTableCell::computeAbsoluteRepaintRect(IntRect& r, bool f)
 {
     r.setY(r.y() + _topExtra);
@@ -487,46 +529,54 @@ CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const
 
 int RenderTableCell::borderLeft() const
 {
-    if (table()->collapseBorders()) {
-        CollapsedBorderValue border = collapsedLeftBorder(table()->style()->direction() == RTL);
-        if (border.exists())
-            return (border.width() + 1) / 2; // Give the extra pixel to top and left.
-        return 0;
-    }
-    return RenderBlock::borderLeft();
+    return table()->collapseBorders() ? borderHalfLeft(false) : RenderBlock::borderLeft();
 }
-    
+
 int RenderTableCell::borderRight() const
 {
-    if (table()->collapseBorders()) {
-        CollapsedBorderValue border = collapsedRightBorder(table()->style()->direction() == RTL);
-        if (border.exists())
-            return border.width() / 2;
-        return 0;
-    }
-    return RenderBlock::borderRight();
+    return table()->collapseBorders() ? borderHalfRight(false) : RenderBlock::borderRight();
 }
 
 int RenderTableCell::borderTop() const
 {
-    if (table()->collapseBorders()) {
-        CollapsedBorderValue border = collapsedTopBorder();
-        if (border.exists())
-            return (border.width() + 1) / 2; // Give the extra pixel to top and left.
-        return 0;
-    }
-    return RenderBlock::borderTop();
+    return table()->collapseBorders() ? borderHalfTop(false) : RenderBlock::borderTop();
 }
 
 int RenderTableCell::borderBottom() const
 {
-    if (table()->collapseBorders()) {
-        CollapsedBorderValue border = collapsedBottomBorder();
-        if (border.exists())
-            return border.width() / 2;
-        return 0;
-    }
-    return RenderBlock::borderBottom();
+    return table()->collapseBorders() ? borderHalfBottom(false) : RenderBlock::borderBottom();
+}
+
+int RenderTableCell::borderHalfLeft(bool outer) const
+{
+    CollapsedBorderValue border = collapsedLeftBorder(table()->style()->direction() == RTL);
+    if (border.exists())
+        return (border.width() + (outer ? 0 : 1)) / 2; // Give the extra pixel to top and left.
+    return 0;
+}
+    
+int RenderTableCell::borderHalfRight(bool outer) const
+{
+    CollapsedBorderValue border = collapsedRightBorder(table()->style()->direction() == RTL);
+    if (border.exists())
+        return (border.width() + (outer ? 1 : 0)) / 2;
+    return 0;
+}
+
+int RenderTableCell::borderHalfTop(bool outer) const
+{
+    CollapsedBorderValue border = collapsedTopBorder();
+    if (border.exists())
+        return (border.width() + (outer ? 0 : 1)) / 2; // Give the extra pixel to top and left.
+    return 0;
+}
+
+int RenderTableCell::borderHalfBottom(bool outer) const
+{
+    CollapsedBorderValue border = collapsedBottomBorder();
+    if (border.exists())
+        return (border.width() + (outer ? 1 : 0)) / 2;
+    return 0;
 }
 
 void RenderTableCell::paint(PaintInfo& paintInfo, int tx, int ty)
index 60a501a..9f616c5 100644 (file)
@@ -71,6 +71,11 @@ public:
     int borderTop() const;
     int borderBottom() const;
 
+    int borderHalfLeft(bool outer) const;
+    int borderHalfRight(bool outer) const;
+    int borderHalfTop(bool outer) const;
+    int borderHalfBottom(bool outer) const;
+
     CollapsedBorderValue collapsedLeftBorder(bool rtl) const;
     CollapsedBorderValue collapsedRightBorder(bool rtl) const;
     CollapsedBorderValue collapsedTopBorder() const;
@@ -91,6 +96,7 @@ public:
     // lie about position to outside observers
     virtual int yPos() const { return m_y + _topExtra; }
 
+    virtual IntRect getAbsoluteRepaintRect();
     virtual void computeAbsoluteRepaintRect(IntRect&, bool f=false);
     virtual bool absolutePosition(int& xPos, int& yPos, bool f = false);