Title: [133968] trunk
Revision
133968
Author
commit-qu...@webkit.org
Date
2012-11-08 16:09:57 -0800 (Thu, 08 Nov 2012)

Log Message

[CSS Exclusions] Polygon with horizontal bottom edges returns incorrect segments
https://bugs.webkit.org/show_bug.cgi?id=100874

Patch by Hans Muller <hmul...@adobe.com> on 2012-11-08
Reviewed by Dirk Schulze.

Source/WebCore:

Revised the way that computeXIntersections() handles intersections with horizotal polygon edges.
Deciding if a vertex intersection corresponds to a polygon "edge crossing", i.e. a change from inside
to outside or outside to inside, now depends on which side of the horizontal line the function's
y parameter corresponds to. If the y corresponds to the top of the line, then isaMinY the parameter
is true, and an intersection with a horizontal edge is only considered to be an edge crossing if
if the inside of the polygon is just below the horizontal edge.  When isMinY is false then the inside
of the polygon must be just above the horizontal edge.

Tests: fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003.html
       fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004.html

* rendering/ExclusionPolygon.cpp:
(WebCore::getVertexIntersectionVertices): Corrected two cases where the next/previous vertex was determined incorrectly.
(WebCore::ExclusionPolygon::computeXIntersections): Added a bool isMinY parameter which specifies if the y parameter corresponds to the top or bottom a horizontal line.
(WebCore::ExclusionPolygon::getExcludedIntervals): Added the new computeXIntersections() parameter.
(WebCore::ExclusionPolygon::getIncludedIntervals): Ditto.
* rendering/ExclusionPolygon.h:
(WebCore::ExclusionPolygonEdge::previousEdge): Corrected the previousEdge() function.

LayoutTests:

Added two additional tests for rectilinear polygons, where the tops and bottoms
of lines intersect the polygons' horizontal edges. More tests of this kind will
be needed when exclusion layout supports polygons that break horizontal lines up
into more than one segment.

* fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003-expected.html: Added.
* fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003.html: Added.
* fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004-expected.html: Added.
* fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (133967 => 133968)


