1
2#pragma once
3
4#include "Vector2.h"
5#include "SignedDistance.h"
6#include "EdgeColor.h"
7
8namespace msdfgen {
9
10// Parameters for iterative search of closest point on a cubic Bezier curve. Increase for higher precision.
11#define MSDFGEN_CUBIC_SEARCH_STARTS 4
12#define MSDFGEN_CUBIC_SEARCH_STEPS 4
13
14/// An abstract edge segment.
15class EdgeSegment {
16
17public:
18 EdgeColor color;
19
20 EdgeSegment(EdgeColor edgeColor = WHITE) : color(edgeColor) { }
21 virtual ~EdgeSegment() { }
22 /// Creates a copy of the edge segment.
23 virtual EdgeSegment * clone() const = 0;
24 /// Returns the point on the edge specified by the parameter (between 0 and 1).
25 virtual Point2 point(double param) const = 0;
26 /// Returns the direction the edge has at the point specified by the parameter.
27 virtual Vector2 direction(double param) const = 0;
28 /// Returns the change of direction (second derivative) at the point specified by the parameter.
29 virtual Vector2 directionChange(double param) const = 0;
30 /// Returns the minimum signed distance between origin and the edge.
31 virtual SignedDistance signedDistance(Point2 origin, double &param) const = 0;
32 /// Converts a previously retrieved signed distance from origin to pseudo-distance.
33 virtual void distanceToPseudoDistance(SignedDistance &distance, Point2 origin, double param) const;
34 /// Outputs a list of (at most three) intersections (their X coordinates) with an infinite horizontal scanline at y and returns how many there are.
35 virtual int scanlineIntersections(double x[3], int dy[3], double y) const = 0;
36 /// Adjusts the bounding box to fit the edge segment.
37 virtual void bound(double &l, double &b, double &r, double &t) const = 0;
38
39 /// Reverses the edge (swaps its start point and end point).
40 virtual void reverse() = 0;
41 /// Moves the start point of the edge segment.
42 virtual void moveStartPoint(Point2 to) = 0;
43 /// Moves the end point of the edge segment.
44 virtual void moveEndPoint(Point2 to) = 0;
45 /// Splits the edge segments into thirds which together represent the original edge.
46 virtual void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const = 0;
47
48};
49
50/// A line segment.
51class LinearSegment : public EdgeSegment {
52
53public:
54 Point2 p[2];
55
56 LinearSegment(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
57 LinearSegment * clone() const;
58 Point2 point(double param) const;
59 Vector2 direction(double param) const;
60 Vector2 directionChange(double param) const;
61 double length() const;
62 SignedDistance signedDistance(Point2 origin, double &param) const;
63 int scanlineIntersections(double x[3], int dy[3], double y) const;
64 void bound(double &l, double &b, double &r, double &t) const;
65
66 void reverse();
67 void moveStartPoint(Point2 to);
68 void moveEndPoint(Point2 to);
69 void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
70
71};
72
73/// A quadratic Bezier curve.
74class QuadraticSegment : public EdgeSegment {
75
76public:
77 Point2 p[3];
78
79 QuadraticSegment(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
80 QuadraticSegment * clone() const;
81 Point2 point(double param) const;
82 Vector2 direction(double param) const;
83 Vector2 directionChange(double param) const;
84 double length() const;
85 SignedDistance signedDistance(Point2 origin, double &param) const;
86 int scanlineIntersections(double x[3], int dy[3], double y) const;
87 void bound(double &l, double &b, double &r, double &t) const;
88
89 void reverse();
90 void moveStartPoint(Point2 to);
91 void moveEndPoint(Point2 to);
92 void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
93
94 EdgeSegment * convertToCubic() const;
95
96};
97
98/// A cubic Bezier curve.
99class CubicSegment : public EdgeSegment {
100
101public:
102 Point2 p[4];
103
104 CubicSegment(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
105 CubicSegment * clone() const;
106 Point2 point(double param) const;
107 Vector2 direction(double param) const;
108 Vector2 directionChange(double param) const;
109 SignedDistance signedDistance(Point2 origin, double &param) const;
110 int scanlineIntersections(double x[3], int dy[3], double y) const;
111 void bound(double &l, double &b, double &r, double &t) const;
112
113 void reverse();
114 void moveStartPoint(Point2 to);
115 void moveEndPoint(Point2 to);
116 void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
117
118 void deconverge(int param, double amount);
119
120};
121
122}
123