@@ -137,7 +137,8 @@ class SimplifyPath
137137 double width = 0.0 , double height = 0.0 ) :
138138 m_source (&source), m_quantize(quantize), m_simplify(simplify),
139139 m_width (width + 1.0 ), m_height(height + 1.0 ), m_queue_read(0 ), m_queue_write(0 ),
140- m_moveto (true ), m_lastx(0.0 ), m_lasty(0.0 ), m_clipped(false ),
140+ m_moveto (true ), m_after_moveto(false ),
141+ m_lastx (0.0 ), m_lasty(0.0 ), m_clipped(false ),
141142 m_do_clipping (width > 0.0 && height > 0.0 ),
142143 m_origdx (0.0 ), m_origdy(0.0 ),
143144 m_origdNorm2 (0.0 ), m_dnorm2Max(0.0 ), m_dnorm2Min(0.0 ),
@@ -205,6 +206,7 @@ class SimplifyPath
205206 *y = front.y ;
206207#if DEBUG_SIMPLIFY
207208 printf ((cmd == agg::path_cmd_move_to) ? " |" : " -" );
209+ printf (" 1 %f %f\n " , *x, *y);
208210#endif
209211 return cmd;
210212 }
@@ -239,18 +241,40 @@ class SimplifyPath
239241
240242 // if we are starting a new path segment, move to the first point
241243 // + init
242- if (m_moveto)
244+
245+ #if DEBUG_SIMPLIFY
246+ printf (" x, y, code: %f, %f, %d\n " , *x, *y, cmd);
247+ #endif
248+ if (m_moveto || cmd == agg::path_cmd_move_to)
243249 {
250+ // m_moveto check is not generally needed because
251+ // m_source generates an initial moveto; but it
252+ // is retained for safety in case circumstances
253+ // arise where this is not true.
254+ if (m_origdNorm2 && !m_after_moveto)
255+ {
256+ // m_origdNorm2 is nonzero only if we have a vector;
257+ // the m_after_moveto check ensures we push this
258+ // vector to the queue only once.
259+ _push (x,y);
260+ }
261+ m_after_moveto = true ;
244262 m_lastx = *x;
245263 m_lasty = *y;
246264 m_moveto = false ;
247265 m_origdNorm2 = 0.0 ;
248- #if DEBUG_SIMPLIFY
249- m_pushed++;
250- printf (" |" );
251- #endif
252- return agg::path_cmd_move_to;
266+ // A moveto resulting from a nan yields a missing
267+ // line segment, hence a break in the line, just
268+ // like clipping, so we treat it the same way.
269+ m_clipped = true ;
270+ if (m_queue_read < m_queue_write)
271+ {
272+ // If we did a push, empty the queue now.
273+ break ;
274+ }
275+ continue ;
253276 }
277+ m_after_moveto = false ;
254278
255279 // Don't render line segments less than one pixel long
256280 if (fabs (*x - m_lastx) < 1.0 && fabs (*y - m_lasty) < 1.0 )
@@ -295,7 +319,7 @@ class SimplifyPath
295319 m_origdy = *y - m_lasty;
296320 m_origdNorm2 = m_origdx*m_origdx + m_origdy*m_origdy;
297321
298- // set all the variables to reflect this new orig vecor
322+ // set all the variables to reflect this new orig vector
299323 m_dnorm2Max = m_origdNorm2;
300324 m_dnorm2Min = 0.0 ;
301325 m_haveMin = false ;
@@ -376,54 +400,16 @@ class SimplifyPath
376400#endif
377401 continue ;
378402 }
379-
380403 // if we get here, then this vector was not similar enough to the
381404 // line we are building, so we need to draw that line and start the
382405 // next one.
383406
384407 // if the line needs to extend in the opposite direction from the
385408 // direction we are drawing in, move back to we start drawing from
386409 // back there.
387- if (m_haveMin)
388- {
389- m_queue[m_queue_write++].set (agg::path_cmd_line_to, m_minX, m_minY);
390- }
391- m_queue[m_queue_write++].set (agg::path_cmd_line_to, m_maxX, m_maxY);
392410
393- // if we clipped some segments between this line and the next line
394- // we are starting, we also need to move to the last point.
395- if (m_clipped) {
396- m_queue[m_queue_write++].set (agg::path_cmd_move_to, m_lastx, m_lasty);
397- }
398- else if (!m_lastMax)
399- {
400- // if the last line was not the longest line, then move back to
401- // the end point of the last line in the sequence. Only do this
402- // if not clipped, since in that case lastx,lasty is not part of
403- // the line just drawn.
404-
405- // Would be move_to if not for the artifacts
406- m_queue[m_queue_write++].set (agg::path_cmd_line_to, m_lastx, m_lasty);
407- }
411+ _push (x, y);
408412
409- // now reset all the variables to get ready for the next line
410- m_origdx = *x - m_lastx;
411- m_origdy = *y - m_lasty;
412- m_origdNorm2 = m_origdx*m_origdx + m_origdy*m_origdy;
413-
414- m_dnorm2Max = m_origdNorm2;
415- m_dnorm2Min = 0.0 ;
416- m_haveMin = false ;
417- m_lastMax = true ;
418- m_lastx = m_maxX = *x;
419- m_lasty = m_maxY = *y;
420- m_lastWrittenX = m_minX = m_lastx;
421- m_lastWrittenY = m_minY = m_lasty;
422-
423- m_clipped = false ;
424- #if DEBUG_SIMPLIFY
425- m_pushed += m_queue_write - m_queue_read;
426- #endif
427413 break ;
428414 }
429415
@@ -453,6 +439,8 @@ class SimplifyPath
453439 *y = front.y ;
454440#if DEBUG_SIMPLIFY
455441 printf ((cmd == agg::path_cmd_move_to) ? " |" : " -" );
442+ printf (" 3 %f %f\n " , *x, *y);
443+
456444#endif
457445 return cmd;
458446 }
@@ -489,6 +477,7 @@ class SimplifyPath
489477 item m_queue[6 ];
490478
491479 bool m_moveto;
480+ bool m_after_moveto;
492481 double m_lastx, m_lasty;
493482 bool m_clipped;
494483 bool m_do_clipping;
@@ -512,6 +501,52 @@ class SimplifyPath
512501 unsigned m_pushed;
513502 unsigned m_skipped;
514503#endif
504+
505+ void _push (double * x, double * y)
506+ {
507+ if (m_haveMin)
508+ {
509+ m_queue[m_queue_write++].set (agg::path_cmd_line_to, m_minX, m_minY);
510+ }
511+ m_queue[m_queue_write++].set (agg::path_cmd_line_to, m_maxX, m_maxY);
512+
513+ // if we clipped some segments between this line and the next line
514+ // we are starting, we also need to move to the last point.
515+ if (m_clipped) {
516+ m_queue[m_queue_write++].set (agg::path_cmd_move_to, m_lastx, m_lasty);
517+ }
518+ else if (!m_lastMax)
519+ {
520+ // if the last line was not the longest line, then move back to
521+ // the end point of the last line in the sequence. Only do this
522+ // if not clipped, since in that case lastx,lasty is not part of
523+ // the line just drawn.
524+
525+ // Would be move_to if not for the artifacts
526+ m_queue[m_queue_write++].set (agg::path_cmd_line_to, m_lastx, m_lasty);
527+ }
528+
529+ // now reset all the variables to get ready for the next line
530+ m_origdx = *x - m_lastx;
531+ m_origdy = *y - m_lasty;
532+ m_origdNorm2 = m_origdx*m_origdx + m_origdy*m_origdy;
533+
534+ m_dnorm2Max = m_origdNorm2;
535+ m_dnorm2Min = 0.0 ;
536+ m_haveMin = false ;
537+ m_lastMax = true ;
538+ m_lastx = m_maxX = *x;
539+ m_lasty = m_maxY = *y;
540+ m_lastWrittenX = m_minX = m_lastx;
541+ m_lastWrittenY = m_minY = m_lasty;
542+
543+ m_clipped = false ;
544+ #if DEBUG_SIMPLIFY
545+ m_pushed += m_queue_write - m_queue_read;
546+ #endif
547+
548+ }
549+
515550};
516551
517552#endif // __AGG_PY_PATH_ITERATOR_H__
0 commit comments