@@ -336,6 +336,7 @@ class PathClipper : public EmbeddedQueue<3>
336
336
double m_initX;
337
337
double m_initY;
338
338
bool m_has_init;
339
+ bool m_was_clipped;
339
340
340
341
public:
341
342
PathClipper (VertexSource &source, bool do_clipping, double width, double height)
@@ -347,7 +348,8 @@ class PathClipper : public EmbeddedQueue<3>
347
348
m_moveto(true ),
348
349
m_initX(nan(" " )),
349
350
m_initY(nan(" " )),
350
- m_has_init(false )
351
+ m_has_init(false ),
352
+ m_was_clipped(false )
351
353
{
352
354
// empty
353
355
}
@@ -361,7 +363,8 @@ class PathClipper : public EmbeddedQueue<3>
361
363
m_moveto(true ),
362
364
m_initX(nan(" " )),
363
365
m_initY(nan(" " )),
364
- m_has_init(false )
366
+ m_has_init(false ),
367
+ m_was_clipped(false )
365
368
{
366
369
m_cliprect.x1 -= 1.0 ;
367
370
m_cliprect.y1 -= 1.0 ;
@@ -372,21 +375,29 @@ class PathClipper : public EmbeddedQueue<3>
372
375
inline void rewind (unsigned path_id)
373
376
{
374
377
m_has_init = false ;
378
+ m_was_clipped = false ;
375
379
m_moveto = true ;
376
380
m_source->rewind (path_id);
377
381
}
378
382
379
- int draw_clipped_line (double x0, double y0, double x1, double y1)
383
+ int draw_clipped_line (double x0, double y0, double x1, double y1,
384
+ bool closed=false )
380
385
{
381
386
unsigned moved = agg::clip_line_segment (&x0, &y0, &x1, &y1, m_cliprect);
382
387
// moved >= 4 - Fully clipped
383
388
// moved & 1 != 0 - First point has been moved
384
389
// moved & 2 != 0 - Second point has been moved
390
+ m_was_clipped = m_was_clipped || (moved != 0 );
385
391
if (moved < 4 ) {
386
392
if (moved & 1 || m_moveto) {
387
393
queue_push (agg::path_cmd_move_to, x0, y0);
388
394
}
389
395
queue_push (agg::path_cmd_line_to, x1, y1);
396
+ if (closed && !m_was_clipped) {
397
+ // Close the path only if the end point hasn't moved.
398
+ queue_push (agg::path_cmd_end_poly | agg::path_flags_close,
399
+ x1, y1);
400
+ }
390
401
391
402
m_moveto = false ;
392
403
return 1 ;
@@ -417,12 +428,23 @@ class PathClipper : public EmbeddedQueue<3>
417
428
switch (code) {
418
429
case (agg::path_cmd_end_poly | agg::path_flags_close):
419
430
if (m_has_init) {
420
- draw_clipped_line (m_lastX, m_lastY, m_initX, m_initY);
431
+ // Queue the line from last point to the initial point, and
432
+ // if never clipped, add a close code.
433
+ draw_clipped_line (m_lastX, m_lastY, m_initX, m_initY,
434
+ true );
435
+ } else {
436
+ // An empty path that is immediately closed.
437
+ queue_push (
438
+ agg::path_cmd_end_poly | agg::path_flags_close,
439
+ m_lastX, m_lastY);
421
440
}
422
- queue_push (
423
- agg::path_cmd_end_poly | agg::path_flags_close,
424
- m_lastX, m_lastY);
425
- goto exit_loop;
441
+ // If paths were not clipped, then the above code queued
442
+ // something, and we should exit the loop. Otherwise, continue
443
+ // to the next point, as there may be a new subpath.
444
+ if (queue_nonempty ()) {
445
+ goto exit_loop;
<
7D35
td data-grid-cell-id="diff-36d69dfa667beb67da44e7bc61c9e0ca35deea173c1cb43e77637c7cbcb4a939-425-446-0" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionNum-bgColor, var(--diffBlob-addition-bgColor-num));text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative left-side">
446
+ }
447
+ break ;
426
448
427
449
case agg::path_cmd_move_to:
428
450
@@ -444,6 +466,7 @@ class PathClipper : public EmbeddedQueue<3>
444
466
m_initY = m_lastY = *y;
445
467
m_has_init = true ;
446
468
m_moveto = true ;
469
+ m_was_clipped = false ;
447
470
// if the last command was moveto exit the loop to emit the code
448
471
if (emit_moveto) {
449
472
goto exit_loop;
0 commit comments