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