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: SkPath_PointIterator(SkPathDirection dir,unsigned startIndex)17 SkPath_PointIterator(SkPathDirection dir, unsigned startIndex) 18 : fCurrent(startIndex % N) 19 , fAdvance(dir == SkPathDirection::kCW ? 1 : N - 1) { } 20 current()21 const SkPoint& current() const { 22 SkASSERT(fCurrent < N); 23 return fPts[fCurrent]; 24 } 25 next()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: SkPath_RectPointIterator(const SkRect & rect,SkPathDirection dir,unsigned startIndex)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: SkPath_OvalPointIterator(const SkRect & oval,SkPathDirection dir,unsigned startIndex)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: SkPath_RRectPointIterator(const SkRRect & rrect,SkPathDirection dir,unsigned startIndex)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