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