xref: /aosp_15_r20/external/skia/modules/bentleyottmann/include/Contour.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 // Copyright 2023 Google LLC
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3 
4 #ifndef Contour_DEFINED
5 #define Contour_DEFINED
6 
7 #include "include/core/SkRect.h"
8 #include "include/private/base/SkAssert.h"
9 #include "include/private/base/SkSpan_impl.h"
10 
11 #include <limits.h>
12 #include <cstddef>
13 #include <cstdint>
14 #include <iterator>
15 #include <vector>
16 
17 class SkPath;
18 namespace myers { class Segment; }
19 struct SkPoint;
20 
21 namespace contour {
22 struct Point {
23     int32_t x;
24     int32_t y;
25 };
26 
27 class Contour {
28 public:
29     SkSpan<const Point> points;
30     SkIRect bounds;
31 };
32 
33 class Contours {
34     class Iterator {
35     public:
36         using value_type = Contour;
37         using difference_type = ptrdiff_t;
38         using pointer = value_type*;
39         using reference = value_type;
40         using iterator_category = std::input_iterator_tag;
Iterator(const Contours & contours,size_t index)41         Iterator(const Contours& contours, size_t index)
42                 : fContours{contours}
43                 , fIndex{index} { }
Iterator(const Iterator & that)44         Iterator(const Iterator& that) : Iterator{ that.fContours, that.fIndex } { }
45         Iterator& operator++() { ++fIndex; return *this; }
46         Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
47         bool operator==(const Iterator& rhs) const { return fIndex == rhs.fIndex; }
48         bool operator!=(const Iterator& rhs) const { return fIndex != rhs.fIndex; }
49         value_type operator*() { return fContours[fIndex]; }
50         friend difference_type operator-(Iterator lhs, Iterator rhs) {
51             return lhs.fIndex - rhs.fIndex;
52         }
53 
54     private:
55         const Contours& fContours;
56         size_t fIndex = 0;
57     };
58 public:
59     static constexpr double kScaleFactor = 1024;
60     static Contours Make(SkPath path);
61 
62     Contour operator[](size_t i) const {
63         SkASSERT(i < fContours.size());
64         auto& [bounds, end] = fContours[i];
65         int32_t start = i == 0 ? 0 : fContours[i-1].end;
66         SkSpan<const Point> points{&fPoints[start], end - start};
67         return {points, bounds};
68     }
69 
begin()70     Iterator begin() const {
71         return Iterator{*this, 0};
72     }
73 
end()74     Iterator end() const {
75         return Iterator{*this, fContours.size()};
76     }
77 
size()78     size_t size() const {
79         return fContours.size();
80     }
81 
empty()82     bool empty() const {
83         return fContours.empty();
84     }
85 
86     std::vector<myers::Segment> segments() const;
87 
88 private:
89     static constexpr SkIRect kEmptyRect = SkIRect::MakeLTRB(INT_MAX, INT_MAX, INT_MIN, INT_MIN);
90     struct CompactContour {
91         SkIRect bounds;
92         int32_t end;
93     };
94 
95     static Point RoundSkPoint(SkPoint p);
96     bool currentContourIsEmpty() const;
97     void addPointToCurrentContour(SkPoint p);
98     void moveToStartOfContour(SkPoint p);
99     void closeContourIfNeeded();
100 
101     Point fContourStart;
102     SkIRect fContourBounds = kEmptyRect;
103 
104     std::vector<Point> fPoints;
105     std::vector<CompactContour> fContours;
106 };
107 }  // namespace contour
108 
109 #endif  // Contour_DEFINED
110