blob: 726a14fd26937171a6a35726b739f5a7d128bab9 [file] [log] [blame]
bsalomon@google.com82d12232013-09-09 15:36:26 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#include "gm.h"
8#include "SkGradientShader.h"
9
10using namespace skiagm;
11
12struct GradData {
13 int fCount;
14 const SkColor* fColors;
15 const SkScalar* fPos;
16};
17
18static const SkColor gColors[] = {
19 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE,
20};
21
22static const GradData gGradData[] = {
halcanary96fcdcc2015-08-27 07:41:13 -070023 { 1, gColors, nullptr },
24 { 2, gColors, nullptr },
25 { 3, gColors, nullptr },
26 { 4, gColors, nullptr },
bsalomon@google.com82d12232013-09-09 15:36:26 +000027};
28
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000029static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
30 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
bsalomon@google.com82d12232013-09-09 15:36:26 +000031}
32
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000033static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
bsalomon@google.com82d12232013-09-09 15:36:26 +000034 SkPoint center;
35 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
36 SkScalarAve(pts[0].fY, pts[1].fY));
37 return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000038 data.fPos, data.fCount, tm);
bsalomon@google.com82d12232013-09-09 15:36:26 +000039}
40
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000041static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode) {
bsalomon@google.com82d12232013-09-09 15:36:26 +000042 SkPoint center;
43 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
44 SkScalarAve(pts[0].fY, pts[1].fY));
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000045 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
bsalomon@google.com82d12232013-09-09 15:36:26 +000046}
47
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000048static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
bsalomon@google.com82d12232013-09-09 15:36:26 +000049 SkPoint center0, center1;
50 center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
51 SkScalarAve(pts[0].fY, pts[1].fY));
52 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
53 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
reed71a6cbf2015-05-04 08:32:51 -070054 return SkGradientShader::CreateTwoPointConical(
bsalomon@google.com82d12232013-09-09 15:36:26 +000055 center1, (pts[1].fX - pts[0].fX) / 7,
56 center0, (pts[1].fX - pts[0].fX) / 2,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000057 data.fColors, data.fPos, data.fCount, tm);
bsalomon@google.com82d12232013-09-09 15:36:26 +000058}
59
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000060static SkShader* Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
bsalomon@google.com82d12232013-09-09 15:36:26 +000061 SkPoint center0, center1;
reed80ea19c2015-05-12 10:37:34 -070062 SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
63 SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
bsalomon@google.com82d12232013-09-09 15:36:26 +000064 center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
65 center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
66 return SkGradientShader::CreateTwoPointConical(center1, radius1,
67 center0, radius0,
68 data.fColors, data.fPos,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000069 data.fCount, tm);
bsalomon@google.com82d12232013-09-09 15:36:26 +000070}
71
72
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000073typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
74
bsalomon@google.com82d12232013-09-09 15:36:26 +000075static const GradMaker gGradMakers[] = {
76 MakeLinear, MakeRadial, MakeSweep, Make2Radial, Make2Conical,
77};
78
79///////////////////////////////////////////////////////////////////////////////
80
81class GradientsNoTextureGM : public GM {
82public:
fmalita063675b2015-10-12 10:41:48 -070083 GradientsNoTextureGM(bool dither) : fDither(dither) {
caryclark65cdba62015-06-15 06:51:08 -070084 this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
bsalomon@google.com82d12232013-09-09 15:36:26 +000085 }
86
87protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000088
fmalita063675b2015-10-12 10:41:48 -070089 SkString onShortName() override {
90 return SkString(fDither ? "gradients_no_texture" : "gradients_no_texture_nodither");
91 }
92
mtklein36352bf2015-03-25 18:17:31 -070093 SkISize onISize() override { return SkISize::Make(640, 615); }
bsalomon@google.com82d12232013-09-09 15:36:26 +000094
mtklein36352bf2015-03-25 18:17:31 -070095 void onDraw(SkCanvas* canvas) override {
bsalomon@google.com82d12232013-09-09 15:36:26 +000096 static const SkPoint kPts[2] = { { 0, 0 },
97 { SkIntToScalar(50), SkIntToScalar(50) } };
98 static const SkShader::TileMode kTM = SkShader::kClamp_TileMode;
99 SkRect kRect = { 0, 0, SkIntToScalar(50), SkIntToScalar(50) };
100 SkPaint paint;
101 paint.setAntiAlias(true);
fmalita063675b2015-10-12 10:41:48 -0700102 paint.setDither(fDither);
bsalomon@google.com82d12232013-09-09 15:36:26 +0000103
104 canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
105 static const uint8_t kAlphas[] = { 0xff, 0x40 };
106 for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphas); ++a) {
107 for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); ++i) {
108 canvas->save();
109 for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); ++j) {
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000110 SkShader* shader = gGradMakers[j](kPts, gGradData[i], kTM);
bsalomon@google.com82d12232013-09-09 15:36:26 +0000111 paint.setShader(shader)->unref();
112 paint.setAlpha(kAlphas[a]);
113 canvas->drawRect(kRect, paint);
114 canvas->translate(0, SkIntToScalar(kRect.height() + 20));
115 }
116 canvas->restore();
117 canvas->translate(SkIntToScalar(kRect.width() + 20), 0);
118 }
119 }
120 }
121
122private:
fmalita063675b2015-10-12 10:41:48 -0700123 bool fDither;
124
bsalomon@google.com82d12232013-09-09 15:36:26 +0000125 typedef GM INHERITED;
126};
127
128///////////////////////////////////////////////////////////////////////////////
129
reed@google.com7b8999b2014-04-18 17:55:37 +0000130struct ColorPos {
131 SkColor* fColors;
132 SkScalar* fPos;
133 int fCount;
134
halcanary96fcdcc2015-08-27 07:41:13 -0700135 ColorPos() : fColors(nullptr), fPos(nullptr), fCount(0) {}
reed@google.com7b8999b2014-04-18 17:55:37 +0000136 ~ColorPos() {
halcanary385fe4d2015-08-26 13:07:48 -0700137 delete[] fColors;
138 delete[] fPos;
reed@google.com7b8999b2014-04-18 17:55:37 +0000139 }
140
141 void construct(const SkColor colors[], const SkScalar pos[], int count) {
halcanary385fe4d2015-08-26 13:07:48 -0700142 fColors = new SkColor[count];
reed@google.com7b8999b2014-04-18 17:55:37 +0000143 memcpy(fColors, colors, count * sizeof(SkColor));
144 if (pos) {
halcanary385fe4d2015-08-26 13:07:48 -0700145 fPos = new SkScalar[count];
reed@google.com7b8999b2014-04-18 17:55:37 +0000146 memcpy(fPos, pos, count * sizeof(SkScalar));
147 fPos[0] = 0;
148 fPos[count - 1] = 1;
149 }
150 fCount = count;
151 }
152};
153
154static void make0(ColorPos* rec) {
155#if 0
156 From http://jsfiddle.net/3fe2a/
157
158background-image: -webkit-linear-gradient(left, #22d1cd 1%, #22d1cd 0.9510157507590116%, #df4b37 2.9510157507590113%, #df4b37 23.695886056604927%, #22d1cd 25.695886056604927%, #22d1cd 25.39321881940624%, #e6de36 27.39321881940624%, #e6de36 31.849399922570655%, #3267ff 33.849399922570655%, #3267ff 44.57735802921938%, #9d47d1 46.57735802921938%, #9d47d1 53.27185850805876%, #3267ff 55.27185850805876%, #3267ff 61.95718972227316%, #5cdd9d 63.95718972227316%, #5cdd9d 69.89166004442%, #3267ff 71.89166004442%, #3267ff 74.45795382765857%, #9d47d1 76.45795382765857%, #9d47d1 82.78364610713776%, #3267ff 84.78364610713776%, #3267ff 94.52743647737229%, #e3d082 96.52743647737229%, #e3d082 96.03934633331295%);
159height: 30px;
160#endif
161
162 const SkColor colors[] = {
163 0xFF22d1cd, 0xFF22d1cd, 0xFFdf4b37, 0xFFdf4b37, 0xFF22d1cd, 0xFF22d1cd, 0xFFe6de36, 0xFFe6de36,
164 0xFF3267ff, 0xFF3267ff, 0xFF9d47d1, 0xFF9d47d1, 0xFF3267ff, 0xFF3267ff, 0xFF5cdd9d, 0xFF5cdd9d,
165 0xFF3267ff, 0xFF3267ff, 0xFF9d47d1, 0xFF9d47d1, 0xFF3267ff, 0xFF3267ff, 0xFFe3d082, 0xFFe3d082
166 };
167 const double percent[] = {
168 1, 0.9510157507590116, 2.9510157507590113, 23.695886056604927,
169 25.695886056604927, 25.39321881940624, 27.39321881940624, 31.849399922570655,
170 33.849399922570655, 44.57735802921938, 46.57735802921938, 53.27185850805876,
171 55.27185850805876, 61.95718972227316, 63.95718972227316, 69.89166004442,
172 71.89166004442, 74.45795382765857, 76.45795382765857, 82.78364610713776,
173 84.78364610713776, 94.52743647737229, 96.52743647737229, 96.03934633331295,
174 };
175 const int N = SK_ARRAY_COUNT(percent);
176 SkScalar pos[N];
177 for (int i = 0; i < N; ++i) {
178 pos[i] = SkDoubleToScalar(percent[i] / 100);
179 }
180 rec->construct(colors, pos, N);
181}
182
183static void make1(ColorPos* rec) {
184 const SkColor colors[] = {
185 SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
186 SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
187 SK_ColorBLACK,
188 };
halcanary96fcdcc2015-08-27 07:41:13 -0700189 rec->construct(colors, nullptr, SK_ARRAY_COUNT(colors));
reed@google.com7b8999b2014-04-18 17:55:37 +0000190}
191
192static void make2(ColorPos* rec) {
193 const SkColor colors[] = {
194 SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
195 SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
196 SK_ColorBLACK,
197 };
198 const int N = SK_ARRAY_COUNT(colors);
199 SkScalar pos[N];
200 for (int i = 0; i < N; ++i) {
201 pos[i] = SK_Scalar1 * i / (N - 1);
202 }
203 rec->construct(colors, pos, N);
204}
205
206class GradientsManyColorsGM : public GM {
207 enum {
208 W = 800,
209 };
210 SkAutoTUnref<SkShader> fShader;
211
212 typedef void (*Proc)(ColorPos*);
213public:
fmalita063675b2015-10-12 10:41:48 -0700214 GradientsManyColorsGM(bool dither) : fDither(dither) {}
skia.committer@gmail.com8a777a52014-04-19 03:04:56 +0000215
reed@google.com7b8999b2014-04-18 17:55:37 +0000216protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000217
fmalita063675b2015-10-12 10:41:48 -0700218 SkString onShortName() override {
219 return SkString(fDither ? "gradients_many" : "gradients_many_nodither");
220 }
221
mtklein36352bf2015-03-25 18:17:31 -0700222 SkISize onISize() override { return SkISize::Make(850, 100); }
skia.committer@gmail.com8a777a52014-04-19 03:04:56 +0000223
mtklein36352bf2015-03-25 18:17:31 -0700224 void onDraw(SkCanvas* canvas) override {
reed@google.com7b8999b2014-04-18 17:55:37 +0000225 const Proc procs[] = {
226 make0, make1, make2,
227 };
228 const SkPoint pts[] = {
229 { 0, 0 },
230 { SkIntToScalar(W), 0 },
231 };
232 const SkRect r = SkRect::MakeWH(SkIntToScalar(W), 30);
233
234 SkPaint paint;
fmalita063675b2015-10-12 10:41:48 -0700235 paint.setDither(fDither);
skia.committer@gmail.com8a777a52014-04-19 03:04:56 +0000236
reed@google.com7b8999b2014-04-18 17:55:37 +0000237 canvas->translate(20, 20);
skia.committer@gmail.com8a777a52014-04-19 03:04:56 +0000238
reed@google.com7b8999b2014-04-18 17:55:37 +0000239 for (int i = 0; i <= 8; ++i) {
240 SkScalar x = r.width() * i / 8;
241 canvas->drawLine(x, 0, x, 10000, paint);
242 }
243
244 for (size_t i = 0; i < SK_ARRAY_COUNT(procs); ++i) {
245 ColorPos rec;
246 procs[i](&rec);
247 SkShader* s = SkGradientShader::CreateLinear(pts, rec.fColors, rec.fPos, rec.fCount,
248 SkShader::kClamp_TileMode);
249 paint.setShader(s)->unref();
250 canvas->drawRect(r, paint);
251 canvas->translate(0, r.height() + 20);
252 }
253 }
skia.committer@gmail.com8a777a52014-04-19 03:04:56 +0000254
reed@google.com7b8999b2014-04-18 17:55:37 +0000255private:
fmalita063675b2015-10-12 10:41:48 -0700256 bool fDither;
257
reed@google.com7b8999b2014-04-18 17:55:37 +0000258 typedef GM INHERITED;
259};
260
261///////////////////////////////////////////////////////////////////////////////
262
fmalita063675b2015-10-12 10:41:48 -0700263DEF_GM(return new GradientsNoTextureGM(true);)
264DEF_GM(return new GradientsNoTextureGM(false);)
265DEF_GM(return new GradientsManyColorsGM(true);)
266DEF_GM(return new GradientsManyColorsGM(false);)