1/*
2 * Copyright 2013 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
8#include "gm.h"
9#include "SkCanvas.h"
10#include "SkGradientShader.h"
11#include "SkRandom.h"
12
13static SkShader* make_shader(SkScalar w, SkScalar h) {
14    const SkColor colors[] = {
15        SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
16        SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW,
17    };
18    const SkPoint pts[] = { { w/4, 0 }, { 3*w/4, h } };
19
20    return SkGradientShader::CreateLinear(pts, colors, NULL,
21                                          SK_ARRAY_COUNT(colors),
22                                          SkShader::kMirror_TileMode);
23}
24
25class VerticesGM : public skiagm::GM {
26    SkPoint     fPts[9];
27    SkPoint     fTexs[9];
28    SkColor     fColors[9];
29    SkShader*   fShader;
30    unsigned    fAlpha;
31
32public:
33    VerticesGM(unsigned alpha) : fShader(NULL), fAlpha(alpha) {
34    }
35
36    virtual ~VerticesGM() {
37        SkSafeUnref(fShader);
38    }
39
40protected:
41    virtual uint32_t onGetFlags() const SK_OVERRIDE {
42        return kSkipTiled_Flag;
43    }
44
45    virtual void onOnceBeforeDraw() SK_OVERRIDE {
46        const SkScalar X = 150;
47        const SkScalar Y = 150;
48
49        fPts[0].set(0, 0);      fPts[1].set(X/2, 10);   fPts[2].set(X, 0);
50        fPts[3].set(10, Y/2);   fPts[4].set(X/2, Y/2);  fPts[5].set(X-10, Y/2);
51        fPts[6].set(0, Y);    fPts[7].set(X/2, Y-10);  fPts[8].set(X, Y);
52
53        const SkScalar w = 200;
54        const SkScalar h = 200;
55
56        fTexs[0].set(0, 0);     fTexs[1].set(w/2, 0);   fTexs[2].set(w, 0);
57        fTexs[3].set(0, h/2);   fTexs[4].set(w/2, h/2); fTexs[5].set(w, h/2);
58        fTexs[6].set(0, h);     fTexs[7].set(w/2, h);   fTexs[8].set(w, h);
59
60        fShader = make_shader(w, h);
61
62        SkRandom rand;
63        for (size_t i = 0; i < SK_ARRAY_COUNT(fColors); ++i) {
64            fColors[i] = rand.nextU() | 0xFF000000;
65        }
66    }
67
68    virtual SkString onShortName() SK_OVERRIDE {
69        SkString name("vertices");
70        if (0xFF != fAlpha) {
71            name.appendf("_%02X", fAlpha);
72        }
73        return name;
74    }
75
76    virtual SkISize onISize() SK_OVERRIDE {
77        return SkISize::Make(600, 600);
78    }
79
80    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
81        // start with the center of a 3x3 grid
82        static const uint16_t fan[] = {
83            4,
84            0, 1, 2, 5, 8, 7, 6, 3, 0
85        };
86
87        const struct {
88            const SkColor*  fColors;
89            const SkPoint*  fTexs;
90        } rec[] = {
91            { fColors,  NULL },
92            { NULL,     fTexs },
93            { fColors,  fTexs },
94        };
95
96        const SkXfermode::Mode modes[] = {
97            SkXfermode::kSrc_Mode,
98            SkXfermode::kDst_Mode,
99            SkXfermode::kModulate_Mode,
100        };
101
102        SkPaint paint;
103        paint.setShader(fShader);
104        paint.setAlpha(fAlpha);
105
106        canvas->translate(20, 20);
107        for (size_t j = 0; j < SK_ARRAY_COUNT(modes); ++j) {
108            SkXfermode* xfer = SkXfermode::Create(modes[j]);
109            canvas->save();
110            for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
111                canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode,
112                                     SK_ARRAY_COUNT(fPts), fPts,
113                                     rec[i].fTexs, rec[i].fColors,
114                                     xfer, fan, SK_ARRAY_COUNT(fan), paint);
115                canvas->translate(200, 0);
116            }
117            canvas->restore();
118            canvas->translate(0, 200);
119            xfer->unref();
120        }
121    }
122
123private:
124    typedef skiagm::GM INHERITED;
125};
126
127/////////////////////////////////////////////////////////////////////////////////////
128
129DEF_GM( return SkNEW_ARGS(VerticesGM, (0xFF)); )
130DEF_GM( return SkNEW_ARGS(VerticesGM, (0x80)); )
131