@@ -26,6 +26,8 @@ struct XY
2626 double x;
2727 double y;
2828
29+ XY () : x(0 ), y(0 ) {}
30+
2931 XY (double x_, double y_) : x(x_), y(y_)
3032 {
3133 }
@@ -521,12 +523,14 @@ struct bisectx
521523 {
522524 }
523525
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
525527 {
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+ };
530534 }
531535};
532536
@@ -536,9 +540,9 @@ struct xlt : public bisectx
536540 {
537541 }
538542
539- inline bool is_inside (double x, double y ) const
543+ inline bool is_inside (const XY point ) const
540544 {
541- return x <= m_x;
545+ return point. x <= m_x;
542546 }
543547};
544548
@@ -548,9 +552,9 @@ struct xgt : public bisectx
548552 {
549553 }
550554
551- inline bool is_inside (double x, double y ) const
555+ inline bool is_inside (const XY point ) const
552556 {
553- return x >= m_x;
557+ return point. x >= m_x;
554558 }
555559};
556560
@@ -562,12 +566,14 @@ struct bisecty
562566 {
563567 }
564568
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
566570 {
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+ };
571577 }
572578};
573579
@@ -577,9 +583,9 @@ struct ylt : public bisecty
577583 {
578584 }
579585
580- inline bool is_inside (double x, double y ) const
586+ inline bool is_inside (const XY point ) const
581587 {
582- return y <= m_y;
588+ return point. y <= m_y;
583589 }
584590};
585591
@@ -589,9 +595,9 @@ struct ygt : public bisecty
589595 {
590596 }
591597
592- inline bool is_inside (double x, double y ) const
598+ inline bool is_inside (const XY point ) const
593599 {
594- return y >= m_y;
600+ return point. y >= m_y;
595601 }
596602};
597603}
@@ -606,46 +612,30 @@ inline void clip_to_rect_one_step(const Polygon &polygon, Polygon &result, const
606612 return ;
607613 }
608614
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 );
613619
614620 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));
618622 }
619623
620624 if (pinside) {
621- result.emplace_back (px, py );
625+ result.emplace_back (p );
622626 }
623627
624- sx = px;
625- sy = py;
628+ s = p;
626629 }
627630}
628631
629632template <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)
632635{
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 ;
649639
650640 if (!inside) {
651641 std::swap (xmin, xmax);
@@ -656,26 +646,27 @@ clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vecto
656646 curve_t curve (path);
657647
658648 Polygon polygon1, polygon2;
659- double x = 0 , y = 0 ;
649+ XY point ;
660650 unsigned code = 0 ;
661651 curve.rewind (0 );
652+ std::vector<Polygon> results;
662653
663654 do {
664655 // Grab the next subpath and store it in polygon1
665656 polygon1.clear ();
666657 do {
667658 if (code == agg::path_cmd_move_to) {
668- polygon1.emplace_back (x, y );
659+ polygon1.emplace_back (point );
669660 }
670661
671- code = curve.vertex (&x, &y);
662+ code = curve.vertex (&point. x , &point. y );
672663
673664 if (code == agg::path_cmd_stop) {
674665 break ;
675666 }
676667
677668 if (code != agg::path_cmd_move_to) {
678- polygon1.emplace_back (x, y );
669+ polygon1.emplace_back (point );
679670 }
680671 } while ((code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
681672
@@ -694,6 +685,8 @@ clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vecto
694685 } while (code != agg::path_cmd_stop);
695686
696687 _finalize_polygon (results, true );
688+
689+ return results;
697690}
698691
699692template <class VerticesArray , class ResultArray >
0 commit comments