1 /*
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 */
7 #include "include/core/SkCanvas.h"
8 #include "include/effects/SkGradientShader.h"
9 #include "samplecode/Sample.h"
10
setgrad(const SkRect & r,SkColor c0,SkColor c1)11 static sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
12 SkColor colors[] = { c0, c1 };
13 SkPoint pts[] = { { r.fLeft, r.fTop }, { r.fRight, r.fTop } };
14 return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
15 }
16
test_alphagradients(SkCanvas * canvas)17 static 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);
23
24 p.setShader(setgrad(r, 0xFF00FF00, 0x0000FF00));
25 canvas->drawRect(r, p);
26 canvas->drawRect(r, p2);
27
28 r.offset(0, r.height() + SkIntToScalar(4));
29 p.setShader(setgrad(r, 0xFF00FF00, 0x00000000));
30 canvas->drawRect(r, p);
31 canvas->drawRect(r, p2);
32
33 r.offset(0, r.height() + SkIntToScalar(4));
34 p.setShader(setgrad(r, 0xFF00FF00, 0x00FF0000));
35 canvas->drawRect(r, p);
36 canvas->drawRect(r, p2);
37 }
38
39 ///////////////////////////////////////////////////////////////////////////////
40
41 struct GradData {
42 int fCount;
43 const SkColor* fColors;
44 const SkScalar* fPos;
45 };
46
47 static const SkColor gColors[] = {
48 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
49 };
50 static const SkScalar gPos0[] = { 0, SK_Scalar1 };
51 static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
52 static const SkScalar gPos2[] = {
53 0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
54 };
55
56 static const GradData gGradData[] = {
57 { 2, gColors, nullptr },
58 { 2, gColors, gPos0 },
59 { 2, gColors, gPos1 },
60 { 5, gColors, nullptr },
61 { 5, gColors, gPos2 }
62 };
63
MakeLinear(const SkPoint pts[2],const GradData & data,SkTileMode tm)64 static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
65 return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
66 }
67
MakeRadial(const SkPoint pts[2],const GradData & data,SkTileMode tm)68 static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
69 SkPoint center;
70 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
71 SkScalarAve(pts[0].fY, pts[1].fY));
72 return SkGradientShader::MakeRadial(center, center.fX, data.fColors,
73 data.fPos, data.fCount, tm);
74 }
75
MakeSweep(const SkPoint pts[2],const GradData & data,SkTileMode tm)76 static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
77 SkPoint center;
78 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
79 SkScalarAve(pts[0].fY, pts[1].fY));
80 return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
81 }
82
Make2Conical(const SkPoint pts[2],const GradData & data,SkTileMode tm)83 static sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
84 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));
89 return SkGradientShader::MakeTwoPointConical(
90 center1, (pts[1].fX - pts[0].fX) / 7,
91 center0, (pts[1].fX - pts[0].fX) / 2,
92 data.fColors, data.fPos, data.fCount, tm);
93 }
94
Make2ConicalConcentric(const SkPoint pts[2],const GradData & data,SkTileMode tm)95 static sk_sp<SkShader> Make2ConicalConcentric(const SkPoint pts[2], const GradData& data,
96 SkTileMode tm) {
97 SkPoint center;
98 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
99 SkScalarAve(pts[0].fY, pts[1].fY));
100 return SkGradientShader::MakeTwoPointConical(
101 center, (pts[1].fX - pts[0].fX) / 7,
102 center, (pts[1].fX - pts[0].fX) / 2,
103 data.fColors, data.fPos, data.fCount, tm);
104 }
105
106 typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data, SkTileMode tm);
107
108 static const GradMaker gGradMakers[] = {
109 MakeLinear, MakeRadial, MakeSweep, Make2Conical, Make2ConicalConcentric
110 };
111
112 ///////////////////////////////////////////////////////////////////////////////
113
114 class GradientsView : public Sample {
115 public:
GradientsView()116 GradientsView() {
117 this->setBGColor(0xFFDDDDDD);
118 }
119
120 protected:
name()121 SkString name() override { return SkString("Gradients"); }
122
onDrawContent(SkCanvas * canvas)123 void onDrawContent(SkCanvas* canvas) override {
124 SkPoint pts[2] = {
125 { 0, 0 },
126 { SkIntToScalar(100), SkIntToScalar(100) }
127 };
128 SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
129 SkPaint paint;
130 paint.setDither(true);
131
132 canvas->save();
133 canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
134
135 for (int tm = 0; tm < kSkTileModeCount; ++tm) {
136 canvas->save();
137 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++) {
140 paint.setShader(gGradMakers[j](pts, gGradData[i], (SkTileMode)tm));
141 canvas->drawRect(r, paint);
142 canvas->translate(0, SkIntToScalar(120));
143 }
144 canvas->restore();
145 canvas->translate(SkIntToScalar(120), 0);
146 }
147 canvas->restore();
148 canvas->translate(SK_ARRAY_COUNT(gGradData)*SkIntToScalar(120), 0);
149 }
150 canvas->restore();
151
152 canvas->translate(0, SkIntToScalar(370));
153 if (false) { // avoid bit rot, suppress warning
154 test_alphagradients(canvas);
155 }
156 }
157
158 private:
159 typedef Sample INHERITED;
160 };
161
162 ///////////////////////////////////////////////////////////////////////////////
163
164 DEF_SAMPLE( return new GradientsView(); )
165