1 | /* |
2 | * Copyright 2019 Google Inc. |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | #ifndef SkPathMakers_DEFINED |
9 | #define SkPathMakers_DEFINED |
10 | |
11 | #include "include/core/SkPathTypes.h" |
12 | #include "include/core/SkPoint.h" |
13 | #include "include/core/SkRRect.h" |
14 | |
15 | template <unsigned N> class SkPath_PointIterator { |
16 | public: |
17 | SkPath_PointIterator(SkPathDirection dir, unsigned startIndex) |
18 | : fCurrent(startIndex % N) |
19 | , fAdvance(dir == SkPathDirection::kCW ? 1 : N - 1) { } |
20 | |
21 | const SkPoint& current() const { |
22 | SkASSERT(fCurrent < N); |
23 | return fPts[fCurrent]; |
24 | } |
25 | |
26 | const SkPoint& next() { |
27 | fCurrent = (fCurrent + fAdvance) % N; |
28 | return this->current(); |
29 | } |
30 | |
31 | protected: |
32 | SkPoint fPts[N]; |
33 | |
34 | private: |
35 | unsigned fCurrent; |
36 | unsigned fAdvance; |
37 | }; |
38 | |
39 | class SkPath_RectPointIterator : public SkPath_PointIterator<4> { |
40 | public: |
41 | SkPath_RectPointIterator(const SkRect& rect, SkPathDirection dir, unsigned startIndex) |
42 | : SkPath_PointIterator(dir, startIndex) { |
43 | |
44 | fPts[0] = SkPoint::Make(rect.fLeft, rect.fTop); |
45 | fPts[1] = SkPoint::Make(rect.fRight, rect.fTop); |
46 | fPts[2] = SkPoint::Make(rect.fRight, rect.fBottom); |
47 | fPts[3] = SkPoint::Make(rect.fLeft, rect.fBottom); |
48 | } |
49 | }; |
50 | |
51 | class SkPath_OvalPointIterator : public SkPath_PointIterator<4> { |
52 | public: |
53 | SkPath_OvalPointIterator(const SkRect& oval, SkPathDirection dir, unsigned startIndex) |
54 | : SkPath_PointIterator(dir, startIndex) { |
55 | |
56 | const SkScalar cx = oval.centerX(); |
57 | const SkScalar cy = oval.centerY(); |
58 | |
59 | fPts[0] = SkPoint::Make(cx, oval.fTop); |
60 | fPts[1] = SkPoint::Make(oval.fRight, cy); |
61 | fPts[2] = SkPoint::Make(cx, oval.fBottom); |
62 | fPts[3] = SkPoint::Make(oval.fLeft, cy); |
63 | } |
64 | }; |
65 | |
66 | class SkPath_RRectPointIterator : public SkPath_PointIterator<8> { |
67 | public: |
68 | SkPath_RRectPointIterator(const SkRRect& rrect, SkPathDirection dir, unsigned startIndex) |
69 | : SkPath_PointIterator(dir, startIndex) { |
70 | |
71 | const SkRect& bounds = rrect.getBounds(); |
72 | const SkScalar L = bounds.fLeft; |
73 | const SkScalar T = bounds.fTop; |
74 | const SkScalar R = bounds.fRight; |
75 | const SkScalar B = bounds.fBottom; |
76 | |
77 | fPts[0] = SkPoint::Make(L + rrect.radii(SkRRect::kUpperLeft_Corner).fX, T); |
78 | fPts[1] = SkPoint::Make(R - rrect.radii(SkRRect::kUpperRight_Corner).fX, T); |
79 | fPts[2] = SkPoint::Make(R, T + rrect.radii(SkRRect::kUpperRight_Corner).fY); |
80 | fPts[3] = SkPoint::Make(R, B - rrect.radii(SkRRect::kLowerRight_Corner).fY); |
81 | fPts[4] = SkPoint::Make(R - rrect.radii(SkRRect::kLowerRight_Corner).fX, B); |
82 | fPts[5] = SkPoint::Make(L + rrect.radii(SkRRect::kLowerLeft_Corner).fX, B); |
83 | fPts[6] = SkPoint::Make(L, B - rrect.radii(SkRRect::kLowerLeft_Corner).fY); |
84 | fPts[7] = SkPoint::Make(L, T + rrect.radii(SkRRect::kUpperLeft_Corner).fY); |
85 | } |
86 | }; |
87 | |
88 | #endif |
89 | |