1#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkGradientShader.h"
5
6static SkShader* setgrad(const SkRect& r, SkColor c0, SkColor c1) {
7    SkColor colors[] = { c0, c1 };
8    SkPoint pts[] = { { r.fLeft, r.fTop }, { r.fRight, r.fTop } };
9    return SkGradientShader::CreateLinear(pts, colors, NULL, 2,
10                                          SkShader::kClamp_TileMode, NULL);
11}
12
13static void test_alphagradients(SkCanvas* canvas) {
14    SkRect r;
15    r.set(SkIntToScalar(10), SkIntToScalar(10),
16          SkIntToScalar(410), SkIntToScalar(30));
17    SkPaint p, p2;
18    p2.setStyle(SkPaint::kStroke_Style);
19
20    p.setShader(setgrad(r, 0xFF00FF00, 0x0000FF00))->unref();
21    canvas->drawRect(r, p);
22    canvas->drawRect(r, p2);
23
24    r.offset(0, r.height() + SkIntToScalar(4));
25    p.setShader(setgrad(r, 0xFF00FF00, 0x00000000))->unref();
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, 0x00FF0000))->unref();
31    canvas->drawRect(r, p);
32    canvas->drawRect(r, p2);
33}
34
35///////////////////////////////////////////////////////////////////////////////
36
37struct GradData {
38    int             fCount;
39    const SkColor*  fColors;
40    const SkScalar* fPos;
41};
42
43static const SkColor gColors[] = {
44    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
45};
46static const SkScalar gPos0[] = { 0, SK_Scalar1 };
47static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
48static const SkScalar gPos2[] = {
49    0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
50};
51
52static const GradData gGradData[] = {
53    { 2, gColors, NULL },
54    { 2, gColors, gPos0 },
55    { 2, gColors, gPos1 },
56    { 5, gColors, NULL },
57    { 5, gColors, gPos2 }
58};
59
60static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
61                            SkShader::TileMode tm, SkUnitMapper* mapper) {
62    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
63                                          data.fCount, tm, mapper);
64}
65
66static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
67                            SkShader::TileMode tm, SkUnitMapper* mapper) {
68    SkPoint center;
69    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
70               SkScalarAve(pts[0].fY, pts[1].fY));
71    return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
72                                          data.fPos, data.fCount, tm, mapper);
73}
74
75static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
76                           SkShader::TileMode tm, SkUnitMapper* mapper) {
77    SkPoint center;
78    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
79               SkScalarAve(pts[0].fY, pts[1].fY));
80    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
81                                         data.fPos, data.fCount, mapper);
82}
83
84static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
85                           SkShader::TileMode tm, SkUnitMapper* mapper) {
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::CreateTwoPointRadial(
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, mapper);
95}
96
97static SkShader* Make2RadialConcentric(const SkPoint pts[2], const GradData& data,
98                                       SkShader::TileMode tm, SkUnitMapper* mapper) {
99    SkPoint center;
100    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
101               SkScalarAve(pts[0].fY, pts[1].fY));
102    return SkGradientShader::CreateTwoPointRadial(
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, mapper);
106}
107
108typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
109                     SkShader::TileMode tm, SkUnitMapper* mapper);
110static const GradMaker gGradMakers[] = {
111    MakeLinear, MakeRadial, MakeSweep, Make2Radial, Make2RadialConcentric
112};
113
114///////////////////////////////////////////////////////////////////////////////
115
116class GradientsView : public SampleView {
117public:
118	GradientsView() {
119        this->setBGColor(0xFFDDDDDD);
120    }
121
122protected:
123    // overrides from SkEventSink
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
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, NULL);
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     //   test_alphagradients(canvas);
165        this->inval(NULL);
166    }
167
168private:
169    typedef SampleView INHERITED;
170};
171
172///////////////////////////////////////////////////////////////////////////////
173
174static SkView* MyFactory() { return new GradientsView; }
175static SkViewRegister reg(MyFactory);
176
177