@@ -26,6 +26,8 @@ struct XY
26
26
double x;
27
27
double y;
28
28
29
+ XY () : x(0 ), y(0 ) {}
30
+
29
31
XY (double x_, double y_) : x(x_), y(y_)
30
32
{
31
33
}
@@ -521,12 +523,14 @@ struct bisectx
521
523
{
522
524
}
523
525
524
- inline void bisect (double sx, double sy, double px, double py, double *bx, double *by ) const
526
+ inline XY bisect (const XY s, const XY p ) const
525
527
{
526
- *bx = m_x;
527
- double dx = px - sx;
528
- double dy = py - sy;
529
- *by = sy + dy * ((m_x - sx) / dx);
528
+ double dx = p.x - s.x ;
529
+ double dy = p.y - s.y ;
530
+ return {
531
+ m_x,
532
+ s.y + dy * ((m_x - s.x ) / dx),
533
+ };
530
534
}
531
535
};
532
536
@@ -536,9 +540,9 @@ struct xlt : public bisectx
536
540
{
537
541
}
538
542
539
- inline bool is_inside (double x, double y ) const
543
+ inline bool is_inside (const XY point ) const
540
544
{
541
- return x <= m_x;
545
+ return point. x <= m_x;
542
546
}
543
547
};
544
548
@@ -548,9 +552,9 @@ struct xgt : public bisectx
548
552
{
549
553
}
550
554
551
- inline bool is_inside (double x, double y ) const
555
+ inline bool is_inside (const XY point ) const
552
556
{
553
- return x >= m_x;
557
+ return point. x >= m_x;
554
558
}
555
559
};
556
560
@@ -562,12 +566,14 @@ struct bisecty
562
566
{
563
567
}
564
568
565
- inline void bisect (double sx, double sy, double px, double py, double *bx, double *by ) const
569
+ inline XY bisect (const XY s, const XY p ) const
566
570
{
567
- *by = m_y;
568
- double dx = px - sx;
569
- double dy = py - sy;
570
- *bx = sx + dx * ((m_y - sy) / dy);
571
+ double dx = p.x - s.x ;
572
+ double dy = p.y - s.y ;
573
+ return {
574
+ s.x + dx * ((m_y - s.y ) / dy),
575
+ m_y,
576
+ };
571
577
}
572
578
};
573
579
@@ -577,9 +583,9 @@ struct ylt : public bisecty
577
583
{
578
584
}
579
585
580
- inline bool is_inside (double x, double y ) const
586
+ inline bool is_inside (const XY point ) const
581
587
{
582
- return y <= m_y;
588
+ return point. y <= m_y;
583
589
}
584
590
};
585
591
@@ -589,9 +595,9 @@ struct ygt : public bisecty
589
595
{
590
596
}
591
597
592
- inline bool is_inside (double x, double y ) const
598
+ inline bool is_inside (const XY point ) const
593
599
{
594
- return y >= m_y;
600
+ return point. y >= m_y;
595
601
}
596
602
};
597
603
}
@@ -606,46 +612,30 @@ inline void clip_to_rect_one_step(const Polygon &polygon, Polygon &result, const
606
612
return ;
607
613
}
608
614
609
- auto [sx, sy] = polygon.back ();
610
- for (auto [px, py] : polygon) {
611
- sinside = filter.is_inside (sx, sy );
612
- pinside = filter.is_inside (px, py );
615
+ auto s = polygon.back ();
616
+ for (auto p : polygon) {
617
+ sinside = filter.is_inside (s );
618
+ pinside = filter.is_inside (p );
613
619
614
620
if (sinside ^ pinside) {
615
- double bx, by;
616
- filter.bisect (sx, sy, px, py, &bx, &by);
617
- result.emplace_back (bx, by);
621
+ result.emplace_back (filter.bisect (s, p));
618
622
}
619
623
620
624
if (pinside) {
621
- result.emplace_back (px, py );
625
+ result.emplace_back (p );
622
626
}
623
627
624
- sx = px;
625
- sy = py;
628
+ s = p;
626
629
}
627
630
}
628
631
629
632
template <class PathIterator >
630
- void
631
- clip_path_to_rect (PathIterator &path, agg::rect_d &rect, bool inside, std::vector<Polygon> &results )
633
+ auto
634
+ clip_path_to_rect (PathIterator &path, agg::rect_d &rect, bool inside)
632
635
{
633
- double xmin, ymin, xmax, ymax;
634
- if (rect.x1 < rect.x2 ) {
635
- xmin = rect.x1 ;
636
- xmax = rect.x2 ;
637
- } else {
638
- xmin = rect.x2 ;
639
- xmax = rect.x1 ;
640
- }
641
-
642
- if (rect.y1 < rect.y2 ) {
643
- ymin = rect.y1 ;
644
- ymax = rect.y2 ;
645
- } else {
646
- ymin = rect.y2 ;
647
- ymax = rect.y1 ;
648
- }
636
+ rect.normalize ();
637
+ auto xmin = rect.x1 , xmax = rect.x2 ;
638
+ auto ymin = rect.y1 , ymax = rect.y2 ;
649
639
650
640
if (!inside) {
651
641
std::swap (xmin, xmax);
@@ -656,26 +646,27 @@ clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vecto
656
646
curve_t curve (path);
657
647
658
648
Polygon polygon1, polygon2;
659
- double x = 0 , y = 0 ;
649
+ XY point ;
660
650
unsigned code = 0 ;
661
651
curve.rewind (0 );
652
+ std::vector<Polygon> results;
662
653
663
654
do {
664
655
// Grab the next subpath and store it in polygon1
665
656
polygon1.clear ();
666
657
do {
667
658
if (code == agg::path_cmd_move_to) {
668
- polygon1.emplace_back (x, y );
659
+ polygon1.emplace_back (point );
669
660
}
670
661
671
- code = curve.vertex (&x, &y);
662
+ code = curve.vertex (&point. x , &point. y );
672
663
673
664
if (code == agg::path_cmd_stop) {
674
665
break ;
675
666
}
676
667
677
668
if (code != agg::path_cmd_move_to) {
678
- polygon1.emplace_back (x, y );
669
+ polygon1.emplace_back (point );
679
670
}
680
671
} while ((code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
681
672
@@ -694,6 +685,8 @@ clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vecto
694
685
} while (code != agg::path_cmd_stop);
695
686
696
687
_finalize_polygon (results, true );
688
+
689
+ return results;
697
690
}
698
691
699
692
template <class VerticesArray , class ResultArray >
0 commit comments