Commit a264d55e authored by Jason Davies's avatar Jason Davies
Browse files

Don’t generate empty polygons during clipping.

Fixes #1823; spurious closePath events were being generated for
degenerate polygons due to generation of empty polygons and rings in
rare cases.
parent fa55eead
...@@ -3224,7 +3224,6 @@ ...@@ -3224,7 +3224,6 @@
clip.lineEnd = ringEnd; clip.lineEnd = ringEnd;
segments = []; segments = [];
polygon = []; polygon = [];
listener.polygonStart();
}, },
polygonEnd: function() { polygonEnd: function() {
clip.point = point; clip.point = point;
...@@ -3233,13 +3232,15 @@ ...@@ -3233,13 +3232,15 @@
segments = d3.merge(segments); segments = d3.merge(segments);
var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon);
if (segments.length) { if (segments.length) {
if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener);
} else if (clipStartInside) { } else if (clipStartInside) {
if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
listener.lineStart(); listener.lineStart();
interpolate(null, null, 1, listener); interpolate(null, null, 1, listener);
listener.lineEnd(); listener.lineEnd();
} }
listener.polygonEnd(); if (polygonStarted) listener.polygonEnd(), polygonStarted = false;
segments = polygon = null; segments = polygon = null;
}, },
sphere: function() { sphere: function() {
...@@ -3267,7 +3268,7 @@ ...@@ -3267,7 +3268,7 @@
line.lineEnd(); line.lineEnd();
} }
var segments; var segments;
var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygon, ring; var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring;
function pointRing(λ, φ) { function pointRing(λ, φ) {
ring.push([ λ, φ ]); ring.push([ λ, φ ]);
var point = rotate(λ, φ); var point = rotate(λ, φ);
...@@ -3288,9 +3289,12 @@ ...@@ -3288,9 +3289,12 @@
if (clean & 1) { if (clean & 1) {
segment = ringSegments[0]; segment = ringSegments[0];
var n = segment.length - 1, i = -1, point; var n = segment.length - 1, i = -1, point;
listener.lineStart(); if (n > 0) {
while (++i < n) listener.point((point = segment[i])[0], point[1]); if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
listener.lineEnd(); listener.lineStart();
while (++i < n) listener.point((point = segment[i])[0], point[1]);
listener.lineEnd();
}
return; return;
} }
if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -18,7 +18,6 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { ...@@ -18,7 +18,6 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
clip.lineEnd = ringEnd; clip.lineEnd = ringEnd;
segments = []; segments = [];
polygon = []; polygon = [];
listener.polygonStart();
}, },
polygonEnd: function() { polygonEnd: function() {
clip.point = point; clip.point = point;
...@@ -28,13 +27,15 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { ...@@ -28,13 +27,15 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
segments = d3.merge(segments); segments = d3.merge(segments);
var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon);
if (segments.length) { if (segments.length) {
if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener);
} else if (clipStartInside) { } else if (clipStartInside) {
if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
listener.lineStart(); listener.lineStart();
interpolate(null, null, 1, listener); interpolate(null, null, 1, listener);
listener.lineEnd(); listener.lineEnd();
} }
listener.polygonEnd(); if (polygonStarted) listener.polygonEnd(), polygonStarted = false;
segments = polygon = null; segments = polygon = null;
}, },
sphere: function() { sphere: function() {
...@@ -61,6 +62,7 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { ...@@ -61,6 +62,7 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
var buffer = d3_geo_clipBufferListener(), var buffer = d3_geo_clipBufferListener(),
ringListener = clipLine(buffer), ringListener = clipLine(buffer),
polygonStarted = false,
polygon, polygon,
ring; ring;
...@@ -96,9 +98,12 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { ...@@ -96,9 +98,12 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
var n = segment.length - 1, var n = segment.length - 1,
i = -1, i = -1,
point; point;
listener.lineStart(); if (n > 0) {
while (++i < n) listener.point((point = segment[i])[0], point[1]); if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
listener.lineEnd(); listener.lineStart();
while (++i < n) listener.point((point = segment[i])[0], point[1]);
listener.lineEnd();
}
return; return;
} }
......
...@@ -386,6 +386,10 @@ suite.addBatch({ ...@@ -386,6 +386,10 @@ suite.addBatch({
"renders a small circle of 120°": function(p) { "renders a small circle of 120°": function(p) {
p(_.geo.circle().angle(120)()); p(_.geo.circle().angle(120)());
assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 87, y: 700}]); assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 87, y: 700}]);
},
"degenerate polygon": function(p) {
p({type: "Polygon", coordinates: [[[0, 0], [0, 0], [0, 0], [0, 0]]]});
assert.deepEqual(testContext.buffer(), []);
} }
}, },
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment