edge-segments.h 5.6 KB

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