Title: [133490] trunk
Revision
133490
Author
[email protected]
Date
2012-11-05 09:53:01 -0800 (Mon, 05 Nov 2012)

Log Message

[CSS Exclusions] Polygon edges should span colinear vertices
https://bugs.webkit.org/show_bug.cgi?id=99343

Patch by Hans Muller <[email protected]> on 2012-11-05
Reviewed by Dirk Schulze.

Source/WebCore:

ExclusionPolygonEdges now span coincident and collinear vertices. Currently
pairs of vertices are only considered coincident if their coordinates are exactly
equal. Similarly, a vertex is only considered collinear with an edge if the area
of the triangle defined by the three vertices is exactly zero.  In the future it
may be useful to relax the comparison with zero.

Tests: fast/exclusions/shape-inside/shape-inside-coincident-vertices.html
       fast/exclusions/shape-inside/shape-inside-collinear-vertices.html

* rendering/ExclusionPolygon.cpp:
(WebCore::determinant): Used to measure collinearity.
(WebCore):
(WebCore::areCollinearPoints): True if three FloatPoint arguments are collinear per the test outlined above.
(WebCore::areCoincidentPoints): True if the two FloatPoint arguments are equal.
(WebCore::nextVertexIndex): The next vertex index in clockwise or counterclockwise order.
(WebCore::ExclusionPolygon::findNextEdgeVertexIndex): Return the index of the next non-coincident, non-collinear vertex.
(WebCore::ExclusionPolygon::ExclusionPolygon): Skip coincident and collinear vertices when building the list of edges.
* rendering/ExclusionPolygon.h: Added private findNextEdgeVertexIndex() declaration.

LayoutTests:

Verify that exclusion polygonal shape-inside layout is unaffected by coincident
or collinear vertices.

* fast/exclusions/shape-inside/shape-inside-coincident-vertices-expected.html: Added.
* fast/exclusions/shape-inside/shape-inside-coincident-vertices.html: Added.
* fast/exclusions/shape-inside/shape-inside-collinear-vertices-expected.html: Added.
* fast/exclusions/shape-inside/shape-inside-collinear-vertices.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (133489 => 133490)


--- trunk/LayoutTests/ChangeLog	2012-11-05 17:37:13 UTC (rev 133489)
+++ trunk/LayoutTests/ChangeLog	2012-11-05 17:53:01 UTC (rev 133490)
@@ -1,3 +1,18 @@
+2012-11-05  Hans Muller  <[email protected]>
+
+        [CSS Exclusions] Polygon edges should span colinear vertices
+        https://bugs.webkit.org/show_bug.cgi?id=99343
+
+        Reviewed by Dirk Schulze.
+
+        Verify that exclusion polygonal shape-inside layout is unaffected by coincident
+        or collinear vertices.
+
+        * fast/exclusions/shape-inside/shape-inside-coincident-vertices-expected.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-coincident-vertices.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-collinear-vertices-expected.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-collinear-vertices.html: Added.
+
 2012-11-05  Csaba Osztrogonác  <[email protected]>
 
         [Qt] Unreviewed gardening, unskip now passing tests.

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-coincident-vertices-expected.html (0 => 133490)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-coincident-vertices-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-coincident-vertices-expected.html	2012-11-05 17:53:01 UTC (rev 133490)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+<style>
+    #shape-inside {
+        position: relative;
+        top: 50px;
+        left: 50px;
+        width: 250px;
+        height: 250px;
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+    }
+</style>
+</head>
+<body>
+    Requires Ahem font. Verifies that polygonal shapes with multiple coincident vertices produce 
+    the same output as they would with only the unique vertices.  This test should display two
+    indentical solid green squares.
+    <div id="shape-inside">XXXX XXXX XXXX XXXX</div>
+    <div id="shape-inside">XXXX XXXX XXXX XXXX</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-coincident-vertices.html (0 => 133490)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-coincident-vertices.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-coincident-vertices.html	2012-11-05 17:53:01 UTC (rev 133490)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+<style>
+    #shape-inside-coincident-vertices {
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+        width: 250px;
+        height: 250px;
+        -webkit-shape-inside: polygon(50px 50px, 50px 50px,  250px 50px, 250px 50px,  250px 250px,  50px 250px,  50px 50px, 50px 50px);
+    }
+    #shape-inside {
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+        width: 250px;
+        height: 250px;
+        -webkit-shape-inside: polygon(50px 50px, 250px 50px, 250px 250px, 50px 250px);
+    }
+</style>
+</head>
+<body>
+    Requires Ahem font. Verifies that polygonal shapes with multiple coincident vertices produce 
+    the same output as they would with only the unique vertices.  This test should display two
+    indentical solid green squares.
+    <div id="shape-inside-coincident-vertices">XXXX XXXX XXXX XXXX</div>
+    <div id="shape-inside">XXXX XXXX XXXX XXXX</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-collinear-vertices-expected.html (0 => 133490)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-collinear-vertices-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-collinear-vertices-expected.html	2012-11-05 17:53:01 UTC (rev 133490)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+<style>
+    #shape-inside {
+        position: relative;
+        top: 50px;
+        left: 50px;
+        width: 250px;
+        height: 250px;
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+    }
+</style>
+</head>
+<body>
+    Requires Ahem font. Verifies that polygonal shapes with multiple coincident vertices produce 
+    the same output as they would with only the unique vertices.  This test should display two
+    indentical solid green rectilinear triangles.
+    <div id="shape-inside">XXX<br/>XX<br/>X</div>
+    <div id="shape-inside">XXX<br/>XX<br/>X</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-collinear-vertices.html (0 => 133490)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-collinear-vertices.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-collinear-vertices.html	2012-11-05 17:53:01 UTC (rev 133490)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+<style>
+    #shape-inside-collinear-vertices {
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+        width: 250px;
+        height: 250px;
+        -webkit-shape-inside: polygon(200px 100px, 150px 150px, 100px 200px, 50px 250px, 50px 50px, 60px 50px, 61px 50px, 250px 50px);
+    }
+    #shape-inside {
+        font: 50px/1 Ahem, sans-serif;
+        color: green;
+        width: 250px;
+        height: 250px;
+        -webkit-shape-inside: polygon(50px 50px,  250px 50px, 250px 50px, 50px 250px);
+    }
+</style>
+</head>
+<body>
+    Requires Ahem font. Verifies that polygonal shapes with multiple coincident vertices produce 
+    the same output as they would with only the unique vertices.  This test should display two
+    indentical solid green rectilinear triangles.
+    <div id="shape-inside-collinear-vertices">XXX XX X</div>
+    <div id="shape-inside">XXX XX X</div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (133489 => 133490)


