+ std::vector<Bezier> ClipToRectangle(const BRect & r)
+ {
+ // Find points of intersection with the rectangle.
+ Debug("Clipping Bezier to BRect %s", r.Str().c_str());
+
+ bool isVerticalLine = (x0 == x1 && x1 == x2 && x2 == x3);
+ bool isHorizontalLine = (y0 == y1 && y1 == y2 && y2 == y3);
+
+ // Find its roots.
+
+ std::vector<BReal> intersection;
+
+ if (!isVerticalLine)
+ {
+ std::vector<BReal> x_intersection = SolveXParam(r.x);
+ intersection.insert(intersection.end(), x_intersection.begin(), x_intersection.end());
+
+ // And for the other side.
+
+ std::vector<BReal> x_intersection_pt2 = SolveXParam(r.x + r.w);
+ intersection.insert(intersection.end(), x_intersection_pt2.begin(), x_intersection_pt2.end());
+ }
+
+ // Find its roots.
+ if (!isHorizontalLine)
+ {
+ std::vector<BReal> y_intersection = SolveYParam(r.y);
+ intersection.insert(intersection.end(), y_intersection.begin(), y_intersection.end());
+
+ std::vector<BReal> y_intersection_pt2 = SolveYParam(r.y+r.h);
+ intersection.insert(intersection.end(), y_intersection_pt2.begin(), y_intersection_pt2.end());
+ }
+
+ // Merge and sort.
+ intersection.push_back(BReal(0));
+ intersection.push_back(BReal(1));
+ std::sort(intersection.begin(), intersection.end());
+
+ std::vector<Bezier> all_beziers;
+ if (intersection.size() <= 2)
+ {
+ all_beziers.push_back(*this);
+ return all_beziers;
+ }
+ BReal t0 = *(intersection.begin());
+ for (auto it = intersection.begin()+1; it != intersection.end(); ++it)
+ {
+ BReal t1 = *it;
+ if (t1 == t0) continue;
+ //Debug(" -- t0: %f to t1: %f: %f", Double(t0), Double(t1), Double((t1 + t0)/BReal(2)));
+ BReal ptx, pty;
+ Evaluate(ptx, pty, ((t1 + t0) / BReal(2)));
+ if (r.PointIn(ptx, pty))
+ {
+ //Debug("Adding segment: (point at %f, %f)", Double(ptx), Double(pty));
+ all_beziers.push_back(this->ReParametrise(t0, t1));
+ }
+ else
+ {
+ //Debug("Segment removed (point at %f, %f)", Double(ptx), Double(pty));
+ }
+ t0 = t1;
+ }
+ return all_beziers;
+ }