1 | |
---|---|
2 | #include "ShapeDistanceFinder.h" |
3 | |
4 | namespace msdfgen { |
5 | |
6 | template <class ContourCombiner> |
7 | ShapeDistanceFinder<ContourCombiner>::ShapeDistanceFinder(const Shape &shape) : shape(shape), contourCombiner(shape), shapeEdgeCache(shape.edgeCount()) { } |
8 | |
9 | template <class ContourCombiner> |
10 | typename ShapeDistanceFinder<ContourCombiner>::DistanceType ShapeDistanceFinder<ContourCombiner>::distance(const Point2 &origin) { |
11 | contourCombiner.reset(origin); |
12 | typename ContourCombiner::EdgeSelectorType::EdgeCache *edgeCache = &shapeEdgeCache[0]; |
13 | |
14 | for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) { |
15 | if (!contour->edges.empty()) { |
16 | typename ContourCombiner::EdgeSelectorType &edgeSelector = contourCombiner.edgeSelector(int(contour-shape.contours.begin())); |
17 | |
18 | const EdgeSegment *prevEdge = contour->edges.size() >= 2 ? *(contour->edges.end()-2) : *contour->edges.begin(); |
19 | const EdgeSegment *curEdge = contour->edges.back(); |
20 | for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) { |
21 | const EdgeSegment *nextEdge = *edge; |
22 | edgeSelector.addEdge(*edgeCache++, prevEdge, curEdge, nextEdge); |
23 | prevEdge = curEdge; |
24 | curEdge = nextEdge; |
25 | } |
26 | } |
27 | } |
28 | |
29 | return contourCombiner.distance(); |
30 | } |
31 | |
32 | template <class ContourCombiner> |
33 | typename ShapeDistanceFinder<ContourCombiner>::DistanceType ShapeDistanceFinder<ContourCombiner>::oneShotDistance(const Shape &shape, const Point2 &origin) { |
34 | ContourCombiner contourCombiner(shape); |
35 | contourCombiner.reset(origin); |
36 | |
37 | for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) { |
38 | if (!contour->edges.empty()) { |
39 | typename ContourCombiner::EdgeSelectorType &edgeSelector = contourCombiner.edgeSelector(int(contour-shape.contours.begin())); |
40 | |
41 | const EdgeSegment *prevEdge = contour->edges.size() >= 2 ? *(contour->edges.end()-2) : *contour->edges.begin(); |
42 | const EdgeSegment *curEdge = contour->edges.back(); |
43 | for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) { |
44 | const EdgeSegment *nextEdge = *edge; |
45 | typename ContourCombiner::EdgeSelectorType::EdgeCache dummy; |
46 | edgeSelector.addEdge(dummy, prevEdge, curEdge, nextEdge); |
47 | prevEdge = curEdge; |
48 | curEdge = nextEdge; |
49 | } |
50 | } |
51 | } |
52 | |
53 | return contourCombiner.distance(); |
54 | } |
55 | |
56 | } |
57 |