SampleShaderText.cpp revision 137c428290ac7a4804edf564c552711ffb9dfa58
1#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkGradientShader.h"
5#include "SkUnitMappers.h"
6
7static void makebm(SkBitmap* bm, SkBitmap::Config config, int w, int h) {
8    bm->setConfig(config, w, h);
9    bm->allocPixels();
10    bm->eraseColor(0);
11
12    SkCanvas    canvas(*bm);
13    SkScalar s = SkIntToScalar(w < h ? w : h);
14    SkPoint     pts[] = { { 0, 0 }, { s, s } };
15    SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
16    SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
17    SkPaint     paint;
18
19    SkUnitMapper*   um = NULL;
20
21    um = new SkCosineMapper;
22
23    SkAutoUnref au(um);
24
25    paint.setDither(true);
26    paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
27                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
28    canvas.drawPaint(paint);
29}
30
31SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty,
32                           int w, int h) {
33    static SkBitmap bmp;
34    if (bmp.isNull()) {
35        makebm(&bmp, SkBitmap::kARGB_8888_Config, w/2, h/4);
36    }
37    return SkShader::CreateBitmapShader(bmp, tx, ty);
38}
39
40///////////////////////////////////////////////////////////////////////////////
41
42struct GradData {
43    int             fCount;
44    const SkColor*  fColors;
45    const SkScalar* fPos;
46};
47
48static const SkColor gColors[] = {
49    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
50};
51
52static const GradData gGradData[] = {
53    { 2, gColors, NULL },
54    { 5, gColors, NULL },
55};
56
57static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
58                            SkShader::TileMode tm, SkUnitMapper* mapper) {
59    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
60                                          data.fCount, tm, mapper);
61}
62
63static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
64                            SkShader::TileMode tm, SkUnitMapper* mapper) {
65    SkPoint center;
66    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
67               SkScalarAve(pts[0].fY, pts[1].fY));
68    return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
69                                          data.fPos, data.fCount, tm, mapper);
70}
71
72static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
73                           SkShader::TileMode tm, SkUnitMapper* mapper) {
74    SkPoint center;
75    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
76               SkScalarAve(pts[0].fY, pts[1].fY));
77    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
78                                         data.fPos, data.fCount, mapper);
79}
80
81static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
82                           SkShader::TileMode tm, SkUnitMapper* mapper) {
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::CreateTwoPointRadial(
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, mapper);
92}
93
94typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
95                     SkShader::TileMode tm, SkUnitMapper* mapper);
96static const GradMaker gGradMakers[] = {
97    MakeLinear, MakeRadial, MakeSweep, Make2Radial
98};
99
100///////////////////////////////////////////////////////////////////////////////
101
102class ShaderTextView : public SampleView {
103public:
104	ShaderTextView() {
105        this->setBGColor(0xFFDDDDDD);
106    }
107
108protected:
109    // overrides from SkEventSink
110    virtual bool onQuery(SkEvent* evt) {
111        if (SampleCode::TitleQ(*evt)) {
112            SampleCode::TitleR(evt, "Shader Text");
113            return true;
114        }
115        return this->INHERITED::onQuery(evt);
116    }
117
118    virtual void onDrawContent(SkCanvas* canvas) {
119        const char text[] = "Shaded Text";
120        const int textLen = SK_ARRAY_COUNT(text) - 1;
121        static int pointSize = 36;
122
123        int w = pointSize * textLen;
124        int h = pointSize;
125
126        SkPoint pts[2] = {
127            { 0, 0 },
128            { SkIntToScalar(w), SkIntToScalar(h) }
129        };
130        SkScalar textBase = SkIntToScalar(h/2);
131
132        SkShader::TileMode tileModes[] = {
133            SkShader::kClamp_TileMode,
134            SkShader::kRepeat_TileMode,
135            SkShader::kMirror_TileMode
136        };
137
138        static const int gradCount = SK_ARRAY_COUNT(gGradData) *
139                                     SK_ARRAY_COUNT(gGradMakers);
140        static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
141                                    SK_ARRAY_COUNT(tileModes);
142        SkShader* shaders[gradCount + bmpCount];
143
144        int shdIdx = 0;
145        for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
146            for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
147                shaders[shdIdx++] = gGradMakers[m](pts,
148                                                   gGradData[d],
149                                                   SkShader::kClamp_TileMode,
150                                                   NULL);
151            }
152        }
153        for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
154            for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
155                shaders[shdIdx++] = MakeBitmapShader(tileModes[tx],
156                                                     tileModes[ty],
157                                                     w/8, h);
158            }
159        }
160
161        SkPaint paint;
162        paint.setDither(true);
163        paint.setAntiAlias(true);
164        paint.setTextSize(SkIntToScalar(pointSize));
165
166        canvas->save();
167        canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
168
169        SkPath path;
170        path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15),
171                                    SkIntToScalar(300), SkIntToScalar(90)),
172                                    SkIntToScalar(225), SkIntToScalar(90),
173                                    false);
174        path.close();
175
176        static const int testsPerCol = 8;
177        static const int rowHeight = 60;
178        static const int colWidth = 300;
179        canvas->save();
180        for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
181            canvas->save();
182            int i = 2*s;
183            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
184                              SkIntToScalar((i % testsPerCol) * rowHeight));
185            paint.setShader(shaders[s])->unref();
186            canvas->drawText(text, textLen, 0, textBase, paint);
187            canvas->restore();
188            canvas->save();
189            ++i;
190            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
191                              SkIntToScalar((i % testsPerCol) * rowHeight));
192            canvas->drawTextOnPath(text, textLen, path, NULL, paint);
193            canvas->restore();
194        }
195        canvas->restore();
196
197        canvas->translate(0, SkIntToScalar(370));
198        this->inval(NULL);
199    }
200
201private:
202    typedef SampleView INHERITED;
203};
204
205///////////////////////////////////////////////////////////////////////////////
206
207static SkView* MyFactory() { return new ShaderTextView; }
208static SkViewRegister reg(MyFactory);
209
210