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