blob: d52c1fe497c06f4dc2095f5a14cc6c82e5604cba [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 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 */
Mike Kleinc0bd9f92019-04-23 12:05:21 -05007#include "include/core/SkCanvas.h"
8#include "include/effects/SkGradientShader.h"
9#include "samplecode/Sample.h"
reed@android.coma3c05882009-04-02 20:49:39 +000010
reed8a21c9f2016-03-08 18:50:00 -080011static sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
reed@android.com1c12abe2009-07-02 15:01:02 +000012 SkColor colors[] = { c0, c1 };
13 SkPoint pts[] = { { r.fLeft, r.fTop }, { r.fRight, r.fTop } };
Mike Reedfae8fce2019-04-03 10:27:45 -040014 return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
reed@android.com1c12abe2009-07-02 15:01:02 +000015}
16
17static void test_alphagradients(SkCanvas* canvas) {
18 SkRect r;
19 r.set(SkIntToScalar(10), SkIntToScalar(10),
20 SkIntToScalar(410), SkIntToScalar(30));
21 SkPaint p, p2;
22 p2.setStyle(SkPaint::kStroke_Style);
rmistry@google.comae933ce2012-08-23 18:19:56 +000023
reed8a21c9f2016-03-08 18:50:00 -080024 p.setShader(setgrad(r, 0xFF00FF00, 0x0000FF00));
reed@android.com1c12abe2009-07-02 15:01:02 +000025 canvas->drawRect(r, p);
26 canvas->drawRect(r, p2);
rmistry@google.comae933ce2012-08-23 18:19:56 +000027
reed@android.com1c12abe2009-07-02 15:01:02 +000028 r.offset(0, r.height() + SkIntToScalar(4));
reed8a21c9f2016-03-08 18:50:00 -080029 p.setShader(setgrad(r, 0xFF00FF00, 0x00000000));
reed@android.com1c12abe2009-07-02 15:01:02 +000030 canvas->drawRect(r, p);
31 canvas->drawRect(r, p2);
rmistry@google.comae933ce2012-08-23 18:19:56 +000032
reed@android.com1c12abe2009-07-02 15:01:02 +000033 r.offset(0, r.height() + SkIntToScalar(4));
reed8a21c9f2016-03-08 18:50:00 -080034 p.setShader(setgrad(r, 0xFF00FF00, 0x00FF0000));
reed@android.com1c12abe2009-07-02 15:01:02 +000035 canvas->drawRect(r, p);
36 canvas->drawRect(r, p2);
37}
38
39///////////////////////////////////////////////////////////////////////////////
40
reed@android.coma3c05882009-04-02 20:49:39 +000041struct GradData {
42 int fCount;
43 const SkColor* fColors;
44 const SkScalar* fPos;
45};
46
47static const SkColor gColors[] = {
48 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
49};
50static const SkScalar gPos0[] = { 0, SK_Scalar1 };
51static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
52static const SkScalar gPos2[] = {
53 0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
54};
55
56static const GradData gGradData[] = {
halcanary96fcdcc2015-08-27 07:41:13 -070057 { 2, gColors, nullptr },
reed@android.coma3c05882009-04-02 20:49:39 +000058 { 2, gColors, gPos0 },
59 { 2, gColors, gPos1 },
halcanary96fcdcc2015-08-27 07:41:13 -070060 { 5, gColors, nullptr },
reed@android.coma3c05882009-04-02 20:49:39 +000061 { 5, gColors, gPos2 }
62};
63
Mike Reedfae8fce2019-04-03 10:27:45 -040064static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
reed8a21c9f2016-03-08 18:50:00 -080065 return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
reed@android.coma3c05882009-04-02 20:49:39 +000066}
rmistry@google.comae933ce2012-08-23 18:19:56 +000067
Mike Reedfae8fce2019-04-03 10:27:45 -040068static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
reed@android.coma3c05882009-04-02 20:49:39 +000069 SkPoint center;
70 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
71 SkScalarAve(pts[0].fY, pts[1].fY));
reed8a21c9f2016-03-08 18:50:00 -080072 return SkGradientShader::MakeRadial(center, center.fX, data.fColors,
73 data.fPos, data.fCount, tm);
reed@android.coma3c05882009-04-02 20:49:39 +000074}
75
Mike Reedfae8fce2019-04-03 10:27:45 -040076static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
reed@android.coma3c05882009-04-02 20:49:39 +000077 SkPoint center;
78 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
79 SkScalarAve(pts[0].fY, pts[1].fY));
reed8a21c9f2016-03-08 18:50:00 -080080 return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
reed@android.coma3c05882009-04-02 20:49:39 +000081}
82
Mike Reedfae8fce2019-04-03 10:27:45 -040083static sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
reed@android.com8e2af7e2009-09-22 20:14:42 +000084 SkPoint center0, center1;
85 center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
86 SkScalarAve(pts[0].fY, pts[1].fY));
87 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
88 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
reed8a21c9f2016-03-08 18:50:00 -080089 return SkGradientShader::MakeTwoPointConical(
reed@android.com8e2af7e2009-09-22 20:14:42 +000090 center1, (pts[1].fX - pts[0].fX) / 7,
91 center0, (pts[1].fX - pts[0].fX) / 2,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000092 data.fColors, data.fPos, data.fCount, tm);
reed@android.com8e2af7e2009-09-22 20:14:42 +000093}
94
reed8a21c9f2016-03-08 18:50:00 -080095static sk_sp<SkShader> Make2ConicalConcentric(const SkPoint pts[2], const GradData& data,
Mike Reedfae8fce2019-04-03 10:27:45 -040096 SkTileMode tm) {
bsalomon@google.comdc66c422011-04-06 19:35:37 +000097 SkPoint center;
98 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
99 SkScalarAve(pts[0].fY, pts[1].fY));
reed8a21c9f2016-03-08 18:50:00 -0800100 return SkGradientShader::MakeTwoPointConical(
bsalomon@google.comdc66c422011-04-06 19:35:37 +0000101 center, (pts[1].fX - pts[0].fX) / 7,
102 center, (pts[1].fX - pts[0].fX) / 2,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000103 data.fColors, data.fPos, data.fCount, tm);
bsalomon@google.comdc66c422011-04-06 19:35:37 +0000104}
105
Mike Reedfae8fce2019-04-03 10:27:45 -0400106typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data, SkTileMode tm);
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000107
reed@android.coma3c05882009-04-02 20:49:39 +0000108static const GradMaker gGradMakers[] = {
reed71a6cbf2015-05-04 08:32:51 -0700109 MakeLinear, MakeRadial, MakeSweep, Make2Conical, Make2ConicalConcentric
reed@android.coma3c05882009-04-02 20:49:39 +0000110};
111
112///////////////////////////////////////////////////////////////////////////////
113
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400114class GradientsView : public Sample {
reed@android.coma3c05882009-04-02 20:49:39 +0000115public:
rmistry@google.comae933ce2012-08-23 18:19:56 +0000116 GradientsView() {
reed@google.comf2183392011-04-22 14:10:48 +0000117 this->setBGColor(0xFFDDDDDD);
118 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000119
reed@android.coma3c05882009-04-02 20:49:39 +0000120protected:
Hal Canary8a027312019-07-03 10:55:44 -0400121 SkString name() override { return SkString("Gradients"); }
reed@android.coma3c05882009-04-02 20:49:39 +0000122
reed8a21c9f2016-03-08 18:50:00 -0800123 void onDrawContent(SkCanvas* canvas) override {
reed@android.coma3c05882009-04-02 20:49:39 +0000124 SkPoint pts[2] = {
125 { 0, 0 },
126 { SkIntToScalar(100), SkIntToScalar(100) }
127 };
reed@android.coma3c05882009-04-02 20:49:39 +0000128 SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
129 SkPaint paint;
reed@android.com32a42492009-07-10 03:33:52 +0000130 paint.setDither(true);
reed@android.com1c12abe2009-07-02 15:01:02 +0000131
132 canvas->save();
reed@android.com8e2af7e2009-09-22 20:14:42 +0000133 canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
bsalomon@google.comdc66c422011-04-06 19:35:37 +0000134
Mike Reedfae8fce2019-04-03 10:27:45 -0400135 for (int tm = 0; tm < kSkTileModeCount; ++tm) {
reed@android.coma3c05882009-04-02 20:49:39 +0000136 canvas->save();
bsalomon@google.comdc66c422011-04-06 19:35:37 +0000137 for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) {
138 canvas->save();
139 for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) {
Mike Reedfae8fce2019-04-03 10:27:45 -0400140 paint.setShader(gGradMakers[j](pts, gGradData[i], (SkTileMode)tm));
bsalomon@google.comdc66c422011-04-06 19:35:37 +0000141 canvas->drawRect(r, paint);
142 canvas->translate(0, SkIntToScalar(120));
143 }
144 canvas->restore();
145 canvas->translate(SkIntToScalar(120), 0);
reed@android.coma3c05882009-04-02 20:49:39 +0000146 }
147 canvas->restore();
bsalomon@google.comdc66c422011-04-06 19:35:37 +0000148 canvas->translate(SK_ARRAY_COUNT(gGradData)*SkIntToScalar(120), 0);
reed@android.coma3c05882009-04-02 20:49:39 +0000149 }
reed@android.com1c12abe2009-07-02 15:01:02 +0000150 canvas->restore();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000151
reed@android.com1c12abe2009-07-02 15:01:02 +0000152 canvas->translate(0, SkIntToScalar(370));
caryclark@google.com02939ce2012-06-06 12:09:51 +0000153 if (false) { // avoid bit rot, suppress warning
154 test_alphagradients(canvas);
155 }
reed@android.coma3c05882009-04-02 20:49:39 +0000156 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000157
reed@android.coma3c05882009-04-02 20:49:39 +0000158private:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400159 typedef Sample INHERITED;
reed@android.coma3c05882009-04-02 20:49:39 +0000160};
161
162///////////////////////////////////////////////////////////////////////////////
163
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400164DEF_SAMPLE( return new GradientsView(); )