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