| 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 |  | 
|---|