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