--- trunk/LayoutTests/ChangeLog	2012-11-09 00:07:38 UTC (rev 133967)
+++ trunk/LayoutTests/ChangeLog	2012-11-09 00:09:57 UTC (rev 133968)
@@ -1,3 +1,20 @@
+2012-11-08  Hans Muller  <hmul...@adobe.com>
+
+        [CSS Exclusions] Polygon with horizontal bottom edges returns incorrect segments
+        https://bugs.webkit.org/show_bug.cgi?id=100874
+
+        Reviewed by Dirk Schulze.
+
+        Added two additional tests for rectilinear polygons, where the tops and bottoms
+        of lines intersect the polygons' horizontal edges. More tests of this kind will
+        be needed when exclusion layout supports polygons that break horizontal lines up
+        into more than one segment.
+
+        * fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003-expected.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004-expected.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004.html: Added.
+
 2012-11-08  Christophe Dumez  <christophe.du...@intel.com>
 
         [JSC] HTML extensions to String.prototype should escape " as &quot; in argument values

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003-expected.html (0 => 133968)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003-expected.html	2012-11-09 00:09:57 UTC (rev 133968)
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+
+<!-- 
+Test test creates a rectilinear polygon with this shape:
+  XXXXXXXX 
+    XXXX 
+  XXXXXXXX
+-->
+
+<style id="stylesheet">
+    #shape-inside, #shape-outline {
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 400px;
+        height: 200px;
+        margin: 0;
+    }
+
+    #shape-inside {
+        word-wrap: break-word;
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+    }
+
+    #shape-outline {
+        fill: none;
+        stroke: blue;
+    }
+
+    #informative-text {
+        position: absolute;
+        top: 150px;
+    }
+</style>
+</head>
+
+</head>
+<body>
+  <div id="shape-inside">XXXXXXXX<br/>&nbsp;&nbsp;XXXX<br/>XXXXXXXX</div>
+  <svg id="shape-outline" xmlns="http://www.w3.org/2000/svg">
+      <polygon points="0,0 400,0 400,50 300,50 300,100 400,100 400,150 0,150 0,100 100,100 100,50 0,50"/>
+  </svg>
+  <p id="informative-text">
+      This test requires the Ahem font. It creates a rectilinear polygonal shape-inside and a
+      matching stroked SVG polygon. The content should just fill the shape with solid green.</p>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003.html (0 => 133968)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003.html	2012-11-09 00:09:57 UTC (rev 133968)
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+
+<!-- 
+Test test creates a rectilinear polygon with this shape:
+  XXXXXXXX 
+    XXXX 
+  XXXXXXXX
+-->
+
+<style id="stylesheet">
+    #shape-inside, #shape-outline {
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 400px;
+        height: 200px;
+        margin: 0;
+    }
+
+    #shape-inside {
+        -webkit-shape-inside: polygon(0 0px, 400px 0px, 400px 50px, 300px 50px, 300px 100px, 400px 100px, 400px 150px, 0 150px, 0 100px, 100px 100px, 100px 50px, 0px 50px);
+        word-wrap: break-word;
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+    }
+
+    #shape-outline {
+        fill: none;
+        stroke: blue;
+    }
+
+    #informative-text {
+        position: absolute;
+        top: 150px;
+    }
+</style>
+</head>
+
+</head>
+<body>
+  <div id="shape-inside">XXXXXXXX XXXX XXXXXXXX</div>
+  <svg id="shape-outline" xmlns="http://www.w3.org/2000/svg">
+      <polygon points="0,0 400,0 400,50 300,50 300,100 400,100 400,150 0,150 0,100 100,100 100,50 0,50"/>
+  </svg>
+  <p id="informative-text">
+      This test requires the Ahem font. It creates a rectilinear polygonal shape-inside and a
+      matching stroked SVG polygon. The content should just fill the shape with solid green.</p>
+</html>
+

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004-expected.html (0 => 133968)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004-expected.html	2012-11-09 00:09:57 UTC (rev 133968)
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+
+<!-- 
+Test test creates a rectilinear polygon with this shape:
+      XXXX
+    XXXX 
+  XXXX
+-->
+
+<style id="stylesheet">
+    #shape-inside, #shape-outline {
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 400px;
+        height: 200px;
+        margin: 0;
+    }
+
+    #shape-inside {
+        word-wrap: break-word;
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+    }
+
+    #shape-outline {
+        fill: none;
+        stroke: blue;
+    }
+
+    #informative-text {
+        position: absolute;
+        top: 150px;
+    }
+</style>
+</head>
+
+</head>
+<body>
+  <div id="shape-inside">&nbsp;&nbsp;&nbsp;&nbsp;XXXX<br/>&nbsp;&nbsp;XXXX<br/>XXXX</div>
+  <svg id="shape-outline" xmlns="http://www.w3.org/2000/svg">
+      <polygon points="200,0 400,0 400,50 300,50 300,100 200,100 200,150 0,150 0,100 100,100 100,50 200,50"/>
+  </svg>
+  <p id="informative-text">
+      This test requires the Ahem font. It creates a rectilinear polygonal shape-inside and a
+      matching stroked SVG polygon. The content should just fill the shape with solid green.</p>
+</html>
+

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004.html (0 => 133968)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004.html	2012-11-09 00:09:57 UTC (rev 133968)
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+
+<!-- 
+Test test creates a rectilinear polygon with this shape:
+      XXXX
+    XXXX 
+  XXXX
+-->
+
+<style id="stylesheet">
+    #shape-inside, #shape-outline {
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 400px;
+        height: 200px;
+        margin: 0;
+    }
+
+    #shape-inside {
+        -webkit-shape-inside: polygon(200px 0px, 400px 0px, 400px 50px, 300px 50px, 300px 100px, 200px 100px, 200px 150px, 0 150px, 0 100px, 100px 100px, 100px 50px, 200px 50px);
+        word-wrap: break-word;
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+    }
+
+    #shape-outline {
+        fill: none;
+        stroke: blue;
+    }
+
+    #informative-text {
+        position: absolute;
+        top: 150px;
+    }
+</style>
+</head>
+
+</head>
+<body>
+  <div id="shape-inside">XXXX XXXX XXXX</div>
+  <svg id="shape-outline" xmlns="http://www.w3.org/2000/svg">
+      <polygon points="200,0 400,0 400,50 300,50 300,100 200,100 200,150 0,150 0,100 100,100 100,50 200,50"/>
+  </svg>
+  <p id="informative-text">
+      This test requires the Ahem font. It creates a rectilinear polygonal shape-inside and a
+      matching stroked SVG polygon. The content should just fill the shape with solid green.</p>
+</html>
+