--- trunk/Source/WebCore/ChangeLog	2012-11-05 17:37:13 UTC (rev 133489)
+++ trunk/Source/WebCore/ChangeLog	2012-11-05 17:53:01 UTC (rev 133490)
@@ -1,3 +1,29 @@
+2012-11-05  Hans Muller  <[email protected]>
+
+        [CSS Exclusions] Polygon edges should span colinear vertices
+        https://bugs.webkit.org/show_bug.cgi?id=99343
+
+        Reviewed by Dirk Schulze.
+
+        ExclusionPolygonEdges now span coincident and collinear vertices. Currently
+        pairs of vertices are only considered coincident if their coordinates are exactly
+        equal. Similarly, a vertex is only considered collinear with an edge if the area
+        of the triangle defined by the three vertices is exactly zero.  In the future it
+        may be useful to relax the comparison with zero.
+
+        Tests: fast/exclusions/shape-inside/shape-inside-coincident-vertices.html
+               fast/exclusions/shape-inside/shape-inside-collinear-vertices.html
+
+        * rendering/ExclusionPolygon.cpp:
+        (WebCore::determinant): Used to measure collinearity.
+        (WebCore):
+        (WebCore::areCollinearPoints): True if three FloatPoint arguments are collinear per the test outlined above.
+        (WebCore::areCoincidentPoints): True if the two FloatPoint arguments are equal.
+        (WebCore::nextVertexIndex): The next vertex index in clockwise or counterclockwise order.
+        (WebCore::ExclusionPolygon::findNextEdgeVertexIndex): Return the index of the next non-coincident, non-collinear vertex.
+        (WebCore::ExclusionPolygon::ExclusionPolygon): Skip coincident and collinear vertices when building the list of edges.
+        * rendering/ExclusionPolygon.h: Added private findNextEdgeVertexIndex() declaration.
+
 2012-11-05  Christophe Dumez  <[email protected]>
 
         [EFL] Use POSIX implementation of SharedBuffer::createWithContentsOfFile()

Modified: trunk/Source/WebCore/rendering/ExclusionPolygon.cpp (133489 => 133490)


--- trunk/Source/WebCore/rendering/ExclusionPolygon.cpp	2012-11-05 17:37:13 UTC (rev 133489)
+++ trunk/Source/WebCore/rendering/ExclusionPolygon.cpp	2012-11-05 17:53:01 UTC (rev 133490)
@@ -47,6 +47,45 @@
     EdgeIntersectionType type;
 };
 
