@@ -278,33 +278,25 @@ class PathNanRemover : protected EmbeddedQueue<4>
278
278
clipped, but are always included in their entirety.
279
279
*/
280
280
template <class VertexSource >
281
- class PathClipper
281
+ class PathClipper : public EmbeddedQueue < 3 >
282
282
{
283
283
VertexSource *m_source;
284
284
bool m_do_clipping;
285
285
agg::rect_base<double > m_cliprect;
286
286
double m_lastX;
287
287
double m_lastY;
288
288
bool m_moveto;
289
- double m_nextX;
290
- double m_nextY;
291
- bool m_has_next;
292
- bool m_end_poly;
293
289
double m_initX;
294
290
double m_initY;
295
291
bool m_has_init;
296
- bool m_broke_path;
297
292
298
293
public:
299
294
PathClipper (VertexSource &source, bool do_clipping, double width, double height)
300
295
: m_source(&source),
301
296
m_do_clipping (do_clipping),
302
297
m_cliprect(-1.0 , -1.0 , width + 1.0 , height + 1.0 ),
303
298
m_moveto(true ),
304
- m_has_next(false ),
305
- m_end_poly(false ),
306
- m_has_init(false ),
307
- m_broke_path(false )
299
+ m_has_init(false )
308
300
{
309
301
// empty
310
302
}
@@ -314,10 +306,7 @@ class PathClipper
314
306
m_do_clipping(do_clipping),
315
307
m_cliprect(rect),
316
308
m_moveto(true ),
317
- m_has_next(false ),
318
- m_end_poly(false ),
319
- m_has_init(false ),
320
- m_broke_path(false )
309
+ m_has_init(false )
321
310
{
322
311
m_cliprect.x1 -= 1.0 ;
323
312
m_cliprect.y1 -= 1.0 ;
@@ -327,86 +316,100 @@ class PathClipper
327
316
328
317
inline void rewind (unsigned path_id)
329
318
{
330
- m_has_next = false ;
319
+ m_has_init = false ;
331
320
m_moveto = true ;
332
321
m_source->rewind (path_id);
333
322
}
334
323
324
+ int draw_clipped_line (double x0, double y0, double x1, double y1)
325
+ {
326
+ unsigned moved = agg::clip_line_segment (&x0, &y0 , &x1, &y1 , m_cliprect);
327
+ // moved >= 4 - Fully clipped
328
+ // moved & 1 != 0 - First point has been moved
329
+ // moved & 2 != 0 - Second point has been moved
330
+ if (moved < 4 ) {
331
+ if (moved & 1 || m_moveto) {
332
+ queue_push (agg::path_cmd_move_to, x0, y0 );
333
+ }
334
+ queue_push (agg::path_cmd_line_to, x1, y1 );
335
+
336
+ m_moveto = false ;
337
+ return 1 ;
338
+ }
339
+
340
+ return 0 ;
341
+ }
342
+
335
343
unsigned vertex (double *x, double *y)
336
344
{
337
345
unsigned code;
338
346
339
347
if (m_do_clipping) {
340
348
/* This is the slow path where we actually do clipping */
341
349
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;
350
+ if (queue_pop (&code, x, y)) {
351
+ return code;
352
352
}
353
353
354
354
while ((code = m_source->vertex (x, y)) != agg::path_cmd_stop) {
355
- if (code == (agg::path_cmd_end_poly | agg::path_flags_close)) {
355
+ switch (code) {
356
+ case (agg::path_cmd_end_poly | agg::path_flags_close):
356
357
if (m_has_init) {
357
- *x = m_initX;
358
- *y = m_initY;
359
- code = agg::path_cmd_line_to;
360
- m_end_poly = true ;
361
- } else {
362
- continue ;
358
+ draw_clipped_line (m_lastX, m_lastY, m_initX, m_initY);
363
359
}
364
- }
365
-
366
- if (code == agg::path_cmd_move_to) {
367
- m_initX = *x;
368
- m_initY = *y;
360
+ queue_push (
361
+ agg::path_cmd_end_poly | agg::path_flags_close,
362
+ m_lastX, m_lastY);
363
+ goto exit_loop;
364
+
365
+ case agg::path_cmd_move_to:
366
+ m_initX = m_lastX = *x;
367
+ m_initY = m_lastY = *y;
369
368
m_has_init = true ;
370
369
m_moveto = true ;
371
- }
372
- if (m_moveto) {
373
- m_moveto = false ;
374
- code = agg::path_cmd_move_to;
375
370
break ;
376
- } else if (code == agg::path_cmd_line_to) {
377
- double x0, y0 , x1, y1 ;
378
- x0 = m_lastX;
379
- y0 = m_lastY;
380
- x1 = *x;
381
- y1 = *y;
371
+
372
+ case agg::path_cmd_line_to:
373
+ if (draw_clipped_line (m_lastX, m_lastY, *x, *y)) {
374
+ m_lastX = *x;
375
+ m_lastY = *y;
376
+ goto exit_loop;
377
+ }
382
378
m_lastX = *x;
383
379
m_lastY = *y;
384
- unsigned moved = agg::clip_line_segment (&x0, &y0 , &x1, &y1 , m_cliprect);
385
- // moved >= 4 - Fully clipped
386
- // moved & 1 != 0 - First point has been moved
387
- // moved & 2 != 0 - Second point has been moved
388
- 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;
397
- }
398
- *x = x1;
399
- *y = y1 ;
400
- return code;
401
- }
402
- } else {
403
380
break ;
381
+
382
+ default :
383
+ if (m_moveto) {
384
+ queue_push (agg::path_cmd_move_to, m_lastX, m_lastY);
385
+ m_moveto = false ;
386
+ }
387
+
388
+ queue_push (code, *x, *y);
389
+ m_lastX = *x;
390
+ m_lastY = *y;
391
+ goto exit_loop;
404
392
}
405
393
}
406
394
407
- m_lastX = *x;
408
- m_lastY = *y;
409
- return code;
395
+ exit_loop:
396
+
397
+ if (queue_pop (&code, x, y)) {
398
+ return code;
399
+ }
400
+
401
+ if (m_moveto &&
402
+ m_lastX >= m_cliprect.x1 &&
403
+ m_lastX <= m_cliprect.x2 &&
404
+ m_lastY >= m_cliprect.y1 &&
405
+ m_lastY <= m_cliprect.y2 ) {
406
+ *x = m_lastX;
407
+ *y = m_lastY;
408
+ m_moveto = false ;
409
+ return agg::path_cmd_move_to;
410
+ }
411
+
412
+ return agg::path_cmd_stop;
410
413
} else {
411
414
// If not doing any clipping, just pass along the vertices
412
415
// verbatim
0 commit comments