Modified: trunk/Source/WebCore/ChangeLog (133967 => 133968)


--- trunk/Source/WebCore/ChangeLog	2012-11-09 00:07:38 UTC (rev 133967)
+++ trunk/Source/WebCore/ChangeLog	2012-11-09 00:09:57 UTC (rev 133968)
@@ -1,3 +1,29 @@
+2012-11-08  Hans Muller  <hmul...@adobe.com>
+
+        [CSS Exclusions] Polygon with horizontal bottom edges returns incorrect segments
+        https://bugs.webkit.org/show_bug.cgi?id=100874
+
+        Reviewed by Dirk Schulze.
+
+        Revised the way that computeXIntersections() handles intersections with horizotal polygon edges.
+        Deciding if a vertex intersection corresponds to a polygon "edge crossing", i.e. a change from inside
+        to outside or outside to inside, now depends on which side of the horizontal line the function's
+        y parameter corresponds to. If the y corresponds to the top of the line, then isaMinY the parameter
+        is true, and an intersection with a horizontal edge is only considered to be an edge crossing if
+        if the inside of the polygon is just below the horizontal edge.  When isMinY is false then the inside
+        of the polygon must be just above the horizontal edge.
+
+        Tests: fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-003.html
+               fast/exclusions/shape-inside/shape-inside-rectilinear-polygon-004.html
+
+        * rendering/ExclusionPolygon.cpp:
+        (WebCore::getVertexIntersectionVertices): Corrected two cases where the next/previous vertex was determined incorrectly.
+        (WebCore::ExclusionPolygon::computeXIntersections): Added a bool isMinY parameter which specifies if the y parameter corresponds to the top or bottom a horizontal line.
+        (WebCore::ExclusionPolygon::getExcludedIntervals): Added the new computeXIntersections() parameter.
+        (WebCore::ExclusionPolygon::getIncludedIntervals): Ditto.
+        * rendering/ExclusionPolygon.h:
+        (WebCore::ExclusionPolygonEdge::previousEdge): Corrected the previousEdge() function.
+
 2012-11-08  Otto Derek Cheung  <otche...@rim.com>
 
         [BlackBerry] Disable cookies on file://

Modified: trunk/Source/WebCore/rendering/ExclusionPolygon.cpp (133967 => 133968)


--- trunk/Source/WebCore/rendering/ExclusionPolygon.cpp	2012-11-09 00:07:38 UTC (rev 133967)
+++ trunk/Source/WebCore/rendering/ExclusionPolygon.cpp	2012-11-09 00:09:57 UTC (rev 133968)
@@ -190,13 +190,13 @@
 
     if ((intersection.type == VertexMinY && (thisEdge.vertex1().y() < thisEdge.vertex2().y()))
         || (intersection.type == VertexMaxY && (thisEdge.vertex1().y() > thisEdge.vertex2().y()))) {
-        prevVertex = polygon.vertexAt(thisEdge.previousEdge().vertexIndex2);
+        prevVertex = polygon.vertexAt(thisEdge.previousEdge().vertexIndex1);
         thisVertex = polygon.vertexAt(thisEdge.vertexIndex1);
         nextVertex = polygon.vertexAt(thisEdge.vertexIndex2);
     } else {
         prevVertex = polygon.vertexAt(thisEdge.vertexIndex1);
         thisVertex = polygon.vertexAt(thisEdge.vertexIndex2);
-        nextVertex = polygon.vertexAt(thisEdge.nextEdge().vertexIndex1);
+        nextVertex = polygon.vertexAt(thisEdge.nextEdge().vertexIndex2);
     }
 
     return true;
@@ -219,7 +219,7 @@
     return (x1 == x2) ? intersection1.type < intersection2.type : x1 < x2;
 }
 
