2020-12-27 14:30:33 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2024-03-12 09:26:55 +01:00
|
|
|
#include "Vector2.hpp"
|
|
|
|
#include "SignedDistance.hpp"
|
2020-12-27 14:30:33 +01:00
|
|
|
#include "EdgeColor.h"
|
|
|
|
|
|
|
|
namespace msdfgen {
|
|
|
|
|
|
|
|
// Parameters for iterative search of closest point on a cubic Bezier curve. Increase for higher precision.
|
|
|
|
#define MSDFGEN_CUBIC_SEARCH_STARTS 4
|
|
|
|
#define MSDFGEN_CUBIC_SEARCH_STEPS 4
|
|
|
|
|
|
|
|
/// An abstract edge segment.
|
|
|
|
class EdgeSegment {
|
|
|
|
|
|
|
|
public:
|
|
|
|
EdgeColor color;
|
|
|
|
|
|
|
|
EdgeSegment(EdgeColor edgeColor = WHITE) : color(edgeColor) { }
|
|
|
|
virtual ~EdgeSegment() { }
|
|
|
|
/// Creates a copy of the edge segment.
|
2024-03-12 09:26:55 +01:00
|
|
|
virtual EdgeSegment *clone() const = 0;
|
|
|
|
/// Returns the numeric code of the edge segment's type.
|
|
|
|
virtual int type() const = 0;
|
|
|
|
/// Returns the array of control points.
|
|
|
|
virtual const Point2 *controlPoints() const = 0;
|
2020-12-27 14:30:33 +01:00
|
|
|
/// Returns the point on the edge specified by the parameter (between 0 and 1).
|
|
|
|
virtual Point2 point(double param) const = 0;
|
|
|
|
/// Returns the direction the edge has at the point specified by the parameter.
|
|
|
|
virtual Vector2 direction(double param) const = 0;
|
|
|
|
/// Returns the change of direction (second derivative) at the point specified by the parameter.
|
|
|
|
virtual Vector2 directionChange(double param) const = 0;
|
|
|
|
/// Returns the minimum signed distance between origin and the edge.
|
|
|
|
virtual SignedDistance signedDistance(Point2 origin, double ¶m) const = 0;
|
|
|
|
/// Converts a previously retrieved signed distance from origin to pseudo-distance.
|
|
|
|
virtual void distanceToPseudoDistance(SignedDistance &distance, Point2 origin, double param) const;
|
|
|
|
/// Outputs a list of (at most three) intersections (their X coordinates) with an infinite horizontal scanline at y and returns how many there are.
|
|
|
|
virtual int scanlineIntersections(double x[3], int dy[3], double y) const = 0;
|
|
|
|
/// Adjusts the bounding box to fit the edge segment.
|
|
|
|
virtual void bound(double &l, double &b, double &r, double &t) const = 0;
|
|
|
|
|
|
|
|
/// Reverses the edge (swaps its start point and end point).
|
|
|
|
virtual void reverse() = 0;
|
|
|
|
/// Moves the start point of the edge segment.
|
|
|
|
virtual void moveStartPoint(Point2 to) = 0;
|
|
|
|
/// Moves the end point of the edge segment.
|
|
|
|
virtual void moveEndPoint(Point2 to) = 0;
|
|
|
|
/// Splits the edge segments into thirds which together represent the original edge.
|
|
|
|
virtual void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const = 0;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/// A line segment.
|
|
|
|
class LinearSegment : public EdgeSegment {
|
|
|
|
|
|
|
|
public:
|
2024-03-12 09:26:55 +01:00
|
|
|
enum EdgeType {
|
|
|
|
EDGE_TYPE = 1
|
|
|
|
};
|
|
|
|
|
2020-12-27 14:30:33 +01:00
|
|
|
Point2 p[2];
|
|
|
|
|
|
|
|
LinearSegment(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
|
2024-03-12 09:26:55 +01:00
|
|
|
LinearSegment *clone() const;
|
|
|
|
int type() const;
|
|
|
|
const Point2 *controlPoints() const;
|
2020-12-27 14:30:33 +01:00
|
|
|
Point2 point(double param) const;
|
|
|
|
Vector2 direction(double param) const;
|
|
|
|
Vector2 directionChange(double param) const;
|
|
|
|
double length() const;
|
|
|
|
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
|
|
|
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
|
|
|
void bound(double &l, double &b, double &r, double &t) const;
|
|
|
|
|
|
|
|
void reverse();
|
|
|
|
void moveStartPoint(Point2 to);
|
|
|
|
void moveEndPoint(Point2 to);
|
|
|
|
void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/// A quadratic Bezier curve.
|
|
|
|
class QuadraticSegment : public EdgeSegment {
|
|
|
|
|
|
|
|
public:
|
2024-03-12 09:26:55 +01:00
|
|
|
enum EdgeType {
|
|
|
|
EDGE_TYPE = 2
|
|
|
|
};
|
|
|
|
|
2020-12-27 14:30:33 +01:00
|
|
|
Point2 p[3];
|
|
|
|
|
|
|
|
QuadraticSegment(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
|
2024-03-12 09:26:55 +01:00
|
|
|
QuadraticSegment *clone() const;
|
|
|
|
int type() const;
|
|
|
|
const Point2 *controlPoints() const;
|
2020-12-27 14:30:33 +01:00
|
|
|
Point2 point(double param) const;
|
|
|
|
Vector2 direction(double param) const;
|
|
|
|
Vector2 directionChange(double param) const;
|
|
|
|
double length() const;
|
|
|
|
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
|
|
|
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
|
|
|
void bound(double &l, double &b, double &r, double &t) const;
|
|
|
|
|
|
|
|
void reverse();
|
|
|
|
void moveStartPoint(Point2 to);
|
|
|
|
void moveEndPoint(Point2 to);
|
|
|
|
void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
|
|
|
|
|
2024-03-12 09:26:55 +01:00
|
|
|
EdgeSegment *convertToCubic() const;
|
2020-12-27 14:30:33 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/// A cubic Bezier curve.
|
|
|
|
class CubicSegment : public EdgeSegment {
|
|
|
|
|
|
|
|
public:
|
2024-03-12 09:26:55 +01:00
|
|
|
enum EdgeType {
|
|
|
|
EDGE_TYPE = 3
|
|
|
|
};
|
|
|
|
|
2020-12-27 14:30:33 +01:00
|
|
|
Point2 p[4];
|
|
|
|
|
|
|
|
CubicSegment(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
|
2024-03-12 09:26:55 +01:00
|
|
|
CubicSegment *clone() const;
|
|
|
|
int type() const;
|
|
|
|
const Point2 *controlPoints() const;
|
2020-12-27 14:30:33 +01:00
|
|
|
Point2 point(double param) const;
|
|
|
|
Vector2 direction(double param) const;
|
|
|
|
Vector2 directionChange(double param) const;
|
|
|
|
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
|
|
|
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
|
|
|
void bound(double &l, double &b, double &r, double &t) const;
|
|
|
|
|
|
|
|
void reverse();
|
|
|
|
void moveStartPoint(Point2 to);
|
|
|
|
void moveEndPoint(Point2 to);
|
|
|
|
void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
|
|
|
|
|
|
|
|
void deconverge(int param, double amount);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|