Index: src/effects/gradients/SkGradientShader.cpp |
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp |
index 504855a478e1003becc24b5480df1f72afe60f31..2d0d847db112e8205d76770b097efbc04a4172c2 100644 |
--- a/src/effects/gradients/SkGradientShader.cpp |
+++ b/src/effects/gradients/SkGradientShader.cpp |
@@ -118,12 +118,13 @@ SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) { |
SkFixed dp = SK_Fixed1 / (desc.fCount - 1); |
SkFixed p = dp; |
SkFixed scale = (desc.fCount - 1) << 8; // (1 << 24) / dp |
- for (int i = 1; i < desc.fCount; i++) { |
+ for (int i = 1; i < desc.fCount - 1; i++) { |
recs->fPos = p; |
recs->fScale = scale; |
recs += 1; |
p += dp; |
} |
+ recs->fPos = SK_Fixed1; |
} |
} |
this->initCommon(); |
@@ -237,6 +238,30 @@ SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor |
return kTexture_GpuColorType; |
} |
+void SkGradientShaderBase::FlipGradientColors(SkColor* colorDst, Rec* recDst, |
+ SkColor* colorSrc, Rec* recSrc, |
+ int count) { |
+ SkAutoSTArray<8, SkColor> colorsTemp(count); |
+ for (int i = 0; i < count; ++i) { |
+ int offset = count - i - 1; |
+ colorsTemp[i] = colorSrc[offset]; |
+ } |
+ if (count > 2) { |
+ SkAutoSTArray<8, Rec> recsTemp(count); |
+ for (int i = 0; i < count; ++i) { |
+ int offset = count - i - 1; |
+ recsTemp[i].fPos = SK_Fixed1 - recSrc[offset].fPos; |
+ recsTemp[i].fScale = recSrc[offset].fScale; |
+ } |
+ memcpy(recDst, recsTemp.get(), count * sizeof(Rec)); |
+ } |
+ memcpy(colorDst, colorsTemp.get(), count * sizeof(SkColor)); |
+} |
+ |
+void SkGradientShaderBase::flipGradientColors() { |
+ FlipGradientColors(fOrigColors, fRecs, fOrigColors, fRecs, fColorCount); |
+} |
+ |
bool SkGradientShaderBase::isOpaque() const { |
return fColorsAreOpaque; |
} |
@@ -643,11 +668,23 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { |
} |
} |
-void SkGradientShaderBase::commonAsAGradient(GradientInfo* info) const { |
+void SkGradientShaderBase::commonAsAGradient(GradientInfo* info, bool flipGrad) const { |
if (info) { |
if (info->fColorCount >= fColorCount) { |
+ SkColor* colorLoc; |
+ Rec* recLoc; |
+ if (flipGrad && (info->fColors || info->fColorOffsets)) { |
+ SkAutoSTArray<8, SkColor> colorStorage(fColorCount); |
+ SkAutoSTArray<8, Rec> recStorage(fColorCount); |
+ colorLoc = colorStorage.get(); |
+ recLoc = recStorage.get(); |
+ FlipGradientColors(colorLoc, recLoc, fOrigColors, fRecs, fColorCount); |
+ } else { |
+ colorLoc = fOrigColors; |
+ recLoc = fRecs; |
+ } |
if (info->fColors) { |
- memcpy(info->fColors, fOrigColors, fColorCount * sizeof(SkColor)); |
+ memcpy(info->fColors, colorLoc, fColorCount * sizeof(SkColor)); |
} |
if (info->fColorOffsets) { |
if (fColorCount == 2) { |
@@ -655,7 +692,7 @@ void SkGradientShaderBase::commonAsAGradient(GradientInfo* info) const { |
info->fColorOffsets[1] = SK_Scalar1; |
} else if (fColorCount > 2) { |
for (int i = 0; i < fColorCount; ++i) { |
- info->fColorOffsets[i] = SkFixedToScalar(fRecs[i].fPos); |
+ info->fColorOffsets[i] = SkFixedToScalar(recLoc[i].fPos); |
} |
} |
} |
@@ -801,12 +838,36 @@ SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, |
if (start == end && startRadius == endRadius) { |
return SkNEW(SkEmptyShader); |
} |
+ |
EXPAND_1_COLOR(colorCount); |
+ bool flipGradient = startRadius > endRadius; |
+ |
SkGradientShaderBase::Descriptor desc; |
- desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); |
- return SkNEW_ARGS(SkTwoPointConicalGradient, |
- (start, startRadius, end, endRadius, desc)); |
+ |
+ if (!flipGradient) { |
+ desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); |
+ return SkNEW_ARGS(SkTwoPointConicalGradient, |
+ (start, startRadius, end, endRadius, flipGradient, desc)); |
+ } else { |
+ SkAutoSTArray<8, SkColor> colorsNew(colorCount); |
+ SkAutoSTArray<8, SkScalar> posNew(colorCount); |
+ for (int i = 0; i < colorCount; ++i) { |
+ colorsNew[i] = colors[colorCount - i - 1]; |
+ } |
+ |
+ if (pos) { |
+ for (int i = 0; i < colorCount; ++i) { |
+ posNew[i] = 1 - pos[colorCount - i - 1]; |
+ } |
+ desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, mapper, flags); |
+ } else { |
+ desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, mapper, flags); |
+ } |
+ |
+ return SkNEW_ARGS(SkTwoPointConicalGradient, |
+ (end, endRadius, start, startRadius, flipGradient, desc)); |
+ } |
} |
SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy, |