1 /* 2 * Copyright 2014 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 GrStrokeInfo_DEFINED 9 #define GrStrokeInfo_DEFINED 10 11 #include "SkStrokeRec.h" 12 #include "SkPathEffect.h" 13 14 /* 15 * GrStrokeInfo encapsulates all the pertinent infomation regarding the stroke. The SkStrokeRec 16 * which holds information on fill style, width, miter, cap, and join. It also holds information 17 * about the dash like intervals, count, and phase. 18 */ 19 class GrStrokeInfo { 20 public: GrStrokeInfo(SkStrokeRec::InitStyle style)21 GrStrokeInfo(SkStrokeRec::InitStyle style) : 22 fStroke(style), fDashType(SkPathEffect::kNone_DashType) {} 23 24 GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true) : fStroke(src.fStroke) { 25 if (includeDash && src.isDashed()) { 26 fDashType = src.fDashType; 27 fDashPhase = src.fDashPhase; 28 fIntervals.reset(src.getDashCount()); 29 memcpy(fIntervals.get(), src.fIntervals.get(), fIntervals.count() * sizeof(SkScalar)); 30 } else { 31 fDashType = SkPathEffect::kNone_DashType; 32 } 33 } 34 GrStrokeInfo(const SkPaint & paint,SkPaint::Style styleOverride)35 GrStrokeInfo(const SkPaint& paint, SkPaint::Style styleOverride) : 36 fStroke(paint, styleOverride), fDashType(SkPathEffect::kNone_DashType) { 37 this->init(paint); 38 } 39 GrStrokeInfo(const SkPaint & paint)40 explicit GrStrokeInfo(const SkPaint& paint) : 41 fStroke(paint), fDashType(SkPathEffect::kNone_DashType) { 42 this->init(paint); 43 } 44 45 GrStrokeInfo& operator=(const GrStrokeInfo& other) { 46 if (other.isDashed()) { 47 fDashType = other.fDashType; 48 fDashPhase = other.fDashPhase; 49 fIntervals.reset(other.getDashCount()); 50 memcpy(fIntervals.get(), other.fIntervals.get(), fIntervals.count() * sizeof(SkScalar)); 51 } else { 52 this->removeDash(); 53 } 54 fStroke = other.fStroke; 55 return *this; 56 } 57 getStrokeRec()58 const SkStrokeRec& getStrokeRec() const { return fStroke; } 59 getStrokeRecPtr()60 SkStrokeRec* getStrokeRecPtr() { return &fStroke; } 61 setFillStyle()62 void setFillStyle() { fStroke.setFillStyle(); } 63 64 /* 65 * This functions takes in a patheffect and updates the dashing information if the path effect 66 * is a Dash type. Returns true if the path effect is a dashed effect and we are stroking, 67 * otherwise it returns false. 68 */ setDashInfo(const SkPathEffect * pe)69 bool setDashInfo(const SkPathEffect* pe) { 70 if (pe && !fStroke.isFillStyle()) { 71 SkPathEffect::DashInfo dashInfo; 72 fDashType = pe->asADash(&dashInfo); 73 if (SkPathEffect::kDash_DashType == fDashType) { 74 fIntervals.reset(dashInfo.fCount); 75 dashInfo.fIntervals = fIntervals.get(); 76 pe->asADash(&dashInfo); 77 fDashPhase = dashInfo.fPhase; 78 return true; 79 } 80 } 81 return false; 82 } 83 84 /* 85 * Like the above, but sets with an explicit SkPathEffect::DashInfo 86 */ setDashInfo(const SkPathEffect::DashInfo & info)87 bool setDashInfo(const SkPathEffect::DashInfo& info) { 88 if (!fStroke.isFillStyle()) { 89 SkASSERT(!fStroke.isFillStyle()); 90 fDashType = SkPathEffect::kDash_DashType; 91 fDashPhase = info.fPhase; 92 fIntervals.reset(info.fCount); 93 for (int i = 0; i < fIntervals.count(); i++) { 94 fIntervals[i] = info.fIntervals[i]; 95 } 96 return true; 97 } 98 return false; 99 } 100 isDashed()101 bool isDashed() const { 102 return (!fStroke.isFillStyle() && SkPathEffect::kDash_DashType == fDashType); 103 } 104 isFillStyle()105 bool isFillStyle() const { return fStroke.isFillStyle(); } 106 getDashCount()107 int32_t getDashCount() const { 108 SkASSERT(this->isDashed()); 109 return fIntervals.count(); 110 } 111 getDashPhase()112 SkScalar getDashPhase() const { 113 SkASSERT(this->isDashed()); 114 return fDashPhase; 115 } 116 getDashIntervals()117 const SkScalar* getDashIntervals() const { 118 SkASSERT(this->isDashed()); 119 return fIntervals.get(); 120 } 121 removeDash()122 void removeDash() { 123 fDashType = SkPathEffect::kNone_DashType; 124 } 125 126 /** Applies the dash to a path, if the stroke info has dashing. 127 * @return true if the dashing was applied (dst and dstStrokeInfo will be modified). 128 * false if the stroke info did not have dashing. The dst and dstStrokeInfo 129 * will be unmodified. The stroking in the SkStrokeRec might still 130 * be applicable. 131 */ 132 bool applyDash(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const; 133 134 private: 135 init(const SkPaint & paint)136 void init(const SkPaint& paint) { 137 const SkPathEffect* pe = paint.getPathEffect(); 138 this->setDashInfo(pe); 139 } 140 141 SkStrokeRec fStroke; 142 SkPathEffect::DashType fDashType; 143 SkScalar fDashPhase; 144 SkAutoSTArray<2, SkScalar> fIntervals; 145 }; 146 147 #endif 148