Index: src/effects/gradients/SkTwoPointConicalGradient.cpp |
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp |
index de8c2364c364fe5f8081b4a2f91111575e38c6af..1e6a0d81268a28c30e630a3be37039510e761aea 100644 |
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp |
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp |
@@ -20,7 +20,7 @@ static int valid_divide(float numer, float denom, float* ratio) { |
// Return the number of distinct real roots, and write them into roots[] in |
// ascending order |
-static int find_quad_roots(float A, float B, float C, float roots[2]) { |
+static int find_quad_roots(float A, float B, float C, float roots[2], bool descendingOrder = false) { |
SkASSERT(roots); |
if (A == 0) { |
@@ -54,6 +54,9 @@ static int find_quad_roots(float A, float B, float C, float roots[2]) { |
float r1 = C / Q; |
roots[0] = r0 < r1 ? r0 : r1; |
roots[1] = r0 > r1 ? r0 : r1; |
+ if (descendingOrder) { |
+ SkTSwap(roots[0], roots[1]); |
+ } |
return 2; |
} |
@@ -64,7 +67,8 @@ static float lerp(float x, float dx, float t) { |
static float sqr(float x) { return x * x; } |
void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, |
- const SkPoint& center1, SkScalar rad1) { |
+ const SkPoint& center1, SkScalar rad1, |
+ bool flipped) { |
fCenterX = SkScalarToFloat(center0.fX); |
fCenterY = SkScalarToFloat(center0.fY); |
fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; |
@@ -75,6 +79,8 @@ void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, |
fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); |
fRadius2 = sqr(fRadius); |
fRDR = fRadius * fDRadius; |
+ |
+ fFlipped = flipped; |
} |
void TwoPtRadial::setup(SkScalar fx, SkScalar fy, SkScalar dfx, SkScalar dfy) { |
@@ -90,7 +96,7 @@ SkFixed TwoPtRadial::nextT() { |
float roots[2]; |
float C = sqr(fRelX) + sqr(fRelY) - fRadius2; |
- int countRoots = find_quad_roots(fA, fB, C, roots); |
+ int countRoots = find_quad_roots(fA, fB, C, roots, fFlipped); |
fRelX += fIncX; |
fRelY += fIncY; |
@@ -169,7 +175,7 @@ static void twopoint_mirror(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC, |
} |
void SkTwoPointConicalGradient::init() { |
- fRec.init(fCenter1, fRadius1, fCenter2, fRadius2); |
+ fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad); |
fPtsToUnit.reset(); |
} |
@@ -178,12 +184,13 @@ void SkTwoPointConicalGradient::init() { |
SkTwoPointConicalGradient::SkTwoPointConicalGradient( |
const SkPoint& start, SkScalar startRadius, |
const SkPoint& end, SkScalar endRadius, |
- const Descriptor& desc) |
+ bool flippedGrad, const Descriptor& desc) |
: SkGradientShaderBase(desc), |
fCenter1(start), |
fCenter2(end), |
fRadius1(startRadius), |
- fRadius2(endRadius) { |
+ fRadius2(endRadius), |
+ fFlippedGrad(flippedGrad) { |
// this is degenerate, and should be caught by our caller |
SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2); |
this->init(); |
@@ -299,14 +306,19 @@ SkShader::BitmapType SkTwoPointConicalGradient::asABitmap( |
return kTwoPointConical_BitmapType; |
} |
+// Returns the original non-sorted version of the gradient |
SkShader::GradientType SkTwoPointConicalGradient::asAGradient( |
GradientInfo* info) const { |
if (info) { |
- commonAsAGradient(info); |
+ commonAsAGradient(info, fFlippedGrad); |
info->fPoint[0] = fCenter1; |
info->fPoint[1] = fCenter2; |
info->fRadius[0] = fRadius1; |
info->fRadius[1] = fRadius2; |
+ if (fFlippedGrad) { |
+ SkTSwap(info->fPoint[0], info->fPoint[1]); |
+ SkTSwap(info->fRadius[0], info->fRadius[1]); |
+ } |
} |
return kConical_GradientType; |
} |
@@ -318,6 +330,20 @@ SkTwoPointConicalGradient::SkTwoPointConicalGradient( |
fCenter2(buffer.readPoint()), |
fRadius1(buffer.readScalar()), |
fRadius2(buffer.readScalar()) { |
+ if (buffer.pictureVersion() >= 24 || 0 == buffer.pictureVersion()) { |
+ fFlippedGrad = buffer.readBool(); |
+ } else { |
+ // V23_COMPATIBILITY_CODE |
+ // Sort gradient by radius size for old pictures |
+ if (fRadius2 < fRadius1) { |
+ SkTSwap(fCenter1, fCenter2); |
+ SkTSwap(fRadius1, fRadius2); |
+ this->flipGradientColors(); |
+ fFlippedGrad = true; |
+ } else { |
+ fFlippedGrad = false; |
+ } |
+ } |
this->init(); |
}; |
@@ -328,6 +354,7 @@ void SkTwoPointConicalGradient::flatten( |
buffer.writePoint(fCenter2); |
buffer.writeScalar(fRadius1); |
buffer.writeScalar(fRadius2); |
+ buffer.writeBool(fFlippedGrad); |
} |
#if SK_SUPPORT_GPU |