1 | |
2 | #pragma once |
3 | |
4 | #include "Vector2.h" |
5 | #include "SignedDistance.h" |
6 | #include "edge-segments.h" |
7 | |
8 | namespace msdfgen { |
9 | |
10 | struct MultiDistance { |
11 | double r, g, b; |
12 | }; |
13 | struct MultiAndTrueDistance : MultiDistance { |
14 | double a; |
15 | }; |
16 | |
17 | /// Selects the nearest edge by its true distance. |
18 | class TrueDistanceSelector { |
19 | |
20 | public: |
21 | typedef double DistanceType; |
22 | |
23 | struct EdgeCache { |
24 | Point2 point; |
25 | double absDistance; |
26 | |
27 | EdgeCache(); |
28 | }; |
29 | |
30 | void reset(const Point2 &p); |
31 | void addEdge(EdgeCache &cache, const EdgeSegment *prevEdge, const EdgeSegment *edge, const EdgeSegment *nextEdge); |
32 | void merge(const TrueDistanceSelector &other); |
33 | DistanceType distance() const; |
34 | |
35 | private: |
36 | Point2 p; |
37 | SignedDistance minDistance; |
38 | |
39 | }; |
40 | |
41 | class PseudoDistanceSelectorBase { |
42 | |
43 | public: |
44 | struct EdgeCache { |
45 | Point2 point; |
46 | double absDistance; |
47 | double aDomainDistance, bDomainDistance; |
48 | double aPseudoDistance, bPseudoDistance; |
49 | |
50 | EdgeCache(); |
51 | }; |
52 | |
53 | static bool getPseudoDistance(double &distance, const Vector2 &ep, const Vector2 &edgeDir); |
54 | |
55 | PseudoDistanceSelectorBase(); |
56 | void reset(double delta); |
57 | bool isEdgeRelevant(const EdgeCache &cache, const EdgeSegment *edge, const Point2 &p) const; |
58 | void addEdgeTrueDistance(const EdgeSegment *edge, const SignedDistance &distance, double param); |
59 | void addEdgePseudoDistance(double distance); |
60 | void merge(const PseudoDistanceSelectorBase &other); |
61 | double computeDistance(const Point2 &p) const; |
62 | SignedDistance trueDistance() const; |
63 | |
64 | private: |
65 | SignedDistance minTrueDistance; |
66 | double minNegativePseudoDistance; |
67 | double minPositivePseudoDistance; |
68 | const EdgeSegment *nearEdge; |
69 | double nearEdgeParam; |
70 | |
71 | }; |
72 | |
73 | /// Selects the nearest edge by its pseudo-distance. |
74 | class PseudoDistanceSelector : public PseudoDistanceSelectorBase { |
75 | |
76 | public: |
77 | typedef double DistanceType; |
78 | |
79 | void reset(const Point2 &p); |
80 | void addEdge(EdgeCache &cache, const EdgeSegment *prevEdge, const EdgeSegment *edge, const EdgeSegment *nextEdge); |
81 | DistanceType distance() const; |
82 | |
83 | private: |
84 | Point2 p; |
85 | |
86 | }; |
87 | |
88 | /// Selects the nearest edge for each of the three channels by its pseudo-distance. |
89 | class MultiDistanceSelector { |
90 | |
91 | public: |
92 | typedef MultiDistance DistanceType; |
93 | typedef PseudoDistanceSelectorBase::EdgeCache EdgeCache; |
94 | |
95 | void reset(const Point2 &p); |
96 | void addEdge(EdgeCache &cache, const EdgeSegment *prevEdge, const EdgeSegment *edge, const EdgeSegment *nextEdge); |
97 | void merge(const MultiDistanceSelector &other); |
98 | DistanceType distance() const; |
99 | SignedDistance trueDistance() const; |
100 | |
101 | private: |
102 | Point2 p; |
103 | PseudoDistanceSelectorBase r, g, b; |
104 | |
105 | }; |
106 | |
107 | /// Selects the nearest edge for each of the three color channels by its pseudo-distance and by true distance for the alpha channel. |
108 | class MultiAndTrueDistanceSelector : public MultiDistanceSelector { |
109 | |
110 | public: |
111 | typedef MultiAndTrueDistance DistanceType; |
112 | |
113 | DistanceType distance() const; |
114 | |
115 | }; |
116 | |
117 | } |
118 | |