-void ExclusionPolygon::computeXIntersections(float y, Vector<ExclusionInterval>& result) const
+void ExclusionPolygon::computeXIntersections(float y, bool isMinY, Vector<ExclusionInterval>& result) const
 {
     Vector<ExclusionPolygon::EdgeInterval> overlappingEdges;
     m_edgeTree.allOverlaps(ExclusionPolygon::EdgeInterval(y, y, 0), overlappingEdges);
@@ -265,19 +265,19 @@
         }
 
         if (evenOddCrossing) {
-            bool edgeCrossing = false;
-            if (thisIntersection.type == Normal || !inside || index == intersections.size() - 1)
-                edgeCrossing = true;
-            else {
+            bool edgeCrossing = thisIntersection.type == Normal;
+            if (!edgeCrossing) {
                 FloatPoint prevVertex;
                 FloatPoint thisVertex;
                 FloatPoint nextVertex;
 
                 if (getVertexIntersectionVertices(thisIntersection, prevVertex, thisVertex, nextVertex)) {
-                    if (prevVertex.y() == y)
-                        edgeCrossing =  (thisVertex.x() > prevVertex.x()) ? nextVertex.y() > y : nextVertex.y() < y;
+                    if (nextVertex.y() == y)
+                        edgeCrossing = (isMinY) ? prevVertex.y() > y : prevVertex.y() < y;
+                    else if (prevVertex.y() == y)
+                        edgeCrossing = (isMinY) ? nextVertex.y() > y : nextVertex.y() < y;
                     else
-                        edgeCrossing = (nextVertex.y() != y);
+                        edgeCrossing = true;
                 }
             }
             if (edgeCrossing)
@@ -331,8 +331,8 @@
     float y2 = maxYForLogicalLine(logicalTop, logicalHeight);
 
     Vector<ExclusionInterval> y1XIntervals, y2XIntervals;
-    computeXIntersections(y1, y1XIntervals);
-    computeXIntersections(y2, y2XIntervals);
+    computeXIntersections(y1, true, y1XIntervals);
+    computeXIntersections(y2, false, y2XIntervals);
 
     Vector<ExclusionInterval> mergedIntervals;
     mergeExclusionIntervals(y1XIntervals, y2XIntervals, mergedIntervals);
@@ -358,8 +358,8 @@
     float y2 = maxYForLogicalLine(logicalTop, logicalHeight);
 
     Vector<ExclusionInterval> y1XIntervals, y2XIntervals;
-    computeXIntersections(y1, y1XIntervals);
-    computeXIntersections(y2, y2XIntervals);
+    computeXIntersections(y1, true, y1XIntervals);
+    computeXIntersections(y2, false, y2XIntervals);
 
     Vector<ExclusionInterval> commonIntervals;
     intersectExclusionIntervals(y1XIntervals, y2XIntervals, commonIntervals);

Modified: trunk/Source/WebCore/rendering/ExclusionPolygon.h (133967 => 133968)


--- trunk/Source/WebCore/rendering/ExclusionPolygon.h	2012-11-09 00:07:38 UTC (rev 133967)
+++ trunk/Source/WebCore/rendering/ExclusionPolygon.h	2012-11-09 00:09:57 UTC (rev 133968)
@@ -68,7 +68,7 @@
     virtual void getIncludedIntervals(float logicalTop, float logicalHeight, SegmentList&) const OVERRIDE;
 
 private:
-    void computeXIntersections(float y, Vector<ExclusionInterval>&) const;
+    void computeXIntersections(float y, bool isMinY, Vector<ExclusionInterval>&) const;
     void computeEdgeIntersections(float minY, float maxY, Vector<ExclusionInterval>&) const;
     unsigned findNextEdgeVertexIndex(unsigned vertexIndex1, bool clockwise) const;
 
@@ -102,7 +102,7 @@
     const ExclusionPolygonEdge& previousEdge() const
     {
         ASSERT(polygon && polygon->numberOfEdges() > 1);
-        return polygon->edgeAt((edgeIndex + polygon->numberOfEdges() - 2) % polygon->numberOfEdges());
+        return polygon->edgeAt((edgeIndex + polygon->numberOfEdges() - 1) % polygon->numberOfEdges());
     }
 
     const ExclusionPolygonEdge& nextEdge() const
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to