+static inline float determinant(const FloatSize& a, const FloatSize& b)
+{
+    return a.width() * b.height() - a.height() * b.width();
+}
+
+static inline bool areCollinearPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
+{
+    return !determinant(p1 - p0, p2 - p0);
+}
+
+static inline bool areCoincidentPoints(const FloatPoint& p0, const FloatPoint& p1)
+{
+    return p0.x() == p1.x() && p0.y() == p1.y();
+}
+
+static inline unsigned nextVertexIndex(unsigned vertexIndex, unsigned nVertices, bool clockwise)
+{
+    return ((clockwise) ? vertexIndex + 1 : vertexIndex - 1 + nVertices) % nVertices;
+}
+
+unsigned ExclusionPolygon::findNextEdgeVertexIndex(unsigned vertexIndex1, bool clockwise) const
+{
+    unsigned nVertices = numberOfVertices();
+    unsigned vertexIndex2 = nextVertexIndex(vertexIndex1, nVertices, clockwise);
+    unsigned lastVertexIndex = (clockwise) ? 0 : nVertices - 1;
+
+    while (vertexIndex2 != lastVertexIndex && areCoincidentPoints(vertexAt(vertexIndex1), vertexAt(vertexIndex2)))
+        vertexIndex2 = nextVertexIndex(vertexIndex2, nVertices, clockwise);
+
+    while (vertexIndex2 != lastVertexIndex) {
+        unsigned vertexIndex3 = nextVertexIndex(vertexIndex2, nVertices, clockwise);
+        if (!areCollinearPoints(vertexAt(vertexIndex1), vertexAt(vertexIndex2), vertexAt(vertexIndex3)))
+            break;
+        vertexIndex2 = vertexIndex3;
+    }
+
+    return vertexIndex2;
+}
+
 ExclusionPolygon::ExclusionPolygon(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule)
     : ExclusionShape()
     , m_vertices(vertices)
@@ -59,19 +98,42 @@
     if (nVertices)
         m_boundingBox.setLocation(vertexAt(0));
 
-    for (unsigned i = 0; i < nVertices; i++) {
-        const FloatPoint& vertex = vertexAt(i);
-        m_boundingBox.extend(vertex);
-        m_edges[i].polygon = this;
-        m_edges[i].vertexIndex1 = i;
-        m_edges[i].vertexIndex2 = (i + 1) % nVertices;
-        m_edges[i].edgeIndex = i;
+    if (m_empty)
+        return;
+
+    unsigned edgeIndex = 0;
+    unsigned vertexIndex1 = 0;
+    do {
+        m_boundingBox.extend(vertexAt(vertexIndex1));
+        unsigned vertexIndex2 = findNextEdgeVertexIndex(vertexIndex1, true);
+        m_edges[edgeIndex].polygon = this;
+        m_edges[edgeIndex].vertexIndex1 = vertexIndex1;
+        m_edges[edgeIndex].vertexIndex2 = vertexIndex2;
+        m_edges[edgeIndex].edgeIndex = edgeIndex;
+        edgeIndex++;
+        vertexIndex1 = vertexIndex2;
+    } while (vertexIndex1);
+
+    if (edgeIndex > 3) {
+        const ExclusionPolygonEdge& firstEdge = m_edges[0];
+        const ExclusionPolygonEdge& lastEdge = m_edges[edgeIndex - 1];
+        if (areCollinearPoints(lastEdge.vertex1(), lastEdge.vertex2(), firstEdge.vertex2())) {
+            m_edges[0].vertexIndex1 = lastEdge.vertexIndex1;
+            edgeIndex--;
+        }
     }
 
+    m_edges.resize(edgeIndex);
+    m_empty = m_edges.size() < 3;
+
+    if (m_empty)
+        return;
+
     for (unsigned i = 0; i < m_edges.size(); i++) {
         ExclusionPolygonEdge* edge = &m_edges[i];
         m_edgeTree.add(EdgeInterval(edge->minY(), edge->maxY(), edge));
     }
+
 }
 
 static bool computeXIntersection(const ExclusionPolygonEdge* edgePointer, float y, EdgeIntersection& result)

Modified: trunk/Source/WebCore/rendering/ExclusionPolygon.h (133489 => 133490)


--- trunk/Source/WebCore/rendering/ExclusionPolygon.h	2012-11-05 17:37:13 UTC (rev 133489)
+++ trunk/Source/WebCore/rendering/ExclusionPolygon.h	2012-11-05 17:53:01 UTC (rev 133490)
@@ -70,6 +70,7 @@
 private:
     void computeXIntersections(float y, Vector<ExclusionInterval>&) const;
     void computeEdgeIntersections(float minY, float maxY, Vector<ExclusionInterval>&) const;
+    unsigned findNextEdgeVertexIndex(unsigned vertexIndex1, bool clockwise) const;
 
     typedef PODInterval<float, ExclusionPolygonEdge*> EdgeInterval;
     typedef PODIntervalTree<float, ExclusionPolygonEdge*> EdgeIntervalTree;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to