Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1d52371

Browse files
committed
Fix #5895: Properly clip MOVETO commands
1 parent cc1b0c9 commit 1d52371

2 files changed

Lines changed: 39 additions & 37 deletions

File tree

lib/matplotlib/tests/test_simplification.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,12 @@ def test_clipping_with_nans():
212212
ax.set_ylim(-0.25, 0.25)
213213

214214

215+
def test_clipping_full():
216+
p = path.Path([[1e30, 1e30]] * 5)
217+
simplified = list(p.iter_segments(clip=[0, 0, 100, 100]))
218+
assert simplified == []
219+
220+
215221
if __name__=='__main__':
216222
import nose
217223
nose.runmodule(argv=['-s','--with-doctest'], exit=False)

src/path_converters.h

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class PathNanRemover : protected EmbeddedQueue<4>
278278
clipped, but are always included in their entirety.
279279
*/
280280
template <class VertexSource>
281-
class PathClipper
281+
class PathClipper : public EmbeddedQueue<2>
282282
{
283283
VertexSource *m_source;
284284
bool m_do_clipping;
@@ -339,16 +339,8 @@ class PathClipper
339339
if (m_do_clipping) {
340340
/* This is the slow path where we actually do clipping */
341341

342-
if (m_end_poly) {
343-
m_end_poly = false;
344-
return (agg::path_cmd_end_poly | agg::path_flags_close);
345-
}
346-
347-
if (m_has_next) {
348-
m_has_next = false;
349-
*x = m_nextX;
350-
*y = m_nextY;
351-
return agg::path_cmd_line_to;
342+
if (queue_pop(&code, x, y)) {
343+
return code;
352344
}
353345

354346
while ((code = m_source->vertex(x, y)) != agg::path_cmd_stop) {
@@ -358,55 +350,59 @@ class PathClipper
358350
*y = m_initY;
359351
code = agg::path_cmd_line_to;
360352
m_end_poly = true;
361-
} else {
362-
continue;
353+
break;
363354
}
364355
}
365356

366357
if (code == agg::path_cmd_move_to) {
367-
m_initX = *x;
368-
m_initY = *y;
369-
m_has_init = true;
358+
m_lastX = *x;
359+
m_lastY = *y;
370360
m_moveto = true;
371-
}
372-
if (m_moveto) {
373-
m_moveto = false;
374-
code = agg::path_cmd_move_to;
375-
break;
376361
} else if (code == agg::path_cmd_line_to) {
377362
double x0, y0, x1, y1;
378363
x0 = m_lastX;
379364
y0 = m_lastY;
380365
x1 = *x;
381366
y1 = *y;
382-
m_lastX = *x;
383-
m_lastY = *y;
367+
m_lastX = x1;
368+
m_lastY = y1;
384369
unsigned moved = agg::clip_line_segment(&x0, &y0, &x1, &y1, m_cliprect);
385370
// moved >= 4 - Fully clipped
386371
// moved & 1 != 0 - First point has been moved
387372
// moved & 2 != 0 - Second point has been moved
388373
if (moved < 4) {
389-
if (moved & 1) {
390-
*x = x0;
391-
*y = y0;
392-
m_nextX = x1;
393-
m_nextY = y1;
394-
m_has_next = true;
395-
m_broke_path = true;
396-
return agg::path_cmd_move_to;
374+
if (moved & 1 || m_moveto) {
375+
queue_push(agg::path_cmd_move_to, x0, y0);
397376
}
398-
*x = x1;
399-
*y = y1;
400-
return code;
377+
queue_push(agg::path_cmd_line_to, x1, y1);
378+
379+
if (m_moveto) {
380+
m_moveto = false;
381+
m_initX = x0;
382+
m_initY = y0;
383+
m_has_init = true;
384+
}
385+
break;
401386
}
402387
} else {
388+
if (m_moveto) {
389+
queue_push(agg::path_cmd_move_to, m_lastX, m_lastY);
390+
m_moveto = false;
391+
m_initX = m_lastX;
392+
m_initY = m_lastY;
393+
m_has_init = true;
394+
}
395+
396+
queue_push(code, *x, *y);
403397
break;
404398
}
405399
}
406400

407-
m_lastX = *x;
408-
m_lastY = *y;
409-
return code;
401+
if (queue_pop(&code, x, y)) {
402+
return code;
403+
}
404+
405+
return agg::path_cmd_stop;
410406
} else {
411407
// If not doing any clipping, just pass along the vertices
412408
// verbatim

0 commit comments

Comments
 (0)