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