OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkTwoPointConicalGradient.h" | 8 #include "SkTwoPointConicalGradient.h" |
9 | 9 |
10 #include "SkTwoPointConicalGradient_gpu.h" | 10 #include "SkTwoPointConicalGradient_gpu.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 SkASSERT(ratio); | 25 SkASSERT(ratio); |
26 if (0 == denom) { | 26 if (0 == denom) { |
27 return 0; | 27 return 0; |
28 } | 28 } |
29 *ratio = numer / denom; | 29 *ratio = numer / denom; |
30 return 1; | 30 return 1; |
31 } | 31 } |
32 | 32 |
33 // Return the number of distinct real roots, and write them into roots[] in | 33 // Return the number of distinct real roots, and write them into roots[] in |
34 // ascending order | 34 // ascending order |
35 static int find_quad_roots(float A, float B, float C, float roots[2], bool desce
ndingOrder = false) { | 35 static int find_quad_roots(float A, float B, float C, float roots[2]) { |
36 SkASSERT(roots); | 36 SkASSERT(roots); |
37 | 37 |
38 if (A == 0) { | 38 if (A == 0) { |
39 return valid_divide(-C, B, roots); | 39 return valid_divide(-C, B, roots); |
40 } | 40 } |
41 | 41 |
42 float R = B*B - 4*A*C; | 42 float R = B*B - 4*A*C; |
43 if (R < 0) { | 43 if (R < 0) { |
44 return 0; | 44 return 0; |
45 } | 45 } |
(...skipping 13 matching lines...) Expand all Loading... |
59 Q *= -0.5f; | 59 Q *= -0.5f; |
60 if (0 == Q) { | 60 if (0 == Q) { |
61 roots[0] = 0; | 61 roots[0] = 0; |
62 return 1; | 62 return 1; |
63 } | 63 } |
64 | 64 |
65 float r0 = Q / A; | 65 float r0 = Q / A; |
66 float r1 = C / Q; | 66 float r1 = C / Q; |
67 roots[0] = r0 < r1 ? r0 : r1; | 67 roots[0] = r0 < r1 ? r0 : r1; |
68 roots[1] = r0 > r1 ? r0 : r1; | 68 roots[1] = r0 > r1 ? r0 : r1; |
69 if (descendingOrder) { | |
70 SkTSwap(roots[0], roots[1]); | |
71 } | |
72 return 2; | 69 return 2; |
73 } | 70 } |
74 | 71 |
75 static float lerp(float x, float dx, float t) { | 72 static float lerp(float x, float dx, float t) { |
76 return x + t * dx; | 73 return x + t * dx; |
77 } | 74 } |
78 | 75 |
79 static float sqr(float x) { return x * x; } | 76 static float sqr(float x) { return x * x; } |
80 | 77 |
81 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, | 78 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, |
82 const SkPoint& center1, SkScalar rad1, | 79 const SkPoint& center1, SkScalar rad1) { |
83 bool flipped) { | |
84 fCenterX = SkScalarToFloat(center0.fX); | 80 fCenterX = SkScalarToFloat(center0.fX); |
85 fCenterY = SkScalarToFloat(center0.fY); | 81 fCenterY = SkScalarToFloat(center0.fY); |
86 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; | 82 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; |
87 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; | 83 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; |
88 fRadius = SkScalarToFloat(rad0); | 84 fRadius = SkScalarToFloat(rad0); |
89 fDRadius = SkScalarToFloat(rad1) - fRadius; | 85 fDRadius = SkScalarToFloat(rad1) - fRadius; |
90 | 86 |
91 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); | 87 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); |
92 fRadius2 = sqr(fRadius); | 88 fRadius2 = sqr(fRadius); |
93 fRDR = fRadius * fDRadius; | 89 fRDR = fRadius * fDRadius; |
94 | |
95 fFlipped = flipped; | |
96 } | 90 } |
97 | 91 |
98 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc
alar fy, | 92 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc
alar fy, |
99 SkScalar dfx, SkScalar dfy) | 93 SkScalar dfx, SkScalar dfy) |
100 : fRec(rec) | 94 : fRec(rec) |
101 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) | 95 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) |
102 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) | 96 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) |
103 , fIncX(SkScalarToFloat(dfx)) | 97 , fIncX(SkScalarToFloat(dfx)) |
104 , fIncY(SkScalarToFloat(dfy)) | 98 , fIncY(SkScalarToFloat(dfy)) |
105 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) | 99 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) |
106 , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {} | 100 , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {} |
107 | 101 |
108 SkFixed TwoPtRadialContext::nextT() { | 102 SkFixed TwoPtRadialContext::nextT() { |
109 float roots[2]; | 103 float roots[2]; |
110 | 104 |
111 float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2; | 105 float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2; |
112 int countRoots = find_quad_roots(fRec.fA, fB, C, roots, fRec.fFlipped); | 106 int countRoots = find_quad_roots(fRec.fA, fB, C, roots); |
113 | 107 |
114 fRelX += fIncX; | 108 fRelX += fIncX; |
115 fRelY += fIncY; | 109 fRelY += fIncY; |
116 fB += fDB; | 110 fB += fDB; |
117 | 111 |
118 if (0 == countRoots) { | 112 if (0 == countRoots) { |
119 return TwoPtRadial::kDontDrawT; | 113 return TwoPtRadial::kDontDrawT; |
120 } | 114 } |
121 | 115 |
122 // Prefer the bigger t value if both give a radius(t) > 0 | 116 // Prefer the bigger t value if both give a radius(t) > 0 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 SkFixed index = mirror_tileproc(t); | 175 SkFixed index = mirror_tileproc(t); |
182 SkASSERT(index <= 0xFFFF); | 176 SkASSERT(index <= 0xFFFF); |
183 *dstC++ = cache[toggle + | 177 *dstC++ = cache[toggle + |
184 (index >> SkGradientShaderBase::kCache32Shift)]; | 178 (index >> SkGradientShaderBase::kCache32Shift)]; |
185 } | 179 } |
186 toggle = next_dither_toggle(toggle); | 180 toggle = next_dither_toggle(toggle); |
187 } | 181 } |
188 } | 182 } |
189 | 183 |
190 void SkTwoPointConicalGradient::init() { | 184 void SkTwoPointConicalGradient::init() { |
191 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad); | 185 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2); |
192 fPtsToUnit.reset(); | 186 fPtsToUnit.reset(); |
193 } | 187 } |
194 | 188 |
195 ///////////////////////////////////////////////////////////////////// | 189 ///////////////////////////////////////////////////////////////////// |
196 | 190 |
197 SkTwoPointConicalGradient::SkTwoPointConicalGradient( | 191 SkTwoPointConicalGradient::SkTwoPointConicalGradient( |
198 const SkPoint& start, SkScalar startRadius, | 192 const SkPoint& start, SkScalar startRadius, |
199 const SkPoint& end, SkScalar endRadius, | 193 const SkPoint& end, SkScalar endRadius, |
200 bool flippedGrad, const Descriptor& desc) | 194 const Descriptor& desc) |
201 : SkGradientShaderBase(desc), | 195 : SkGradientShaderBase(desc), |
202 fCenter1(start), | 196 fCenter1(start), |
203 fCenter2(end), | 197 fCenter2(end), |
204 fRadius1(startRadius), | 198 fRadius1(startRadius), |
205 fRadius2(endRadius), | 199 fRadius2(endRadius) { |
206 fFlippedGrad(flippedGrad) { | |
207 // this is degenerate, and should be caught by our caller | 200 // this is degenerate, and should be caught by our caller |
208 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2); | 201 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2); |
209 this->init(); | 202 this->init(); |
210 } | 203 } |
211 | 204 |
212 bool SkTwoPointConicalGradient::isOpaque() const { | 205 bool SkTwoPointConicalGradient::isOpaque() const { |
213 // Because areas outside the cone are left untouched, we cannot treat the | 206 // Because areas outside the cone are left untouched, we cannot treat the |
214 // shader as opaque even if the gradient itself is opaque. | 207 // shader as opaque even if the gradient itself is opaque. |
215 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380 | 208 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380 |
216 return false; | 209 return false; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 return kConical_GradientType; | 338 return kConical_GradientType; |
346 } | 339 } |
347 | 340 |
348 SkTwoPointConicalGradient::SkTwoPointConicalGradient( | 341 SkTwoPointConicalGradient::SkTwoPointConicalGradient( |
349 SkReadBuffer& buffer) | 342 SkReadBuffer& buffer) |
350 : INHERITED(buffer), | 343 : INHERITED(buffer), |
351 fCenter1(buffer.readPoint()), | 344 fCenter1(buffer.readPoint()), |
352 fCenter2(buffer.readPoint()), | 345 fCenter2(buffer.readPoint()), |
353 fRadius1(buffer.readScalar()), | 346 fRadius1(buffer.readScalar()), |
354 fRadius2(buffer.readScalar()) { | 347 fRadius2(buffer.readScalar()) { |
355 if (buffer.pictureVersion() >= 24 || 0 == buffer.pictureVersion()) { | |
356 fFlippedGrad = buffer.readBool(); | |
357 } else { | |
358 // V23_COMPATIBILITY_CODE | |
359 // Sort gradient by radius size for old pictures | |
360 if (fRadius2 < fRadius1) { | |
361 SkTSwap(fCenter1, fCenter2); | |
362 SkTSwap(fRadius1, fRadius2); | |
363 this->flipGradientColors(); | |
364 fFlippedGrad = true; | |
365 } else { | |
366 fFlippedGrad = false; | |
367 } | |
368 } | |
369 this->init(); | 348 this->init(); |
370 }; | 349 }; |
371 | 350 |
372 void SkTwoPointConicalGradient::flatten( | 351 void SkTwoPointConicalGradient::flatten( |
373 SkWriteBuffer& buffer) const { | 352 SkWriteBuffer& buffer) const { |
374 this->INHERITED::flatten(buffer); | 353 this->INHERITED::flatten(buffer); |
375 buffer.writePoint(fCenter1); | 354 buffer.writePoint(fCenter1); |
376 buffer.writePoint(fCenter2); | 355 buffer.writePoint(fCenter2); |
377 buffer.writeScalar(fRadius1); | 356 buffer.writeScalar(fRadius1); |
378 buffer.writeScalar(fRadius2); | 357 buffer.writeScalar(fRadius2); |
379 buffer.writeBool(fFlippedGrad); | |
380 } | 358 } |
381 | 359 |
382 #if SK_SUPPORT_GPU | 360 #if SK_SUPPORT_GPU |
383 | 361 |
384 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk
Paint&) const { | 362 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk
Paint&) const { |
385 SkASSERT(NULL != context); | 363 SkASSERT(NULL != context); |
386 SkASSERT(fPtsToUnit.isIdentity()); | 364 SkASSERT(fPtsToUnit.isIdentity()); |
387 | 365 |
388 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode); | 366 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode); |
389 } | 367 } |
(...skipping 25 matching lines...) Expand all Loading... |
415 str->appendScalar(fCenter2.fY); | 393 str->appendScalar(fCenter2.fY); |
416 str->append(") radius2: "); | 394 str->append(") radius2: "); |
417 str->appendScalar(fRadius2); | 395 str->appendScalar(fRadius2); |
418 str->append(" "); | 396 str->append(" "); |
419 | 397 |
420 this->INHERITED::toString(str); | 398 this->INHERITED::toString(str); |
421 | 399 |
422 str->append(")"); | 400 str->append(")"); |
423 } | 401 } |
424 #endif | 402 #endif |
OLD | NEW |