Chromium Code Reviews| 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]) { | 35 static int find_quad_roots(float A, float B, float C, float roots[2], bool desce ndingOrder = false) { |
| 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 } | |
| 69 return 2; | 72 return 2; |
| 70 } | 73 } |
| 71 | 74 |
| 72 static float lerp(float x, float dx, float t) { | 75 static float lerp(float x, float dx, float t) { |
| 73 return x + t * dx; | 76 return x + t * dx; |
| 74 } | 77 } |
| 75 | 78 |
| 76 static float sqr(float x) { return x * x; } | 79 static float sqr(float x) { return x * x; } |
| 77 | 80 |
| 78 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, | 81 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, |
| 79 const SkPoint& center1, SkScalar rad1) { | 82 const SkPoint& center1, SkScalar rad1, |
| 83 bool flipped) { | |
| 80 fCenterX = SkScalarToFloat(center0.fX); | 84 fCenterX = SkScalarToFloat(center0.fX); |
| 81 fCenterY = SkScalarToFloat(center0.fY); | 85 fCenterY = SkScalarToFloat(center0.fY); |
| 82 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; | 86 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; |
| 83 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; | 87 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; |
| 84 fRadius = SkScalarToFloat(rad0); | 88 fRadius = SkScalarToFloat(rad0); |
| 85 fDRadius = SkScalarToFloat(rad1) - fRadius; | 89 fDRadius = SkScalarToFloat(rad1) - fRadius; |
| 86 | 90 |
| 87 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); | 91 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); |
| 88 fRadius2 = sqr(fRadius); | 92 fRadius2 = sqr(fRadius); |
| 89 fRDR = fRadius * fDRadius; | 93 fRDR = fRadius * fDRadius; |
| 94 | |
| 95 fFlipped = flipped; | |
| 90 } | 96 } |
| 91 | 97 |
| 92 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc alar fy, | 98 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc alar fy, |
| 93 SkScalar dfx, SkScalar dfy) | 99 SkScalar dfx, SkScalar dfy) |
| 94 : fRec(rec) | 100 : fRec(rec) |
| 95 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) | 101 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) |
| 96 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) | 102 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) |
| 97 , fIncX(SkScalarToFloat(dfx)) | 103 , fIncX(SkScalarToFloat(dfx)) |
| 98 , fIncY(SkScalarToFloat(dfy)) | 104 , fIncY(SkScalarToFloat(dfy)) |
| 99 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) | 105 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 SkFixed index = mirror_tileproc(t); | 181 SkFixed index = mirror_tileproc(t); |
| 176 SkASSERT(index <= 0xFFFF); | 182 SkASSERT(index <= 0xFFFF); |
| 177 *dstC++ = cache[toggle + | 183 *dstC++ = cache[toggle + |
| 178 (index >> SkGradientShaderBase::kCache32Shift)]; | 184 (index >> SkGradientShaderBase::kCache32Shift)]; |
| 179 } | 185 } |
| 180 toggle = next_dither_toggle(toggle); | 186 toggle = next_dither_toggle(toggle); |
| 181 } | 187 } |
| 182 } | 188 } |
| 183 | 189 |
| 184 void SkTwoPointConicalGradient::init() { | 190 void SkTwoPointConicalGradient::init() { |
| 185 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2); | 191 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad); |
| 186 fPtsToUnit.reset(); | 192 fPtsToUnit.reset(); |
| 187 } | 193 } |
| 188 | 194 |
| 189 ///////////////////////////////////////////////////////////////////// | 195 ///////////////////////////////////////////////////////////////////// |
| 190 | 196 |
| 191 SkTwoPointConicalGradient::SkTwoPointConicalGradient( | 197 SkTwoPointConicalGradient::SkTwoPointConicalGradient( |
| 192 const SkPoint& start, SkScalar startRadius, | 198 const SkPoint& start, SkScalar startRadius, |
| 193 const SkPoint& end, SkScalar endRadius, | 199 const SkPoint& end, SkScalar endRadius, |
| 194 const Descriptor& desc) | 200 bool flippedGrad, const Descriptor& desc) |
| 195 : SkGradientShaderBase(desc), | 201 : SkGradientShaderBase(desc), |
| 196 fCenter1(start), | 202 fCenter1(start), |
| 197 fCenter2(end), | 203 fCenter2(end), |
| 198 fRadius1(startRadius), | 204 fRadius1(startRadius), |
| 199 fRadius2(endRadius) { | 205 fRadius2(endRadius), |
| 206 fFlippedGrad(flippedGrad) { | |
| 200 // this is degenerate, and should be caught by our caller | 207 // this is degenerate, and should be caught by our caller |
| 201 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2); | 208 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2); |
| 202 this->init(); | 209 this->init(); |
| 203 } | 210 } |
| 204 | 211 |
| 205 bool SkTwoPointConicalGradient::isOpaque() const { | 212 bool SkTwoPointConicalGradient::isOpaque() const { |
| 206 // Because areas outside the cone are left untouched, we cannot treat the | 213 // Because areas outside the cone are left untouched, we cannot treat the |
| 207 // shader as opaque even if the gradient itself is opaque. | 214 // shader as opaque even if the gradient itself is opaque. |
| 208 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380 | 215 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380 |
| 209 return false; | 216 return false; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 if (info) { | 338 if (info) { |
| 332 commonAsAGradient(info); | 339 commonAsAGradient(info); |
| 333 info->fPoint[0] = fCenter1; | 340 info->fPoint[0] = fCenter1; |
| 334 info->fPoint[1] = fCenter2; | 341 info->fPoint[1] = fCenter2; |
| 335 info->fRadius[0] = fRadius1; | 342 info->fRadius[0] = fRadius1; |
| 336 info->fRadius[1] = fRadius2; | 343 info->fRadius[1] = fRadius2; |
| 337 } | 344 } |
| 338 return kConical_GradientType; | 345 return kConical_GradientType; |
| 339 } | 346 } |
| 340 | 347 |
| 348 static const int kNewTwoPointConicalVersion = 24; | |
| 349 | |
| 341 SkTwoPointConicalGradient::SkTwoPointConicalGradient( | 350 SkTwoPointConicalGradient::SkTwoPointConicalGradient( |
| 342 SkReadBuffer& buffer) | 351 SkReadBuffer& buffer) |
| 343 : INHERITED(buffer), | 352 : INHERITED(buffer), |
| 344 fCenter1(buffer.readPoint()), | 353 fCenter1(buffer.readPoint()), |
| 345 fCenter2(buffer.readPoint()), | 354 fCenter2(buffer.readPoint()), |
| 346 fRadius1(buffer.readScalar()), | 355 fRadius1(buffer.readScalar()), |
| 347 fRadius2(buffer.readScalar()) { | 356 fRadius2(buffer.readScalar()) { |
| 357 if (buffer.pictureVersion() > kNewTwoPointConicalVersion || 0 == buffer.pict ureVersion()) { | |
|
mtklein
2014/04/16 17:23:35
I'd personally just write the literal 24 until you
| |
| 358 fFlippedGrad = buffer.readBool(); | |
| 359 } else { | |
| 360 // Sort gradient by radius size for old pictures | |
|
mtklein
2014/04/16 17:23:35
Mark this with // V23_COMPATIBILITY_CODE so we can
| |
| 361 if (fRadius2 < fRadius1) { | |
| 362 SkTSwap(fCenter1, fCenter2); | |
| 363 SkTSwap(fRadius1, fRadius2); | |
| 364 this->flipGradientColors(); | |
| 365 fFlippedGrad = true; | |
| 366 } else { | |
| 367 fFlippedGrad = false; | |
| 368 } | |
| 369 } | |
| 348 this->init(); | 370 this->init(); |
| 349 }; | 371 }; |
| 350 | 372 |
| 351 void SkTwoPointConicalGradient::flatten( | 373 void SkTwoPointConicalGradient::flatten( |
| 352 SkWriteBuffer& buffer) const { | 374 SkWriteBuffer& buffer) const { |
| 353 this->INHERITED::flatten(buffer); | 375 this->INHERITED::flatten(buffer); |
| 354 buffer.writePoint(fCenter1); | 376 buffer.writePoint(fCenter1); |
| 355 buffer.writePoint(fCenter2); | 377 buffer.writePoint(fCenter2); |
| 356 buffer.writeScalar(fRadius1); | 378 buffer.writeScalar(fRadius1); |
| 357 buffer.writeScalar(fRadius2); | 379 buffer.writeScalar(fRadius2); |
| 380 buffer.writeBool(fFlippedGrad); | |
| 358 } | 381 } |
| 359 | 382 |
| 360 #if SK_SUPPORT_GPU | 383 #if SK_SUPPORT_GPU |
| 361 | 384 |
| 362 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk Paint&) const { | 385 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk Paint&) const { |
| 363 SkASSERT(NULL != context); | 386 SkASSERT(NULL != context); |
| 364 SkASSERT(fPtsToUnit.isIdentity()); | 387 SkASSERT(fPtsToUnit.isIdentity()); |
| 365 | 388 |
| 366 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode); | 389 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode); |
| 367 } | 390 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 393 str->appendScalar(fCenter2.fY); | 416 str->appendScalar(fCenter2.fY); |
| 394 str->append(") radius2: "); | 417 str->append(") radius2: "); |
| 395 str->appendScalar(fRadius2); | 418 str->appendScalar(fRadius2); |
| 396 str->append(" "); | 419 str->append(" "); |
| 397 | 420 |
| 398 this->INHERITED::toString(str); | 421 this->INHERITED::toString(str); |
| 399 | 422 |
| 400 str->append(")"); | 423 str->append(")"); |
| 401 } | 424 } |
| 402 #endif | 425 #endif |
| OLD | NEW |