| 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 |