Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(406)

Side by Side Diff: src/effects/gradients/SkTwoPointConicalGradient.cpp

Issue 227623004: Add flipped gradient branch to two point conical gradient (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Another ignore Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 11
12 static int valid_divide(float numer, float denom, float* ratio) { 12 static int valid_divide(float numer, float denom, float* ratio) {
13 SkASSERT(ratio); 13 SkASSERT(ratio);
14 if (0 == denom) { 14 if (0 == denom) {
15 return 0; 15 return 0;
16 } 16 }
17 *ratio = numer / denom; 17 *ratio = numer / denom;
18 return 1; 18 return 1;
19 } 19 }
20 20
21 // Return the number of distinct real roots, and write them into roots[] in 21 // Return the number of distinct real roots, and write them into roots[] in
22 // ascending order 22 // ascending order
23 static int find_quad_roots(float A, float B, float C, float roots[2]) { 23 static int find_quad_roots(float A, float B, float C, float roots[2], bool desce ndingOrder = false) {
24 SkASSERT(roots); 24 SkASSERT(roots);
25 25
26 if (A == 0) { 26 if (A == 0) {
27 return valid_divide(-C, B, roots); 27 return valid_divide(-C, B, roots);
28 } 28 }
29 29
30 float R = B*B - 4*A*C; 30 float R = B*B - 4*A*C;
31 if (R < 0) { 31 if (R < 0) {
32 return 0; 32 return 0;
33 } 33 }
(...skipping 13 matching lines...) Expand all
47 Q *= -0.5f; 47 Q *= -0.5f;
48 if (0 == Q) { 48 if (0 == Q) {
49 roots[0] = 0; 49 roots[0] = 0;
50 return 1; 50 return 1;
51 } 51 }
52 52
53 float r0 = Q / A; 53 float r0 = Q / A;
54 float r1 = C / Q; 54 float r1 = C / Q;
55 roots[0] = r0 < r1 ? r0 : r1; 55 roots[0] = r0 < r1 ? r0 : r1;
56 roots[1] = r0 > r1 ? r0 : r1; 56 roots[1] = r0 > r1 ? r0 : r1;
57 if (descendingOrder) {
58 SkTSwap(roots[0], roots[1]);
59 }
57 return 2; 60 return 2;
58 } 61 }
59 62
60 static float lerp(float x, float dx, float t) { 63 static float lerp(float x, float dx, float t) {
61 return x + t * dx; 64 return x + t * dx;
62 } 65 }
63 66
64 static float sqr(float x) { return x * x; } 67 static float sqr(float x) { return x * x; }
65 68
66 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, 69 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0,
67 const SkPoint& center1, SkScalar rad1) { 70 const SkPoint& center1, SkScalar rad1,
71 bool flipped) {
68 fCenterX = SkScalarToFloat(center0.fX); 72 fCenterX = SkScalarToFloat(center0.fX);
69 fCenterY = SkScalarToFloat(center0.fY); 73 fCenterY = SkScalarToFloat(center0.fY);
70 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; 74 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX;
71 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; 75 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY;
72 fRadius = SkScalarToFloat(rad0); 76 fRadius = SkScalarToFloat(rad0);
73 fDRadius = SkScalarToFloat(rad1) - fRadius; 77 fDRadius = SkScalarToFloat(rad1) - fRadius;
74 78
75 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); 79 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius);
76 fRadius2 = sqr(fRadius); 80 fRadius2 = sqr(fRadius);
77 fRDR = fRadius * fDRadius; 81 fRDR = fRadius * fDRadius;
82
83 fFlipped = flipped;
78 } 84 }
79 85
80 void TwoPtRadial::setup(SkScalar fx, SkScalar fy, SkScalar dfx, SkScalar dfy) { 86 void TwoPtRadial::setup(SkScalar fx, SkScalar fy, SkScalar dfx, SkScalar dfy) {
81 fRelX = SkScalarToFloat(fx) - fCenterX; 87 fRelX = SkScalarToFloat(fx) - fCenterX;
82 fRelY = SkScalarToFloat(fy) - fCenterY; 88 fRelY = SkScalarToFloat(fy) - fCenterY;
83 fIncX = SkScalarToFloat(dfx); 89 fIncX = SkScalarToFloat(dfx);
84 fIncY = SkScalarToFloat(dfy); 90 fIncY = SkScalarToFloat(dfy);
85 fB = -2 * (fDCenterX * fRelX + fDCenterY * fRelY + fRDR); 91 fB = -2 * (fDCenterX * fRelX + fDCenterY * fRelY + fRDR);
86 fDB = -2 * (fDCenterX * fIncX + fDCenterY * fIncY); 92 fDB = -2 * (fDCenterX * fIncX + fDCenterY * fIncY);
87 } 93 }
88 94
89 SkFixed TwoPtRadial::nextT() { 95 SkFixed TwoPtRadial::nextT() {
90 float roots[2]; 96 float roots[2];
91 97
92 float C = sqr(fRelX) + sqr(fRelY) - fRadius2; 98 float C = sqr(fRelX) + sqr(fRelY) - fRadius2;
93 int countRoots = find_quad_roots(fA, fB, C, roots); 99 int countRoots = find_quad_roots(fA, fB, C, roots, fFlipped);
94 100
95 fRelX += fIncX; 101 fRelX += fIncX;
96 fRelY += fIncY; 102 fRelY += fIncY;
97 fB += fDB; 103 fB += fDB;
98 104
99 if (0 == countRoots) { 105 if (0 == countRoots) {
100 return kDontDrawT; 106 return kDontDrawT;
101 } 107 }
102 108
103 // Prefer the bigger t value if both give a radius(t) > 0 109 // Prefer the bigger t value if both give a radius(t) > 0
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 SkFixed index = mirror_tileproc(t); 168 SkFixed index = mirror_tileproc(t);
163 SkASSERT(index <= 0xFFFF); 169 SkASSERT(index <= 0xFFFF);
164 *dstC++ = cache[toggle + 170 *dstC++ = cache[toggle +
165 (index >> SkGradientShaderBase::kCache32Shift)]; 171 (index >> SkGradientShaderBase::kCache32Shift)];
166 } 172 }
167 toggle = next_dither_toggle(toggle); 173 toggle = next_dither_toggle(toggle);
168 } 174 }
169 } 175 }
170 176
171 void SkTwoPointConicalGradient::init() { 177 void SkTwoPointConicalGradient::init() {
172 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2); 178 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad);
173 fPtsToUnit.reset(); 179 fPtsToUnit.reset();
174 } 180 }
175 181
176 ///////////////////////////////////////////////////////////////////// 182 /////////////////////////////////////////////////////////////////////
177 183
178 SkTwoPointConicalGradient::SkTwoPointConicalGradient( 184 SkTwoPointConicalGradient::SkTwoPointConicalGradient(
179 const SkPoint& start, SkScalar startRadius, 185 const SkPoint& start, SkScalar startRadius,
180 const SkPoint& end, SkScalar endRadius, 186 const SkPoint& end, SkScalar endRadius,
181 const Descriptor& desc) 187 bool flippedGrad, const Descriptor& desc)
182 : SkGradientShaderBase(desc), 188 : SkGradientShaderBase(desc),
183 fCenter1(start), 189 fCenter1(start),
184 fCenter2(end), 190 fCenter2(end),
185 fRadius1(startRadius), 191 fRadius1(startRadius),
186 fRadius2(endRadius) { 192 fRadius2(endRadius),
193 fFlippedGrad(flippedGrad) {
187 // this is degenerate, and should be caught by our caller 194 // this is degenerate, and should be caught by our caller
188 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2); 195 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2);
189 this->init(); 196 this->init();
190 } 197 }
191 198
192 bool SkTwoPointConicalGradient::isOpaque() const { 199 bool SkTwoPointConicalGradient::isOpaque() const {
193 // Because areas outside the cone are left untouched, we cannot treat the 200 // Because areas outside the cone are left untouched, we cannot treat the
194 // shader as opaque even if the gradient itself is opaque. 201 // shader as opaque even if the gradient itself is opaque.
195 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380 202 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380
196 return false; 203 return false;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 } 299 }
293 matrix->preTranslate(-fCenter1.fX, -fCenter1.fY); 300 matrix->preTranslate(-fCenter1.fX, -fCenter1.fY);
294 } 301 }
295 if (xy) { 302 if (xy) {
296 xy[0] = fTileMode; 303 xy[0] = fTileMode;
297 xy[1] = kClamp_TileMode; 304 xy[1] = kClamp_TileMode;
298 } 305 }
299 return kTwoPointConical_BitmapType; 306 return kTwoPointConical_BitmapType;
300 } 307 }
301 308
309 // Returns the original non-sorted version of the gradient
302 SkShader::GradientType SkTwoPointConicalGradient::asAGradient( 310 SkShader::GradientType SkTwoPointConicalGradient::asAGradient(
303 GradientInfo* info) const { 311 GradientInfo* info) const {
304 if (info) { 312 if (info) {
305 commonAsAGradient(info); 313 commonAsAGradient(info, fFlippedGrad);
306 info->fPoint[0] = fCenter1; 314 info->fPoint[0] = fCenter1;
307 info->fPoint[1] = fCenter2; 315 info->fPoint[1] = fCenter2;
308 info->fRadius[0] = fRadius1; 316 info->fRadius[0] = fRadius1;
309 info->fRadius[1] = fRadius2; 317 info->fRadius[1] = fRadius2;
318 if (fFlippedGrad) {
319 SkTSwap(info->fPoint[0], info->fPoint[1]);
320 SkTSwap(info->fRadius[0], info->fRadius[1]);
321 }
310 } 322 }
311 return kConical_GradientType; 323 return kConical_GradientType;
312 } 324 }
313 325
314 SkTwoPointConicalGradient::SkTwoPointConicalGradient( 326 SkTwoPointConicalGradient::SkTwoPointConicalGradient(
315 SkReadBuffer& buffer) 327 SkReadBuffer& buffer)
316 : INHERITED(buffer), 328 : INHERITED(buffer),
317 fCenter1(buffer.readPoint()), 329 fCenter1(buffer.readPoint()),
318 fCenter2(buffer.readPoint()), 330 fCenter2(buffer.readPoint()),
319 fRadius1(buffer.readScalar()), 331 fRadius1(buffer.readScalar()),
320 fRadius2(buffer.readScalar()) { 332 fRadius2(buffer.readScalar()) {
333 if (buffer.pictureVersion() >= 24 || 0 == buffer.pictureVersion()) {
334 fFlippedGrad = buffer.readBool();
335 } else {
336 // V23_COMPATIBILITY_CODE
337 // Sort gradient by radius size for old pictures
338 if (fRadius2 < fRadius1) {
339 SkTSwap(fCenter1, fCenter2);
340 SkTSwap(fRadius1, fRadius2);
341 this->flipGradientColors();
342 fFlippedGrad = true;
343 } else {
344 fFlippedGrad = false;
345 }
346 }
321 this->init(); 347 this->init();
322 }; 348 };
323 349
324 void SkTwoPointConicalGradient::flatten( 350 void SkTwoPointConicalGradient::flatten(
325 SkWriteBuffer& buffer) const { 351 SkWriteBuffer& buffer) const {
326 this->INHERITED::flatten(buffer); 352 this->INHERITED::flatten(buffer);
327 buffer.writePoint(fCenter1); 353 buffer.writePoint(fCenter1);
328 buffer.writePoint(fCenter2); 354 buffer.writePoint(fCenter2);
329 buffer.writeScalar(fRadius1); 355 buffer.writeScalar(fRadius1);
330 buffer.writeScalar(fRadius2); 356 buffer.writeScalar(fRadius2);
357 buffer.writeBool(fFlippedGrad);
331 } 358 }
332 359
333 #if SK_SUPPORT_GPU 360 #if SK_SUPPORT_GPU
334 361
335 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk Paint&) const { 362 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk Paint&) const {
336 SkASSERT(NULL != context); 363 SkASSERT(NULL != context);
337 SkASSERT(fPtsToUnit.isIdentity()); 364 SkASSERT(fPtsToUnit.isIdentity());
338 365
339 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode); 366 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode);
340 } 367 }
(...skipping 25 matching lines...) Expand all
366 str->appendScalar(fCenter2.fY); 393 str->appendScalar(fCenter2.fY);
367 str->append(") radius2: "); 394 str->append(") radius2: ");
368 str->appendScalar(fRadius2); 395 str->appendScalar(fRadius2);
369 str->append(" "); 396 str->append(" ");
370 397
371 this->INHERITED::toString(str); 398 this->INHERITED::toString(str);
372 399
373 str->append(")"); 400 str->append(")");
374 } 401 }
375 #endif 402 #endif
OLDNEW
« no previous file with comments | « src/effects/gradients/SkTwoPointConicalGradient.h ('k') | src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698