Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 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 "Sk4fLinearGradient.h" | 8 #include "Sk4fLinearGradient.h" |
| 9 #include "SkGradientShaderPriv.h" | 9 #include "SkGradientShaderPriv.h" |
| 10 #include "SkHalf.h" | 10 #include "SkHalf.h" |
| 11 #include "SkLinearGradient.h" | 11 #include "SkLinearGradient.h" |
| 12 #include "SkRadialGradient.h" | 12 #include "SkRadialGradient.h" |
| 13 #include "SkTwoPointConicalGradient.h" | 13 #include "SkTwoPointConicalGradient.h" |
| 14 #include "SkSweepGradient.h" | 14 #include "SkSweepGradient.h" |
| 15 | 15 |
| 16 enum GradientSerializationFlags { | |
|
f(malita)
2016/09/28 15:41:52
nit: enum class + drop _GSF suffix?
Brian Osman
2016/09/28 15:46:17
Seems like that would make all of my usage harder
f(malita)
2016/09/28 15:54:46
Ack, good point.
| |
| 17 kHasPosition_GSF = 0x80000000, | |
| 18 kHasLocalMatrix_GSF = 0x40000000, | |
| 19 kHasColorSpace_GSF = 0x20000000, | |
| 20 | |
| 21 kTileModeShift_GSF = 16, | |
| 22 kTileModeMask_GSF = 0xF, | |
| 23 | |
| 24 kGradFlagsShift_GSF = 0, | |
| 25 kGradFlagsMask_GSF = 0xF, | |
| 26 }; | |
| 27 | |
| 16 void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const { | 28 void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const { |
| 17 buffer.writeColorArray(fColors, fCount); | 29 uint32_t flags = 0; |
| 18 // TODO: Flatten fColors4f and fColorSpace | |
| 19 if (fPos) { | 30 if (fPos) { |
| 20 buffer.writeBool(true); | 31 flags |= kHasPosition_GSF; |
| 32 } | |
| 33 if (fLocalMatrix) { | |
| 34 flags |= kHasLocalMatrix_GSF; | |
| 35 } | |
| 36 sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : null ptr; | |
| 37 if (colorSpaceData) { | |
| 38 flags |= kHasColorSpace_GSF; | |
| 39 } | |
| 40 SkASSERT(fTileMode <= kTileModeMask_GSF); | |
| 41 flags |= (fTileMode << kTileModeShift_GSF); | |
| 42 SkASSERT(fGradFlags <= kGradFlagsMask_GSF); | |
| 43 flags |= (fGradFlags << kGradFlagsShift_GSF); | |
| 44 | |
| 45 buffer.writeUInt(flags); | |
| 46 | |
| 47 buffer.writeColor4fArray(fColors, fCount); | |
| 48 if (colorSpaceData) { | |
| 49 buffer.writeDataAsByteArray(colorSpaceData.get()); | |
| 50 } | |
| 51 if (fPos) { | |
| 21 buffer.writeScalarArray(fPos, fCount); | 52 buffer.writeScalarArray(fPos, fCount); |
| 22 } else { | |
| 23 buffer.writeBool(false); | |
| 24 } | 53 } |
| 25 buffer.write32(fTileMode); | |
| 26 buffer.write32(fGradFlags); | |
| 27 if (fLocalMatrix) { | 54 if (fLocalMatrix) { |
| 28 buffer.writeBool(true); | |
| 29 buffer.writeMatrix(*fLocalMatrix); | 55 buffer.writeMatrix(*fLocalMatrix); |
| 30 } else { | |
| 31 buffer.writeBool(false); | |
| 32 } | 56 } |
| 33 } | 57 } |
| 34 | 58 |
| 35 bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) { | 59 bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) { |
| 36 // TODO: Unflatten fColors4f and fColorSpace | 60 if (buffer.isVersionLT(SkReadBuffer::kGradientShaderFloatColor_Version)) { |
| 37 fCount = buffer.getArrayCount(); | 61 fCount = buffer.getArrayCount(); |
| 38 if (fCount > kStorageCount) { | 62 if (fCount > kStorageCount) { |
| 39 size_t allocSize = (sizeof(SkColor) + sizeof(SkScalar)) * fCount; | 63 size_t allocSize = (sizeof(SkColor4f) + sizeof(SkScalar)) * fCount; |
| 40 fDynamicStorage.reset(allocSize); | 64 fDynamicStorage.reset(allocSize); |
| 41 fColors = (SkColor*)fDynamicStorage.get(); | 65 fColors = (SkColor4f*)fDynamicStorage.get(); |
| 42 fPos = (SkScalar*)(fColors + fCount); | 66 fPos = (SkScalar*)(fColors + fCount); |
| 43 } else { | 67 } else { |
| 44 fColors = fColorStorage; | 68 fColors = fColorStorage; |
| 45 fPos = fPosStorage; | 69 fPos = fPosStorage; |
| 46 } | 70 } |
| 47 | 71 |
| 48 if (!buffer.readColorArray(const_cast<SkColor*>(fColors), fCount)) { | 72 // Old gradients serialized SkColor. Read that to a temporary location, then convert. |
| 49 return false; | 73 SkSTArray<2, SkColor, true> colors; |
| 50 } | 74 colors.resize_back(fCount); |
| 51 if (buffer.readBool()) { | 75 if (!buffer.readColorArray(colors.begin(), fCount)) { |
| 52 if (!buffer.readScalarArray(const_cast<SkScalar*>(fPos), fCount)) { | |
| 53 return false; | 76 return false; |
| 54 } | 77 } |
| 78 for (int i = 0; i < fCount; ++i) { | |
| 79 mutableColors()[i] = SkColor4f::FromColor(colors[i]); | |
| 80 } | |
| 81 | |
| 82 if (buffer.readBool()) { | |
| 83 if (!buffer.readScalarArray(const_cast<SkScalar*>(fPos), fCount)) { | |
| 84 return false; | |
| 85 } | |
| 86 } else { | |
| 87 fPos = nullptr; | |
| 88 } | |
| 89 | |
| 90 fColorSpace = nullptr; | |
| 91 fTileMode = (SkShader::TileMode)buffer.read32(); | |
| 92 fGradFlags = buffer.read32(); | |
| 93 | |
| 94 if (buffer.readBool()) { | |
| 95 fLocalMatrix = &fLocalMatrixStorage; | |
| 96 buffer.readMatrix(&fLocalMatrixStorage); | |
| 97 } else { | |
| 98 fLocalMatrix = nullptr; | |
| 99 } | |
| 55 } else { | 100 } else { |
| 56 fPos = nullptr; | 101 // New gradient format. Includes floating point color, color space, dens ely packed flags |
| 57 } | 102 uint32_t flags = buffer.readUInt(); |
| 58 | 103 |
| 59 fTileMode = (SkShader::TileMode)buffer.read32(); | 104 fTileMode = (SkShader::TileMode)((flags >> kTileModeShift_GSF) & kTileMo deMask_GSF); |
| 60 fGradFlags = buffer.read32(); | 105 fGradFlags = (flags >> kGradFlagsShift_GSF) & kGradFlagsMask_GSF; |
| 61 | 106 |
| 62 if (buffer.readBool()) { | 107 fCount = buffer.getArrayCount(); |
| 63 fLocalMatrix = &fLocalMatrixStorage; | 108 if (fCount > kStorageCount) { |
| 64 buffer.readMatrix(&fLocalMatrixStorage); | 109 size_t allocSize = (sizeof(SkColor4f) + sizeof(SkScalar)) * fCount; |
| 65 } else { | 110 fDynamicStorage.reset(allocSize); |
| 66 fLocalMatrix = nullptr; | 111 fColors = (SkColor4f*)fDynamicStorage.get(); |
| 112 fPos = (SkScalar*)(fColors + fCount); | |
| 113 } else { | |
| 114 fColors = fColorStorage; | |
| 115 fPos = fPosStorage; | |
| 116 } | |
| 117 if (!buffer.readColor4fArray(mutableColors(), fCount)) { | |
| 118 return false; | |
| 119 } | |
| 120 if (SkToBool(flags & kHasColorSpace_GSF)) { | |
| 121 sk_sp<SkData> data = buffer.readByteArrayAsData(); | |
| 122 fColorSpace = SkColorSpace::Deserialize(data->data(), data->size()); | |
| 123 } else { | |
| 124 fColorSpace = nullptr; | |
| 125 } | |
| 126 if (SkToBool(flags & kHasPosition_GSF)) { | |
| 127 if (!buffer.readScalarArray(mutablePos(), fCount)) { | |
| 128 return false; | |
| 129 } | |
| 130 } else { | |
| 131 fPos = nullptr; | |
| 132 } | |
| 133 if (SkToBool(flags & kHasLocalMatrix_GSF)) { | |
| 134 fLocalMatrix = &fLocalMatrixStorage; | |
| 135 buffer.readMatrix(&fLocalMatrixStorage); | |
| 136 } else { | |
| 137 fLocalMatrix = nullptr; | |
| 138 } | |
| 67 } | 139 } |
| 68 return buffer.isValid(); | 140 return buffer.isValid(); |
| 69 } | 141 } |
| 70 | 142 |
| 71 //////////////////////////////////////////////////////////////////////////////// //////////// | 143 //////////////////////////////////////////////////////////////////////////////// //////////// |
| 72 | 144 |
| 73 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc, const SkMatri x& ptsToUnit) | 145 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc, const SkMatri x& ptsToUnit) |
| 74 : INHERITED(desc.fLocalMatrix) | 146 : INHERITED(desc.fLocalMatrix) |
| 75 , fPtsToUnit(ptsToUnit) | 147 , fPtsToUnit(ptsToUnit) |
| 76 { | 148 { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 103 dummyFirst = desc.fPos[0] != 0; | 175 dummyFirst = desc.fPos[0] != 0; |
| 104 dummyLast = desc.fPos[desc.fCount - 1] != SK_Scalar1; | 176 dummyLast = desc.fPos[desc.fCount - 1] != SK_Scalar1; |
| 105 fColorCount += dummyFirst + dummyLast; | 177 fColorCount += dummyFirst + dummyLast; |
| 106 } | 178 } |
| 107 | 179 |
| 108 if (fColorCount > kColorStorageCount) { | 180 if (fColorCount > kColorStorageCount) { |
| 109 size_t size = sizeof(SkColor) + sizeof(SkColor4f) + sizeof(Rec); | 181 size_t size = sizeof(SkColor) + sizeof(SkColor4f) + sizeof(Rec); |
| 110 if (desc.fPos) { | 182 if (desc.fPos) { |
| 111 size += sizeof(SkScalar); | 183 size += sizeof(SkScalar); |
| 112 } | 184 } |
| 113 fOrigColors = reinterpret_cast<SkColor*>( | 185 fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(size * fColorCo unt)); |
| 114 sk_malloc_throw(size * fColorCount)); | |
| 115 } | 186 } |
| 116 else { | 187 else { |
| 117 fOrigColors = fStorage; | 188 fOrigColors = fStorage; |
| 118 } | 189 } |
| 119 | 190 |
| 120 fOrigColors4f = (SkColor4f*)(fOrigColors + fColorCount); | 191 fOrigColors4f = (SkColor4f*)(fOrigColors + fColorCount); |
| 121 | 192 |
| 122 // We should have been supplied with either fColors *or* (fColors4f and fCol orSpace) | 193 // Now copy over the colors, adding the dummies as needed |
| 123 if (desc.fColors) { | 194 SkColor4f* origColors = fOrigColors4f; |
| 124 // TODO: Should we support alternate gamma-encoded colorspaces with SkCo lor inputs? | 195 if (dummyFirst) { |
| 125 SkASSERT(!desc.fColors4f && !desc.fColorSpace); | 196 *origColors++ = desc.fColors[0]; |
| 197 } | |
| 198 memcpy(origColors, desc.fColors, desc.fCount * sizeof(SkColor4f)); | |
| 199 if (dummyLast) { | |
| 200 origColors += desc.fCount; | |
| 201 *origColors = desc.fColors[desc.fCount - 1]; | |
| 202 } | |
| 126 | 203 |
| 127 // Now copy over the colors, adding the dummies as needed | 204 // Convert our SkColor4f colors to SkColor as well. Note that this is incorr ect if the |
| 128 SkColor* origColors = fOrigColors; | 205 // source colors are not in sRGB gamut. We would need to do a gamut transfor mation, but |
| 129 if (dummyFirst) { | 206 // SkColorSpaceXform can't do that (yet). GrColorSpaceXform can, but we may not have GPU |
| 130 *origColors++ = desc.fColors[0]; | 207 // support compiled in here. For the common case (sRGB colors), this does th e right thing. |
| 131 } | 208 for (int i = 0; i < fColorCount; ++i) { |
| 132 memcpy(origColors, desc.fColors, desc.fCount * sizeof(SkColor)); | 209 fOrigColors[i] = fOrigColors4f[i].toSkColor(); |
| 133 if (dummyLast) { | 210 } |
| 134 origColors += desc.fCount; | |
| 135 *origColors = desc.fColors[desc.fCount - 1]; | |
| 136 } | |
| 137 | 211 |
| 138 // Convert our SkColor colors to SkColor4f as well | 212 if (!desc.fColorSpace) { |
| 139 for (int i = 0; i < fColorCount; ++i) { | 213 // This happens if we were constructed from SkColors, so our colors are really sRGB |
| 140 fOrigColors4f[i] = SkColor4f::FromColor(fOrigColors[i]); | |
| 141 } | |
| 142 | |
| 143 // Color space refers to fColors4f, so it's always linear gamma | |
| 144 fColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named); | 214 fColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named); |
| 145 } else { | 215 } else { |
| 146 SkASSERT(desc.fColors4f && desc.fColorSpace && desc.fColorSpace->gammaIs Linear()); | 216 // The color space refers to the float colors, so it must be linear gamm a |
| 147 | 217 SkASSERT(desc.fColorSpace->gammaIsLinear()); |
| 148 // Now copy over the colors, adding the dummies as needed | |
| 149 SkColor4f* origColors = fOrigColors4f; | |
| 150 if (dummyFirst) { | |
| 151 *origColors++ = desc.fColors4f[0]; | |
| 152 } | |
| 153 memcpy(origColors, desc.fColors4f, desc.fCount * sizeof(SkColor4f)); | |
| 154 if (dummyLast) { | |
| 155 origColors += desc.fCount; | |
| 156 *origColors = desc.fColors4f[desc.fCount - 1]; | |
| 157 } | |
| 158 | |
| 159 // Convert our SkColor4f colors to SkColor as well. Note that this is in correct if the | |
| 160 // source colors are not in sRGB gamut. We would need to do a gamut tran sformation, but | |
| 161 // SkColorSpaceXform can't do that (yet). GrColorSpaceXform can, but we may not have GPU | |
| 162 // support compiled in here. | |
| 163 for (int i = 0; i < fColorCount; ++i) { | |
| 164 fOrigColors[i] = fOrigColors4f[i].toSkColor(); | |
| 165 } | |
| 166 fColorSpace = desc.fColorSpace; | 218 fColorSpace = desc.fColorSpace; |
| 167 } | 219 } |
| 168 | 220 |
| 169 if (desc.fPos && fColorCount) { | 221 if (desc.fPos && fColorCount) { |
| 170 fOrigPos = (SkScalar*)(fOrigColors4f + fColorCount); | 222 fOrigPos = (SkScalar*)(fOrigColors4f + fColorCount); |
| 171 fRecs = (Rec*)(fOrigPos + fColorCount); | 223 fRecs = (Rec*)(fOrigPos + fColorCount); |
| 172 } else { | 224 } else { |
| 173 fOrigPos = nullptr; | 225 fOrigPos = nullptr; |
| 174 fRecs = (Rec*)(fOrigColors4f + fColorCount); | 226 fRecs = (Rec*)(fOrigColors4f + fColorCount); |
| 175 } | 227 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 void SkGradientShaderBase::initCommon() { | 301 void SkGradientShaderBase::initCommon() { |
| 250 unsigned colorAlpha = 0xFF; | 302 unsigned colorAlpha = 0xFF; |
| 251 for (int i = 0; i < fColorCount; i++) { | 303 for (int i = 0; i < fColorCount; i++) { |
| 252 colorAlpha &= SkColorGetA(fOrigColors[i]); | 304 colorAlpha &= SkColorGetA(fOrigColors[i]); |
| 253 } | 305 } |
| 254 fColorsAreOpaque = colorAlpha == 0xFF; | 306 fColorsAreOpaque = colorAlpha == 0xFF; |
| 255 } | 307 } |
| 256 | 308 |
| 257 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { | 309 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { |
| 258 Descriptor desc; | 310 Descriptor desc; |
| 259 desc.fColors = fOrigColors; | 311 desc.fColors = fOrigColors4f; |
| 260 desc.fColors4f = fOrigColors4f; | |
| 261 desc.fColorSpace = fColorSpace; | 312 desc.fColorSpace = fColorSpace; |
| 262 desc.fPos = fOrigPos; | 313 desc.fPos = fOrigPos; |
| 263 desc.fCount = fColorCount; | 314 desc.fCount = fColorCount; |
| 264 desc.fTileMode = fTileMode; | 315 desc.fTileMode = fTileMode; |
| 265 desc.fGradFlags = fGradFlags; | 316 desc.fGradFlags = fGradFlags; |
| 266 | 317 |
| 267 const SkMatrix& m = this->getLocalMatrix(); | 318 const SkMatrix& m = this->getLocalMatrix(); |
| 268 desc.fLocalMatrix = m.isIdentity() ? nullptr : &m; | 319 desc.fLocalMatrix = m.isIdentity() ? nullptr : &m; |
| 269 desc.flatten(buffer); | 320 desc.flatten(buffer); |
| 270 } | 321 } |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 | 816 |
| 766 this->INHERITED::toString(str); | 817 this->INHERITED::toString(str); |
| 767 } | 818 } |
| 768 #endif | 819 #endif |
| 769 | 820 |
| 770 /////////////////////////////////////////////////////////////////////////////// | 821 /////////////////////////////////////////////////////////////////////////////// |
| 771 /////////////////////////////////////////////////////////////////////////////// | 822 /////////////////////////////////////////////////////////////////////////////// |
| 772 | 823 |
| 773 // Return true if these parameters are valid/legal/safe to construct a gradient | 824 // Return true if these parameters are valid/legal/safe to construct a gradient |
| 774 // | 825 // |
| 775 static bool valid_grad(const SkColor colors[], const SkScalar pos[], int count, unsigned tileMode) { | 826 static bool valid_grad(const SkColor4f colors[], const SkScalar pos[], int count , |
| 827 unsigned tileMode) { | |
| 776 return nullptr != colors && count >= 1 && tileMode < (unsigned)SkShader::kTi leModeCount; | 828 return nullptr != colors && count >= 1 && tileMode < (unsigned)SkShader::kTi leModeCount; |
| 777 } | 829 } |
| 778 | 830 |
| 779 static void desc_init(SkGradientShaderBase::Descriptor* desc, | 831 static void desc_init(SkGradientShaderBase::Descriptor* desc, |
| 780 const SkColor colors[], const SkScalar pos[], int colorCou nt, | 832 const SkColor4f colors[], sk_sp<SkColorSpace> colorSpace, |
| 833 const SkScalar pos[], int colorCount, | |
| 781 SkShader::TileMode mode, uint32_t flags, const SkMatrix* l ocalMatrix) { | 834 SkShader::TileMode mode, uint32_t flags, const SkMatrix* l ocalMatrix) { |
| 782 SkASSERT(colorCount > 1); | 835 SkASSERT(colorCount > 1); |
| 783 | 836 |
| 784 desc->fColors = colors; | 837 desc->fColors = colors; |
| 785 desc->fColors4f = nullptr; | 838 desc->fColorSpace = std::move(colorSpace); |
| 786 desc->fColorSpace = nullptr; // SkColor is always sRGB | |
| 787 desc->fPos = pos; | 839 desc->fPos = pos; |
| 788 desc->fCount = colorCount; | 840 desc->fCount = colorCount; |
| 789 desc->fTileMode = mode; | 841 desc->fTileMode = mode; |
| 790 desc->fGradFlags = flags; | 842 desc->fGradFlags = flags; |
| 791 desc->fLocalMatrix = localMatrix; | 843 desc->fLocalMatrix = localMatrix; |
| 792 } | 844 } |
| 793 | 845 |
| 794 // assumes colors is SkColor* and pos is SkScalar* | 846 // assumes colors is SkColor4f* and pos is SkScalar* |
| 795 #define EXPAND_1_COLOR(count) \ | 847 #define EXPAND_1_COLOR(count) \ |
| 796 SkColor tmp[2]; \ | 848 SkColor4f tmp[2]; \ |
| 797 do { \ | 849 do { \ |
| 798 if (1 == count) { \ | 850 if (1 == count) { \ |
| 799 tmp[0] = tmp[1] = colors[0]; \ | 851 tmp[0] = tmp[1] = colors[0]; \ |
| 800 colors = tmp; \ | 852 colors = tmp; \ |
| 801 pos = nullptr; \ | 853 pos = nullptr; \ |
| 802 count = 2; \ | 854 count = 2; \ |
| 803 } \ | 855 } \ |
| 804 } while (0) | 856 } while (0) |
| 805 | 857 |
| 806 struct ColorStopOptimizer { | 858 struct ColorStopOptimizer { |
| 807 ColorStopOptimizer(const SkColor* colors, const SkScalar* pos, | 859 ColorStopOptimizer(const SkColor4f* colors, const SkScalar* pos, |
| 808 int count, SkShader::TileMode mode) | 860 int count, SkShader::TileMode mode) |
| 809 : fColors(colors) | 861 : fColors(colors) |
| 810 , fPos(pos) | 862 , fPos(pos) |
| 811 , fCount(count) { | 863 , fCount(count) { |
| 812 | 864 |
| 813 if (!pos || count != 3) { | 865 if (!pos || count != 3) { |
| 814 return; | 866 return; |
| 815 } | 867 } |
| 816 | 868 |
| 817 if (SkScalarNearlyEqual(pos[0], 0.0f) && | 869 if (SkScalarNearlyEqual(pos[0], 0.0f) && |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 834 if (SkShader::kRepeat_TileMode == mode || | 886 if (SkShader::kRepeat_TileMode == mode || |
| 835 SkShader::kMirror_TileMode == mode || | 887 SkShader::kMirror_TileMode == mode || |
| 836 colors[1] == colors[2]) { | 888 colors[1] == colors[2]) { |
| 837 | 889 |
| 838 // Ignore the rightmost color/pos. | 890 // Ignore the rightmost color/pos. |
| 839 fCount = 2; | 891 fCount = 2; |
| 840 } | 892 } |
| 841 } | 893 } |
| 842 } | 894 } |
| 843 | 895 |
| 844 const SkColor* fColors; | 896 const SkColor4f* fColors; |
| 845 const SkScalar* fPos; | 897 const SkScalar* fPos; |
| 846 int fCount; | 898 int fCount; |
| 899 }; | |
| 900 | |
| 901 struct ColorConverter { | |
| 902 ColorConverter(const SkColor* colors, int count) { | |
| 903 for (int i = 0; i < count; ++i) { | |
| 904 fColors4f.push_back(SkColor4f::FromColor(colors[i])); | |
| 905 } | |
| 906 } | |
| 907 | |
| 908 SkSTArray<2, SkColor4f, true> fColors4f; | |
| 847 }; | 909 }; |
| 848 | 910 |
| 849 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], | 911 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], |
| 850 const SkColor colors[], | 912 const SkColor colors[], |
| 851 const SkScalar pos[], int colorCoun t, | 913 const SkScalar pos[], int colorCoun t, |
| 852 SkShader::TileMode mode, | 914 SkShader::TileMode mode, |
| 853 uint32_t flags, | 915 uint32_t flags, |
| 854 const SkMatrix* localMatrix) { | 916 const SkMatrix* localMatrix) { |
| 917 ColorConverter converter(colors, colorCount); | |
| 918 return MakeLinear(pts, converter.fColors4f.begin(), nullptr, pos, colorCount , mode, flags, | |
| 919 localMatrix); | |
| 920 } | |
| 921 | |
| 922 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], | |
| 923 const SkColor4f colors[], | |
| 924 sk_sp<SkColorSpace> colorSpace, | |
| 925 const SkScalar pos[], int colorCoun t, | |
| 926 SkShader::TileMode mode, | |
| 927 uint32_t flags, | |
| 928 const SkMatrix* localMatrix) { | |
| 855 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { | 929 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { |
| 856 return nullptr; | 930 return nullptr; |
| 857 } | 931 } |
| 858 if (!valid_grad(colors, pos, colorCount, mode)) { | 932 if (!valid_grad(colors, pos, colorCount, mode)) { |
| 859 return nullptr; | 933 return nullptr; |
| 860 } | 934 } |
| 861 if (1 == colorCount) { | 935 if (1 == colorCount) { |
| 862 return SkShader::MakeColorShader(colors[0]); | 936 return SkShader::MakeColorShader(colors[0], std::move(colorSpace)); |
| 863 } | 937 } |
| 864 | 938 |
| 865 ColorStopOptimizer opt(colors, pos, colorCount, mode); | 939 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 866 | 940 |
| 867 SkGradientShaderBase::Descriptor desc; | 941 SkGradientShaderBase::Descriptor desc; |
| 868 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix ); | 942 desc_init(&desc, opt.fColors, std::move(colorSpace), opt.fPos, opt.fCount, m ode, flags, |
| 943 localMatrix); | |
| 869 return sk_make_sp<SkLinearGradient>(pts, desc); | 944 return sk_make_sp<SkLinearGradient>(pts, desc); |
| 870 } | 945 } |
| 871 | 946 |
| 872 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, | 947 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, |
| 873 const SkColor colors[], | 948 const SkColor colors[], |
| 874 const SkScalar pos[], int colorCount, | 949 const SkScalar pos[], int colorCoun t, |
| 875 SkShader::TileMode mode, | 950 SkShader::TileMode mode, |
| 876 uint32_t flags, | 951 uint32_t flags, |
| 877 const SkMatrix* localMatrix) { | 952 const SkMatrix* localMatrix) { |
| 953 ColorConverter converter(colors, colorCount); | |
| 954 return MakeRadial(center, radius, converter.fColors4f.begin(), nullptr, pos, colorCount, mode, | |
| 955 flags, localMatrix); | |
| 956 } | |
| 957 | |
| 958 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, | |
| 959 const SkColor4f colors[], | |
| 960 sk_sp<SkColorSpace> colorSpace, | |
| 961 const SkScalar pos[], int colorCoun t, | |
| 962 SkShader::TileMode mode, | |
| 963 uint32_t flags, | |
| 964 const SkMatrix* localMatrix) { | |
| 878 if (radius <= 0) { | 965 if (radius <= 0) { |
| 879 return nullptr; | 966 return nullptr; |
| 880 } | 967 } |
| 881 if (!valid_grad(colors, pos, colorCount, mode)) { | 968 if (!valid_grad(colors, pos, colorCount, mode)) { |
| 882 return nullptr; | 969 return nullptr; |
| 883 } | 970 } |
| 884 if (1 == colorCount) { | 971 if (1 == colorCount) { |
| 885 return SkShader::MakeColorShader(colors[0]); | 972 return SkShader::MakeColorShader(colors[0], std::move(colorSpace)); |
| 886 } | 973 } |
| 887 | 974 |
| 888 ColorStopOptimizer opt(colors, pos, colorCount, mode); | 975 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 889 | 976 |
| 890 SkGradientShaderBase::Descriptor desc; | 977 SkGradientShaderBase::Descriptor desc; |
| 891 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix ); | 978 desc_init(&desc, opt.fColors, std::move(colorSpace), opt.fPos, opt.fCount, m ode, flags, |
| 979 localMatrix); | |
| 892 return sk_make_sp<SkRadialGradient>(center, radius, desc); | 980 return sk_make_sp<SkRadialGradient>(center, radius, desc); |
| 893 } | 981 } |
| 894 | 982 |
| 895 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, | 983 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, |
| 896 SkScalar startRadius, | 984 SkScalar startRadius, |
| 897 const SkPoint& end, | 985 const SkPoint& end, |
| 898 SkScalar endRadius, | 986 SkScalar endRadius, |
| 899 const SkColor colors[], | 987 const SkColor colors[], |
| 900 const SkScalar pos[], | 988 const SkScalar pos[], |
| 901 int colorCount, | 989 int colorCount, |
| 902 SkShader::TileMode mode, | 990 SkShader::TileMode mode, |
| 903 uint32_t flags, | 991 uint32_t flags, |
| 904 const SkMatrix* localMatrix) { | 992 const SkMatrix* localMatri x) { |
| 993 ColorConverter converter(colors, colorCount); | |
| 994 return MakeTwoPointConical(start, startRadius, end, endRadius, converter.fCo lors4f.begin(), | |
| 995 nullptr, pos, colorCount, mode, flags, localMatri x); | |
| 996 } | |
| 997 | |
| 998 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, | |
| 999 SkScalar startRadius, | |
| 1000 const SkPoint& end, | |
| 1001 SkScalar endRadius, | |
| 1002 const SkColor4f colors[], | |
| 1003 sk_sp<SkColorSpace> colorS pace, | |
| 1004 const SkScalar pos[], | |
| 1005 int colorCount, | |
| 1006 SkShader::TileMode mode, | |
| 1007 uint32_t flags, | |
| 1008 const SkMatrix* localMatri x) { | |
| 905 if (startRadius < 0 || endRadius < 0) { | 1009 if (startRadius < 0 || endRadius < 0) { |
| 906 return nullptr; | 1010 return nullptr; |
| 907 } | 1011 } |
| 908 if (!valid_grad(colors, pos, colorCount, mode)) { | 1012 if (!valid_grad(colors, pos, colorCount, mode)) { |
| 909 return nullptr; | 1013 return nullptr; |
| 910 } | 1014 } |
| 911 if (startRadius == endRadius) { | 1015 if (startRadius == endRadius) { |
| 912 if (start == end || startRadius == 0) { | 1016 if (start == end || startRadius == 0) { |
| 913 return SkShader::MakeEmptyShader(); | 1017 return SkShader::MakeEmptyShader(); |
| 914 } | 1018 } |
| 915 } | 1019 } |
| 916 EXPAND_1_COLOR(colorCount); | 1020 EXPAND_1_COLOR(colorCount); |
| 917 | 1021 |
| 918 ColorStopOptimizer opt(colors, pos, colorCount, mode); | 1022 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 919 | 1023 |
| 920 bool flipGradient = startRadius > endRadius; | 1024 bool flipGradient = startRadius > endRadius; |
| 921 | 1025 |
| 922 SkGradientShaderBase::Descriptor desc; | 1026 SkGradientShaderBase::Descriptor desc; |
| 923 | 1027 |
| 924 if (!flipGradient) { | 1028 if (!flipGradient) { |
| 925 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMa trix); | 1029 desc_init(&desc, opt.fColors, std::move(colorSpace), opt.fPos, opt.fCoun t, mode, flags, |
| 1030 localMatrix); | |
| 926 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, | 1031 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, |
| 927 flipGradient, desc); | 1032 flipGradient, desc); |
| 928 } else { | 1033 } else { |
| 929 SkAutoSTArray<8, SkColor> colorsNew(opt.fCount); | 1034 SkAutoSTArray<8, SkColor4f> colorsNew(opt.fCount); |
| 930 SkAutoSTArray<8, SkScalar> posNew(opt.fCount); | 1035 SkAutoSTArray<8, SkScalar> posNew(opt.fCount); |
| 931 for (int i = 0; i < opt.fCount; ++i) { | 1036 for (int i = 0; i < opt.fCount; ++i) { |
| 932 colorsNew[i] = opt.fColors[opt.fCount - i - 1]; | 1037 colorsNew[i] = opt.fColors[opt.fCount - i - 1]; |
| 933 } | 1038 } |
| 934 | 1039 |
| 935 if (pos) { | 1040 if (pos) { |
| 936 for (int i = 0; i < opt.fCount; ++i) { | 1041 for (int i = 0; i < opt.fCount; ++i) { |
| 937 posNew[i] = 1 - opt.fPos[opt.fCount - i - 1]; | 1042 posNew[i] = 1 - opt.fPos[opt.fCount - i - 1]; |
| 938 } | 1043 } |
| 939 desc_init(&desc, colorsNew.get(), posNew.get(), opt.fCount, mode, fl ags, localMatrix); | 1044 desc_init(&desc, colorsNew.get(), std::move(colorSpace), posNew.get( ), opt.fCount, mode, |
| 1045 flags, localMatrix); | |
| 940 } else { | 1046 } else { |
| 941 desc_init(&desc, colorsNew.get(), nullptr, opt.fCount, mode, flags, localMatrix); | 1047 desc_init(&desc, colorsNew.get(), std::move(colorSpace), nullptr, op t.fCount, mode, |
| 1048 flags, localMatrix); | |
| 942 } | 1049 } |
| 943 | 1050 |
| 944 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, | 1051 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, |
| 945 flipGradient, desc); | 1052 flipGradient, desc); |
| 946 } | 1053 } |
| 947 } | 1054 } |
| 948 | 1055 |
| 949 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, | 1056 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, |
| 950 const SkColor colors[], | 1057 const SkColor colors[], |
| 951 const SkScalar pos[], | 1058 const SkScalar pos[], |
| 952 int colorCount, | 1059 int colorCount, |
| 953 uint32_t flags, | 1060 uint32_t flags, |
| 954 const SkMatrix* localMatrix) { | 1061 const SkMatrix* localMatrix) { |
| 1062 ColorConverter converter(colors, colorCount); | |
| 1063 return MakeSweep(cx, cy, converter.fColors4f.begin(), nullptr, pos, colorCou nt, flags, | |
| 1064 localMatrix); | |
| 1065 } | |
| 1066 | |
| 1067 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, | |
| 1068 const SkColor4f colors[], | |
| 1069 sk_sp<SkColorSpace> colorSpace, | |
| 1070 const SkScalar pos[], | |
| 1071 int colorCount, | |
| 1072 uint32_t flags, | |
| 1073 const SkMatrix* localMatrix) { | |
| 955 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { | 1074 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { |
| 956 return nullptr; | 1075 return nullptr; |
| 957 } | 1076 } |
| 958 if (1 == colorCount) { | 1077 if (1 == colorCount) { |
| 959 return SkShader::MakeColorShader(colors[0]); | 1078 return SkShader::MakeColorShader(colors[0], std::move(colorSpace)); |
| 960 } | 1079 } |
| 961 | 1080 |
| 962 auto mode = SkShader::kClamp_TileMode; | 1081 auto mode = SkShader::kClamp_TileMode; |
| 963 | 1082 |
| 964 ColorStopOptimizer opt(colors, pos, colorCount, mode); | 1083 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 965 | 1084 |
| 966 SkGradientShaderBase::Descriptor desc; | 1085 SkGradientShaderBase::Descriptor desc; |
| 967 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix ); | 1086 desc_init(&desc, opt.fColors, std::move(colorSpace), opt.fPos, opt.fCount, m ode, flags, |
| 1087 localMatrix); | |
| 968 return sk_make_sp<SkSweepGradient>(cx, cy, desc); | 1088 return sk_make_sp<SkSweepGradient>(cx, cy, desc); |
| 969 } | 1089 } |
| 970 | 1090 |
| 971 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) | 1091 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) |
| 972 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) | 1092 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) |
| 973 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) | 1093 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) |
| 974 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) | 1094 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) |
| 975 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) | 1095 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) |
| 976 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1096 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| 977 | 1097 |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1613 (*stops)[i] = stop; | 1733 (*stops)[i] = stop; |
| 1614 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; | 1734 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; |
| 1615 } | 1735 } |
| 1616 } | 1736 } |
| 1617 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); | 1737 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); |
| 1618 | 1738 |
| 1619 return outColors; | 1739 return outColors; |
| 1620 } | 1740 } |
| 1621 | 1741 |
| 1622 #endif | 1742 #endif |
| OLD | NEW |