fa8e2b59eff21b02a17c2a272569910ca675c51e
[platform/upstream/libSkiaSharp.git] / gm / shadertext.cpp
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
8 #include "gm.h"
9 #include "SkCanvas.h"
10 #include "SkGradientShader.h"
11
12 namespace skiagm {
13
14 static void makebm(SkBitmap* bm, int w, int h) {
15     bm->allocN32Pixels(w, h);
16     bm->eraseColor(SK_ColorTRANSPARENT);
17
18     SkCanvas    canvas(*bm);
19     SkScalar    s = SkIntToScalar(SkMin32(w, h));
20     SkPoint     pts[] = { { 0, 0 }, { s, s } };
21     SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
22     SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
23     SkPaint     paint;
24
25     paint.setDither(true);
26     paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
27                 SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode))->unref();
28     canvas.drawPaint(paint);
29 }
30
31 ///////////////////////////////////////////////////////////////////////////////
32
33 struct GradData {
34     int             fCount;
35     const SkColor*  fColors;
36     const SkScalar* fPos;
37 };
38
39 static const SkColor gColors[] = {
40     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
41 };
42
43 static const GradData gGradData[] = {
44     { 2, gColors, NULL },
45     { 5, gColors, NULL },
46 };
47
48 static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
49     return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
50 }
51
52 static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
53     SkPoint center;
54     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
55                SkScalarAve(pts[0].fY, pts[1].fY));
56     return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
57                                           data.fPos, data.fCount, tm);
58 }
59
60 static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode) {
61     SkPoint center;
62     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
63                SkScalarAve(pts[0].fY, pts[1].fY));
64     return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
65 }
66
67 static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
68     SkPoint center0, center1;
69     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
70                 SkScalarAve(pts[0].fY, pts[1].fY));
71     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
72                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
73     return SkGradientShader::CreateTwoPointRadial(
74                             center1, (pts[1].fX - pts[0].fX) / 7,
75                             center0, (pts[1].fX - pts[0].fX) / 2,
76                             data.fColors, data.fPos, data.fCount, tm);
77 }
78
79 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
80
81 static const GradMaker gGradMakers[] = {
82     MakeLinear, MakeRadial, MakeSweep, Make2Radial
83 };
84
85 ///////////////////////////////////////////////////////////////////////////////
86
87 class ShaderTextGM : public GM {
88 public:
89     ShaderTextGM() {
90         this->setBGColor(0xFFDDDDDD);
91     }
92
93 protected:
94
95     SkString onShortName() SK_OVERRIDE {
96         return SkString("shadertext");
97     }
98
99     SkISize onISize() SK_OVERRIDE { return SkISize::Make(1450, 500); }
100
101     void onDraw(SkCanvas* canvas) SK_OVERRIDE {
102         const char text[] = "Shaded Text";
103         const int textLen = SK_ARRAY_COUNT(text) - 1;
104         const int pointSize = 36;
105
106         const int w = pointSize * textLen;
107         const int h = pointSize;
108
109         SkPoint pts[2] = {
110             { 0, 0 },
111             { SkIntToScalar(w), SkIntToScalar(h) }
112         };
113         SkScalar textBase = SkIntToScalar(h/2);
114
115         SkShader::TileMode tileModes[] = {
116             SkShader::kClamp_TileMode,
117             SkShader::kRepeat_TileMode,
118             SkShader::kMirror_TileMode
119         };
120
121         static const int gradCount = SK_ARRAY_COUNT(gGradData) *
122                                      SK_ARRAY_COUNT(gGradMakers);
123         static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
124                                     SK_ARRAY_COUNT(tileModes);
125         SkShader* shaders[gradCount + bmpCount];
126
127         int shdIdx = 0;
128         for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
129             for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
130                 shaders[shdIdx++] = gGradMakers[m](pts,
131                                                    gGradData[d],
132                                                    SkShader::kClamp_TileMode);
133             }
134         }
135         
136         SkBitmap bm;
137         makebm(&bm, w/16, h/4);
138         for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
139             for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
140                 shaders[shdIdx++] = SkShader::CreateBitmapShader(bm, tileModes[tx], tileModes[ty]);
141             }
142         }
143
144         SkPaint paint;
145         paint.setDither(true);
146         paint.setAntiAlias(true);
147         sk_tool_utils::set_portable_typeface(&paint);
148         paint.setTextSize(SkIntToScalar(pointSize));
149
150         canvas->save();
151         canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
152
153         SkPath path;
154         path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15),
155                                     SkIntToScalar(300), SkIntToScalar(90)),
156                                     SkIntToScalar(225), SkIntToScalar(90),
157                                     false);
158         path.close();
159
160         static const int testsPerCol = 8;
161         static const int rowHeight = 60;
162         static const int colWidth = 300;
163         canvas->save();
164         for (int s = 0; s < static_cast<int>(SK_ARRAY_COUNT(shaders)); s++) {
165             canvas->save();
166             int i = 2*s;
167             canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
168                               SkIntToScalar((i % testsPerCol) * rowHeight));
169             paint.setShader(shaders[s])->unref();
170             canvas->drawText(text, textLen, 0, textBase, paint);
171             canvas->restore();
172             canvas->save();
173             ++i;
174             canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
175                               SkIntToScalar((i % testsPerCol) * rowHeight));
176             canvas->drawTextOnPath(text, textLen, path, NULL, paint);
177             canvas->restore();
178         }
179         canvas->restore();
180
181     }
182
183 private:
184     typedef GM INHERITED;
185 };
186
187 ///////////////////////////////////////////////////////////////////////////////
188
189 static GM* MyFactory(void*) { return new ShaderTextGM; }
190 static GMRegistry reg(MyFactory);
191 }