OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 #include "GrRRectEffect.h" | 8 #include "GrRRectEffect.h" |
9 | 9 |
10 #include "gl/GrGLEffect.h" | 10 #include "gl/GrGLEffect.h" |
11 #include "gl/GrGLSL.h" | 11 #include "gl/GrGLSL.h" |
12 #include "GrTBackendEffectFactory.h" | 12 #include "GrTBackendEffectFactory.h" |
13 | 13 |
14 #include "SkRRect.h" | 14 #include "SkRRect.h" |
15 | 15 |
| 16 using namespace GrRRectEffect; |
| 17 |
16 class GLRRectEffect; | 18 class GLRRectEffect; |
17 | 19 |
18 class RRectEffect : public GrEffect { | 20 class RRectEffect : public GrEffect { |
19 public: | 21 public: |
20 // This effect only supports circular corner rrects where the radius is >= k
RadiusMin. | 22 // This effect only supports circular corner rrects where the radius is >= k
RadiusMin. |
21 static const SkScalar kRadiusMin; | 23 static const SkScalar kRadiusMin; |
22 | 24 |
23 /// The types of circular corner rrects supported | 25 /// The types of circular corner rrects supported |
24 enum Type { | 26 enum RRectType { |
25 kCircleCorner_Type, //<! All four corners have the same circular rad
ius. | 27 kCircleCorner_RRectType, //<! All four corners have the same circula
r radius. |
26 kLeftCircleTab_Type, //<! The left side has circular corners and the
right is a rect. | 28 kLeftCircleTab_RRectType, //<! The left side has circular corners, th
e right is a rect. |
27 kTopCircleTab_Type, //<! etc | 29 kTopCircleTab_RRectType, //<! etc |
28 kRightCircleTab_Type, | 30 kRightCircleTab_RRectType, |
29 kBottomCircleTab_Type, | 31 kBottomCircleTab_RRectType, |
30 }; | 32 }; |
31 | 33 |
32 static GrEffectRef* Create(const SkRRect&, Type); | 34 static GrEffectRef* Create(EdgeType, const SkRRect&, RRectType); |
33 | 35 |
34 virtual ~RRectEffect() {}; | 36 virtual ~RRectEffect() {}; |
35 static const char* Name() { return "RRect"; } | 37 static const char* Name() { return "RRect"; } |
36 | 38 |
37 const SkRRect& getRRect() const { return fRRect; } | 39 const SkRRect& getRRect() const { return fRRect; } |
38 | 40 |
39 Type getType() const { return fType; } | 41 RRectType getType() const { return fRRectType; } |
| 42 |
| 43 EdgeType getEdgeType() const { return fEdgeType; } |
40 | 44 |
41 typedef GLRRectEffect GLEffect; | 45 typedef GLRRectEffect GLEffect; |
42 | 46 |
43 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 47 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
44 | 48 |
45 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 49 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
46 | 50 |
47 private: | 51 private: |
48 RRectEffect(const SkRRect&, Type); | 52 RRectEffect(EdgeType, const SkRRect&, RRectType); |
49 | 53 |
50 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | 54 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; |
51 | 55 |
52 SkRRect fRRect; | 56 SkRRect fRRect; |
53 Type fType; | 57 EdgeType fEdgeType; |
| 58 RRectType fRRectType; |
54 | 59 |
55 GR_DECLARE_EFFECT_TEST; | 60 GR_DECLARE_EFFECT_TEST; |
56 | 61 |
57 typedef GrEffect INHERITED; | 62 typedef GrEffect INHERITED; |
58 }; | 63 }; |
59 | 64 |
60 const SkScalar RRectEffect::kRadiusMin = 0.5f; | 65 const SkScalar RRectEffect::kRadiusMin = 0.5f; |
61 | 66 |
62 GrEffectRef* RRectEffect::Create(const SkRRect& rrect, Type type) { | 67 GrEffectRef* RRectEffect::Create(EdgeType edgeType, const SkRRect& rrect, RRectT
ype rrtype) { |
63 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(RRectEffect, (rrect, type)
))); | 68 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(RRectEffect, (edgeType, rr
ect, rrtype)))); |
64 } | 69 } |
65 | 70 |
66 void RRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlag
s) const { | 71 void RRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlag
s) const { |
67 *validFlags = 0; | 72 *validFlags = 0; |
68 } | 73 } |
69 | 74 |
70 const GrBackendEffectFactory& RRectEffect::getFactory() const { | 75 const GrBackendEffectFactory& RRectEffect::getFactory() const { |
71 return GrTBackendEffectFactory<RRectEffect>::getInstance(); | 76 return GrTBackendEffectFactory<RRectEffect>::getInstance(); |
72 } | 77 } |
73 | 78 |
74 RRectEffect::RRectEffect(const SkRRect& rrect, Type type) | 79 RRectEffect::RRectEffect(EdgeType edgeType, const SkRRect& rrect, RRectType rrty
pe) |
75 : fRRect(rrect) | 80 : fRRect(rrect) |
76 , fType(type) { | 81 , fEdgeType(edgeType) |
| 82 , fRRectType(rrtype) { |
77 this->setWillReadFragmentPosition(); | 83 this->setWillReadFragmentPosition(); |
78 } | 84 } |
79 | 85 |
80 bool RRectEffect::onIsEqual(const GrEffect& other) const { | 86 bool RRectEffect::onIsEqual(const GrEffect& other) const { |
81 const RRectEffect& rre = CastEffect<RRectEffect>(other); | 87 const RRectEffect& rre = CastEffect<RRectEffect>(other); |
82 // type is derived from fRRect, so no need to check it. | 88 // type is derived from fRRect, so no need to check it. |
83 return fRRect == rre.fRRect; | 89 return fEdgeType == rre.fEdgeType && fRRect == rre.fRRect; |
84 } | 90 } |
85 | 91 |
86 ////////////////////////////////////////////////////////////////////////////// | 92 ////////////////////////////////////////////////////////////////////////////// |
87 | 93 |
88 GR_DEFINE_EFFECT_TEST(RRectEffect); | 94 GR_DEFINE_EFFECT_TEST(RRectEffect); |
89 | 95 |
90 GrEffectRef* RRectEffect::TestCreate(SkRandom* random, | 96 GrEffectRef* RRectEffect::TestCreate(SkRandom* random, |
91 GrContext*, | 97 GrContext*, |
92 const GrDrawTargetCaps& caps, | 98 const GrDrawTargetCaps& caps, |
93 GrTexture*[]) { | 99 GrTexture*[]) { |
94 SkScalar w = random->nextRangeScalar(20.f, 1000.f); | 100 SkScalar w = random->nextRangeScalar(20.f, 1000.f); |
95 SkScalar h = random->nextRangeScalar(20.f, 1000.f); | 101 SkScalar h = random->nextRangeScalar(20.f, 1000.f); |
96 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); | 102 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); |
| 103 EdgeType et = (EdgeType) random->nextULessThan(kEdgeTypeCnt); |
97 SkRRect rrect; | 104 SkRRect rrect; |
98 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 105 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
99 | 106 |
100 return GrRRectEffect::Create(rrect); | 107 return GrRRectEffect::Create(et, rrect); |
101 } | 108 } |
102 | 109 |
103 ////////////////////////////////////////////////////////////////////////////// | 110 ////////////////////////////////////////////////////////////////////////////// |
104 | 111 |
105 class GLRRectEffect : public GrGLEffect { | 112 class GLRRectEffect : public GrGLEffect { |
106 public: | 113 public: |
107 GLRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 114 GLRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
108 | 115 |
109 virtual void emitCode(GrGLShaderBuilder* builder, | 116 virtual void emitCode(GrGLShaderBuilder* builder, |
110 const GrDrawEffect& drawEffect, | 117 const GrDrawEffect& drawEffect, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 // the rrect will have a (0,0) vector at all four corners. So long as the ra
dius > 0.5 they will | 170 // the rrect will have a (0,0) vector at all four corners. So long as the ra
dius > 0.5 they will |
164 // correctly produce an alpha value of 1 at all four corners. We take the mi
n of all the alphas. | 171 // correctly produce an alpha value of 1 at all four corners. We take the mi
n of all the alphas. |
165 // The code below is a simplified version of the above that performs maxs on
the vector | 172 // The code below is a simplified version of the above that performs maxs on
the vector |
166 // components before computing distances and alpha values so that only one d
istance computation | 173 // components before computing distances and alpha values so that only one d
istance computation |
167 // need be computed to determine the min alpha. | 174 // need be computed to determine the min alpha. |
168 // | 175 // |
169 // For the cases where one half of the rrect is rectangular we drop one of t
he x or y | 176 // For the cases where one half of the rrect is rectangular we drop one of t
he x or y |
170 // computations, compute a separate rect edge alpha for the rect side, and m
ul the two computed | 177 // computations, compute a separate rect edge alpha for the rect side, and m
ul the two computed |
171 // alphas together. | 178 // alphas together. |
172 switch (rre.getType()) { | 179 switch (rre.getType()) { |
173 case RRectEffect::kCircleCorner_Type: | 180 case RRectEffect::kCircleCorner_RRectType: |
174 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); | 181 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); |
175 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); | 182 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); |
176 builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; | 183 builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; |
177 builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.
0, 1.0);\n", | 184 builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.
0, 1.0);\n", |
178 radiusPlusHalfName); | 185 radiusPlusHalfName); |
179 break; | 186 break; |
180 case RRectEffect::kLeftCircleTab_Type: | 187 case RRectEffect::kLeftCircleTab_RRectType: |
181 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); | 188 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); |
182 builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos
, rectName); | 189 builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos
, rectName); |
183 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d
y1)), 0.0);\n"); | 190 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d
y1)), 0.0);\n"); |
184 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.
0, 1.0);\n", | 191 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.
0, 1.0);\n", |
185 rectName, fragmentPos); | 192 rectName, fragmentPos); |
186 builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le
ngth(dxy), 0.0, 1.0);\n", | 193 builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le
ngth(dxy), 0.0, 1.0);\n", |
187 radiusPlusHalfName); | 194 radiusPlusHalfName); |
188 break; | 195 break; |
189 case RRectEffect::kTopCircleTab_Type: | 196 case RRectEffect::kTopCircleTab_RRectType: |
190 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); | 197 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); |
191 builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos
, rectName); | 198 builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos
, rectName); |
192 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy
0.y), 0.0);\n"); | 199 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy
0.y), 0.0);\n"); |
193 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0
.0, 1.0);\n", | 200 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0
.0, 1.0);\n", |
194 rectName, fragmentPos); | 201 rectName, fragmentPos); |
195 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - l
ength(dxy), 0.0, 1.0);\n", | 202 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - l
ength(dxy), 0.0, 1.0);\n", |
196 radiusPlusHalfName); | 203 radiusPlusHalfName); |
197 break; | 204 break; |
198 case RRectEffect::kRightCircleTab_Type: | 205 case RRectEffect::kRightCircleTab_RRectType: |
199 builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, f
ragmentPos); | 206 builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, f
ragmentPos); |
200 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); | 207 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); |
201 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1
.y)), 0.0);\n"); | 208 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1
.y)), 0.0);\n"); |
202 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0
, 1.0);\n", | 209 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0
, 1.0);\n", |
203 fragmentPos, rectName); | 210 fragmentPos, rectName); |
204 builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - len
gth(dxy), 0.0, 1.0);\n", | 211 builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - len
gth(dxy), 0.0, 1.0);\n", |
205 radiusPlusHalfName); | 212 radiusPlusHalfName); |
206 break; | 213 break; |
207 case RRectEffect::kBottomCircleTab_Type: | 214 case RRectEffect::kBottomCircleTab_RRectType: |
208 builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f
ragmentPos); | 215 builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f
ragmentPos); |
209 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); | 216 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); |
210 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy
1.y), 0.0);\n"); | 217 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy
1.y), 0.0);\n"); |
211 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", | 218 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", |
212 fragmentPos, rectName); | 219 fragmentPos, rectName); |
213 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", | 220 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", |
214 radiusPlusHalfName); | 221 radiusPlusHalfName); |
215 break; | 222 break; |
216 } | 223 } |
| 224 |
| 225 if (kInverseFillAA_EdgeType == rre.getEdgeType()) { |
| 226 builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n"); |
| 227 } |
217 | 228 |
218 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, | 229 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, |
219 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 230 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); |
220 } | 231 } |
221 | 232 |
222 GrGLEffect::EffectKey GLRRectEffect::GenKey(const GrDrawEffect& drawEffect, cons
t GrGLCaps&) { | 233 GrGLEffect::EffectKey GLRRectEffect::GenKey(const GrDrawEffect& drawEffect, cons
t GrGLCaps&) { |
223 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); | 234 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); |
224 return rre.getType(); | 235 GR_STATIC_ASSERT(kEdgeTypeCnt <= 4); |
| 236 return (rre.getType() << 2) | rre.getEdgeType(); |
225 } | 237 } |
226 | 238 |
227 void GLRRectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect&
drawEffect) { | 239 void GLRRectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect&
drawEffect) { |
228 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); | 240 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); |
229 const SkRRect& rrect = rre.getRRect(); | 241 const SkRRect& rrect = rre.getRRect(); |
230 if (rrect != fPrevRRect) { | 242 if (rrect != fPrevRRect) { |
231 SkRect rect = rrect.getBounds(); | 243 SkRect rect = rrect.getBounds(); |
232 SkScalar radius = 0; | 244 SkScalar radius = 0; |
233 switch (rre.getType()) { | 245 switch (rre.getType()) { |
234 case RRectEffect::kCircleCorner_Type: | 246 case RRectEffect::kCircleCorner_RRectType: |
235 SkASSERT(rrect.isSimpleCircular()); | 247 SkASSERT(rrect.isSimpleCircular()); |
236 radius = rrect.getSimpleRadii().fX; | 248 radius = rrect.getSimpleRadii().fX; |
237 SkASSERT(radius >= RRectEffect::kRadiusMin); | 249 SkASSERT(radius >= RRectEffect::kRadiusMin); |
238 rect.inset(radius, radius); | 250 rect.inset(radius, radius); |
239 break; | 251 break; |
240 case RRectEffect::kLeftCircleTab_Type: | 252 case RRectEffect::kLeftCircleTab_RRectType: |
241 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; | 253 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; |
242 rect.fLeft += radius; | 254 rect.fLeft += radius; |
243 rect.fTop += radius; | 255 rect.fTop += radius; |
244 rect.fRight += 0.5f; | 256 rect.fRight += 0.5f; |
245 rect.fBottom -= radius; | 257 rect.fBottom -= radius; |
246 break; | 258 break; |
247 case RRectEffect::kTopCircleTab_Type: | 259 case RRectEffect::kTopCircleTab_RRectType: |
248 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; | 260 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; |
249 rect.fLeft += radius; | 261 rect.fLeft += radius; |
250 rect.fTop += radius; | 262 rect.fTop += radius; |
251 rect.fRight -= radius; | 263 rect.fRight -= radius; |
252 rect.fBottom += 0.5f; | 264 rect.fBottom += 0.5f; |
253 break; | 265 break; |
254 case RRectEffect::kRightCircleTab_Type: | 266 case RRectEffect::kRightCircleTab_RRectType: |
255 radius = rrect.radii(SkRRect::kUpperRight_Corner).fX; | 267 radius = rrect.radii(SkRRect::kUpperRight_Corner).fX; |
256 rect.fLeft -= 0.5f; | 268 rect.fLeft -= 0.5f; |
257 rect.fTop += radius; | 269 rect.fTop += radius; |
258 rect.fRight -= radius; | 270 rect.fRight -= radius; |
259 rect.fBottom -= radius; | 271 rect.fBottom -= radius; |
260 break; | 272 break; |
261 case RRectEffect::kBottomCircleTab_Type: | 273 case RRectEffect::kBottomCircleTab_RRectType: |
262 radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX; | 274 radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX; |
263 rect.fLeft += radius; | 275 rect.fLeft += radius; |
264 rect.fTop -= 0.5f; | 276 rect.fTop -= 0.5f; |
265 rect.fRight -= radius; | 277 rect.fRight -= radius; |
266 rect.fBottom -= radius; | 278 rect.fBottom -= radius; |
267 break; | 279 break; |
268 } | 280 } |
269 uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.f
Bottom); | 281 uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.f
Bottom); |
270 uman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); | 282 uman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); |
271 fPrevRRect = rrect; | 283 fPrevRRect = rrect; |
272 } | 284 } |
273 } | 285 } |
274 | 286 |
275 ////////////////////////////////////////////////////////////////////////////// | 287 ////////////////////////////////////////////////////////////////////////////// |
276 | 288 |
277 GrEffectRef* GrRRectEffect::Create(const SkRRect& rrect) { | 289 GrEffectRef* GrRRectEffect::Create(EdgeType edgeType, const SkRRect& rrect) { |
278 RRectEffect::Type type; | 290 RRectEffect::RRectType rrtype; |
279 if (rrect.isSimpleCircular()) { | 291 if (rrect.isSimpleCircular()) { |
280 if (rrect.getSimpleRadii().fX < RRectEffect::kRadiusMin) { | 292 if (rrect.getSimpleRadii().fX < RRectEffect::kRadiusMin) { |
281 return NULL; | 293 return NULL; |
282 } | 294 } |
283 type = RRectEffect::kCircleCorner_Type; | 295 rrtype = RRectEffect::kCircleCorner_RRectType; |
284 } else if (rrect.isComplex()) { | 296 } else if (rrect.isComplex()) { |
285 // Check for the "tab" cases - two adjacent circular corners and two squ
are corners. | 297 // Check for the "tab" cases - two adjacent circular corners and two squ
are corners. |
286 SkScalar radius = 0; | 298 SkScalar radius = 0; |
287 int circleCornerBitfield = 0; | 299 int circleCornerBitfield = 0; |
288 for (int c = 0; c < 4; ++c) { | 300 for (int c = 0; c < 4; ++c) { |
289 const SkVector& r = rrect.radii((SkRRect::Corner)c); | 301 const SkVector& r = rrect.radii((SkRRect::Corner)c); |
290 SkASSERT((0 == r.fX) == (0 == r.fY)); | 302 SkASSERT((0 == r.fX) == (0 == r.fY)); |
291 if (0 == r.fX) { | 303 if (0 == r.fX) { |
292 continue; | 304 continue; |
293 } | 305 } |
(...skipping 13 matching lines...) Expand all Loading... |
307 circleCornerBitfield |= 1 << c; | 319 circleCornerBitfield |= 1 << c; |
308 } | 320 } |
309 } | 321 } |
310 | 322 |
311 GR_STATIC_ASSERT(SkRRect::kUpperLeft_Corner == 0); | 323 GR_STATIC_ASSERT(SkRRect::kUpperLeft_Corner == 0); |
312 GR_STATIC_ASSERT(SkRRect::kUpperRight_Corner == 1); | 324 GR_STATIC_ASSERT(SkRRect::kUpperRight_Corner == 1); |
313 GR_STATIC_ASSERT(SkRRect::kLowerRight_Corner == 2); | 325 GR_STATIC_ASSERT(SkRRect::kLowerRight_Corner == 2); |
314 GR_STATIC_ASSERT(SkRRect::kLowerLeft_Corner == 3); | 326 GR_STATIC_ASSERT(SkRRect::kLowerLeft_Corner == 3); |
315 switch (circleCornerBitfield) { | 327 switch (circleCornerBitfield) { |
316 case 3: | 328 case 3: |
317 type = RRectEffect::kTopCircleTab_Type; | 329 rrtype = RRectEffect::kTopCircleTab_RRectType; |
318 break; | 330 break; |
319 case 6: | 331 case 6: |
320 type = RRectEffect::kRightCircleTab_Type; | 332 rrtype = RRectEffect::kRightCircleTab_RRectType; |
321 break; | 333 break; |
322 case 9: | 334 case 9: |
323 type = RRectEffect::kLeftCircleTab_Type; | 335 rrtype = RRectEffect::kLeftCircleTab_RRectType; |
324 break; | 336 break; |
325 case 12: | 337 case 12: |
326 type = RRectEffect::kBottomCircleTab_Type; | 338 rrtype = RRectEffect::kBottomCircleTab_RRectType; |
327 break; | 339 break; |
328 default: | 340 default: |
329 return NULL; | 341 return NULL; |
330 } | 342 } |
331 } else { | 343 } else { |
332 return NULL; | 344 return NULL; |
333 } | 345 } |
334 return RRectEffect::Create(rrect, type); | 346 return RRectEffect::Create(edgeType, rrect, rrtype); |
335 } | 347 } |
OLD | NEW |