OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrStyle_DEFINED | 8 #ifndef GrStyle_DEFINED |
9 #define GrStyle_DEFINED | 9 #define GrStyle_DEFINED |
10 | 10 |
11 #include "GrTypes.h" | 11 #include "GrTypes.h" |
12 #include "SkPathEffect.h" | 12 #include "SkPathEffect.h" |
13 #include "SkStrokeRec.h" | 13 #include "SkStrokeRec.h" |
14 #include "SkTemplates.h" | 14 #include "SkTemplates.h" |
15 | 15 |
16 /** | 16 /** |
17 * Represents the various ways that a GrShape can be styled. It has fill/strokin
g information | 17 * Represents the various ways that a GrShape can be styled. It has fill/strokin
g information |
18 * as well as an optional path effect. If the path effect represents dashing, th
e dashing | 18 * as well as an optional path effect. If the path effect represents dashing, th
e dashing |
19 * information is extracted from the path effect and stored explicitly. | 19 * information is extracted from the path effect and stored explicitly. |
20 * | 20 * |
21 * This object does not support stroke-and-fill styling. It is expected that str
oking and filling | 21 * This object does not support stroke-and-fill styling. It is expected that str
oking and filling |
22 * is handled by drawing a stroke and a fill separately. | 22 * is handled by drawing a stroke and a fill separately. |
23 * | 23 * |
24 * This will replace GrStrokeInfo as GrShape is deployed. | 24 * This will replace GrStrokeInfo as GrShape is deployed. |
25 */ | 25 */ |
26 class GrStyle { | 26 class GrStyle { |
27 public: | 27 public: |
28 GrStyle() : fStrokeRec(SkStrokeRec::kFill_InitStyle) { | 28 /** |
29 fDashInfo.fType = SkPathEffect::kNone_DashType; | 29 * A style object that represents a fill with no path effect. |
| 30 * TODO: constexpr with C++14 |
| 31 */ |
| 32 static const GrStyle& SimpleFill() { |
| 33 static const GrStyle kFill(SkStrokeRec::kFill_InitStyle); |
| 34 return kFill; |
| 35 } |
| 36 |
| 37 /** |
| 38 * A style object that represents a hairline stroke with no path effect. |
| 39 * TODO: constexpr with C++14 |
| 40 */ |
| 41 static const GrStyle& SimpleHairline() { |
| 42 static const GrStyle kHairline(SkStrokeRec::kHairline_InitStyle); |
| 43 return kHairline; |
30 } | 44 } |
31 | 45 |
| 46 enum class Apply { |
| 47 kPathEffectOnly, |
| 48 kPathEffectAndStrokeRec |
| 49 }; |
| 50 |
| 51 /** |
| 52 * Computes the key length for a GrStyle. The return will be negative if it
cannot be turned |
| 53 * into a key. This occurs when there is a path effect that is not a dash. T
he key can |
| 54 * either reflect just the path effect (if one) or the path effect and the s
trokerec. Note |
| 55 * that a simple fill has a zero sized key. |
| 56 */ |
| 57 static int KeySize(const GrStyle& , Apply); |
| 58 |
| 59 /** |
| 60 * Writes a unique key for the style into the provided buffer. This function
assumes the buffer |
| 61 * has room for at least KeySize() values. It assumes that KeySize() returns
a non-negative |
| 62 * value for the style and Apply param. This is written so that the key for
just dash |
| 63 * application followed by the key for the remaining SkStrokeRec is the same
as the key for |
| 64 * applying dashing and SkStrokeRec all at once. |
| 65 */ |
| 66 static void WriteKey(uint32_t*, const GrStyle&, Apply); |
| 67 |
| 68 GrStyle() : GrStyle(SkStrokeRec::kFill_InitStyle) {} |
| 69 |
| 70 explicit GrStyle(SkStrokeRec::InitStyle initStyle) : fStrokeRec(initStyle) {
} |
| 71 |
32 GrStyle(const SkStrokeRec& strokeRec, SkPathEffect* pe) : fStrokeRec(strokeR
ec) { | 72 GrStyle(const SkStrokeRec& strokeRec, SkPathEffect* pe) : fStrokeRec(strokeR
ec) { |
33 SkASSERT(SkStrokeRec::kStrokeAndFill_Style != strokeRec.getStyle()); | 73 SkASSERT(SkStrokeRec::kStrokeAndFill_Style != strokeRec.getStyle()); |
34 this->initPathEffect(pe); | 74 this->initPathEffect(pe); |
35 } | 75 } |
36 | 76 |
37 GrStyle(const GrStyle& that) : fStrokeRec(SkStrokeRec::kFill_InitStyle) { | 77 GrStyle(const GrStyle& that) : fStrokeRec(SkStrokeRec::kFill_InitStyle) { *t
his = that; } |
38 *this = that; | |
39 } | |
40 | 78 |
41 explicit GrStyle(const SkPaint& paint) : fStrokeRec(paint) { | 79 explicit GrStyle(const SkPaint& paint) : fStrokeRec(paint) { |
42 SkASSERT(SkStrokeRec::kStrokeAndFill_Style != fStrokeRec.getStyle()); | 80 SkASSERT(SkStrokeRec::kStrokeAndFill_Style != fStrokeRec.getStyle()); |
43 this->initPathEffect(paint.getPathEffect()); | 81 this->initPathEffect(paint.getPathEffect()); |
44 } | 82 } |
45 | 83 |
46 GrStyle& operator=(const GrStyle& that) { | 84 GrStyle& operator=(const GrStyle& that) { |
47 fPathEffect = that.fPathEffect; | 85 fPathEffect = that.fPathEffect; |
48 fDashInfo = that.fDashInfo; | 86 fDashInfo = that.fDashInfo; |
49 fStrokeRec = that.fStrokeRec; | 87 fStrokeRec = that.fStrokeRec; |
50 return *this; | 88 return *this; |
51 } | 89 } |
| 90 |
| 91 void resetToInitStyle(SkStrokeRec::InitStyle fillOrHairline) { |
| 92 fDashInfo.reset(); |
| 93 fPathEffect.reset(nullptr); |
| 94 if (SkStrokeRec::kFill_InitStyle == fillOrHairline) { |
| 95 fStrokeRec.setFillStyle(); |
| 96 } else { |
| 97 fStrokeRec.setHairlineStyle(); |
| 98 } |
| 99 } |
| 100 |
| 101 /** Is this style a fill with no path effect? */ |
| 102 bool isSimpleFill() const { return fStrokeRec.isFillStyle() && !fPathEffect;
} |
| 103 |
| 104 /** Is this style a hairline with no path effect? */ |
| 105 bool isSimpleHairline() const { return fStrokeRec.isHairlineStyle() && !fPat
hEffect; } |
| 106 |
52 SkPathEffect* pathEffect() const { return fPathEffect.get(); } | 107 SkPathEffect* pathEffect() const { return fPathEffect.get(); } |
53 | 108 |
| 109 bool hasNonDashPathEffect() const { return fPathEffect.get() && !this->isDas
hed(); } |
| 110 |
54 bool isDashed() const { return SkPathEffect::kDash_DashType == fDashInfo.fTy
pe; } | 111 bool isDashed() const { return SkPathEffect::kDash_DashType == fDashInfo.fTy
pe; } |
55 SkScalar dashPhase() const { | 112 SkScalar dashPhase() const { |
56 SkASSERT(this->isDashed()); | 113 SkASSERT(this->isDashed()); |
57 return fDashInfo.fPhase; | 114 return fDashInfo.fPhase; |
58 } | 115 } |
59 int dashIntervalCnt() const { | 116 int dashIntervalCnt() const { |
60 SkASSERT(this->isDashed()); | 117 SkASSERT(this->isDashed()); |
61 return fDashInfo.fIntervals.count(); | 118 return fDashInfo.fIntervals.count(); |
62 } | 119 } |
63 const SkScalar* dashIntervals() const { | 120 const SkScalar* dashIntervals() const { |
64 SkASSERT(this->isDashed()); | 121 SkASSERT(this->isDashed()); |
65 return fDashInfo.fIntervals.get(); | 122 return fDashInfo.fIntervals.get(); |
66 } | 123 } |
67 | 124 |
68 const SkStrokeRec& strokeRec() const { return fStrokeRec; } | 125 const SkStrokeRec& strokeRec() const { return fStrokeRec; } |
69 | 126 |
| 127 /** Hairline or fill styles without path effects make no alterations to a ge
ometry. */ |
| 128 bool applies() const { |
| 129 return this->pathEffect() || (!fStrokeRec.isFillStyle() && !fStrokeRec.i
sHairlineStyle()); |
| 130 } |
| 131 |
| 132 /** |
| 133 * Applies just the path effect and returns remaining stroke information. Th
is will fail if |
| 134 * there is no path effect. |
| 135 */ |
| 136 bool applyPathEffectToPath(SkPath* dst, SkStrokeRec* remainingStoke, const S
kPath& src) const; |
| 137 |
| 138 /** If this succeeds then the result path should be filled or hairlined as i
ndicated by the |
| 139 returned SkStrokeRec::InitStyle value. Will fail if there is no path eff
ect and the |
| 140 strokerec doesn't change the geometry. */ |
| 141 bool applyToPath(SkPath* dst, SkStrokeRec::InitStyle* fillOrHairline, const
SkPath& src) const; |
| 142 |
| 143 /** Given bounds of a path compute the bounds of path with the style applied
. */ |
| 144 void adjustBounds(SkRect* dst, const SkRect& src) const { |
| 145 if (this->pathEffect()) { |
| 146 this->pathEffect()->computeFastBounds(dst, src); |
| 147 } else { |
| 148 SkScalar radius = fStrokeRec.getInflationRadius(); |
| 149 *dst = src.makeOutset(radius, radius); |
| 150 } |
| 151 } |
| 152 |
70 private: | 153 private: |
71 void initPathEffect(SkPathEffect* pe); | 154 void initPathEffect(SkPathEffect* pe); |
72 | 155 |
73 struct DashInfo { | 156 struct DashInfo { |
| 157 DashInfo() : fType(SkPathEffect::kNone_DashType) {} |
74 DashInfo& operator=(const DashInfo& that) { | 158 DashInfo& operator=(const DashInfo& that) { |
75 fType = that.fType; | 159 fType = that.fType; |
76 fPhase = that.fPhase; | 160 fPhase = that.fPhase; |
77 fIntervals.reset(that.fIntervals.count()); | 161 fIntervals.reset(that.fIntervals.count()); |
78 memcpy(fIntervals.get(), that.fIntervals.get(), | 162 memcpy(fIntervals.get(), that.fIntervals.get(), |
79 sizeof(SkScalar) * that.fIntervals.count()); | 163 sizeof(SkScalar) * that.fIntervals.count()); |
80 return *this; | 164 return *this; |
81 } | 165 } |
| 166 void reset() { |
| 167 fType = SkPathEffect::kNone_DashType; |
| 168 fIntervals.reset(0); |
| 169 } |
82 SkPathEffect::DashType fType; | 170 SkPathEffect::DashType fType; |
83 SkScalar fPhase; | 171 SkScalar fPhase; |
84 SkAutoSTArray<4, SkScalar> fIntervals; | 172 SkAutoSTArray<4, SkScalar> fIntervals; |
85 }; | 173 }; |
86 | 174 |
87 SkStrokeRec fStrokeRec; | 175 SkStrokeRec fStrokeRec; |
88 sk_sp<SkPathEffect> fPathEffect; | 176 sk_sp<SkPathEffect> fPathEffect; |
89 DashInfo fDashInfo; | 177 DashInfo fDashInfo; |
90 }; | 178 }; |
91 | 179 |
92 #endif | 180 #endif |
OLD | NEW |