blob: d3c3712e6bcf0da573e0ab8cfcfdd71ef9af0898 [file] [log] [blame]
bsalomon@google.com0fdaa222011-01-25 18:35:26 +00001#include "gm.h"
2#include "SkCanvas.h"
3#include "SkGradientShader.h"
4#include "SkUnitMappers.h"
5
6namespace skiagm {
7
8static void makebm(SkBitmap* bm, SkBitmap::Config config, int w, int h) {
9 bm->setConfig(config, w, h);
10 bm->allocPixels();
11 bm->eraseColor(0);
12
13 SkCanvas canvas(*bm);
epoger@google.comb28b5e42011-05-24 14:51:57 +000014 SkScalar s = SkIntToScalar(SkMin32(w, h));
reed@google.com38690072011-01-26 01:44:18 +000015 SkPoint pts[] = { { 0, 0 }, { s, s } };
bsalomon@google.com0fdaa222011-01-25 18:35:26 +000016 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
17 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
18 SkPaint paint;
19
20 SkUnitMapper* um = NULL;
21
22 um = new SkCosineMapper;
23
24 SkAutoUnref au(um);
25
26 paint.setDither(true);
27 paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
28 SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
29 canvas.drawPaint(paint);
30}
31
32SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty,
33 int w, int h) {
34 static SkBitmap bmp;
35 if (bmp.isNull()) {
36 makebm(&bmp, SkBitmap::kARGB_8888_Config, w/2, h/4);
37 }
38 return SkShader::CreateBitmapShader(bmp, tx, ty);
39}
40
41///////////////////////////////////////////////////////////////////////////////
42
43struct GradData {
44 int fCount;
45 const SkColor* fColors;
46 const SkScalar* fPos;
47};
48
49static const SkColor gColors[] = {
50 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
51};
52
53static const GradData gGradData[] = {
54 { 2, gColors, NULL },
55 { 5, gColors, NULL },
56};
57
58static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
59 SkShader::TileMode tm, SkUnitMapper* mapper) {
60 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
61 data.fCount, tm, mapper);
62}
63
64static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
65 SkShader::TileMode tm, SkUnitMapper* mapper) {
66 SkPoint center;
67 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
68 SkScalarAve(pts[0].fY, pts[1].fY));
69 return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
70 data.fPos, data.fCount, tm, mapper);
71}
72
73static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
74 SkShader::TileMode tm, SkUnitMapper* mapper) {
75 SkPoint center;
76 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
77 SkScalarAve(pts[0].fY, pts[1].fY));
78 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
79 data.fPos, data.fCount, mapper);
80}
81
82static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
83 SkShader::TileMode tm, SkUnitMapper* mapper) {
84 SkPoint center0, center1;
85 center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
86 SkScalarAve(pts[0].fY, pts[1].fY));
87 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
88 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
89 return SkGradientShader::CreateTwoPointRadial(
90 center1, (pts[1].fX - pts[0].fX) / 7,
91 center0, (pts[1].fX - pts[0].fX) / 2,
92 data.fColors, data.fPos, data.fCount, tm, mapper);
93}
94
95typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
96 SkShader::TileMode tm, SkUnitMapper* mapper);
97static const GradMaker gGradMakers[] = {
98 MakeLinear, MakeRadial, MakeSweep, Make2Radial
99};
100
101///////////////////////////////////////////////////////////////////////////////
102
103class ShaderTextGM : public GM {
104public:
105 ShaderTextGM() {}
106
107protected:
108
109 SkString onShortName() {
110 return SkString("shadertext");
111 }
112
bsalomon@google.com39149582011-06-13 21:55:32 +0000113 SkISize onISize() { return make_isize(1450, 500); }
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000114
115 void drawBG(SkCanvas* canvas) {
116 canvas->drawColor(0xFFDDDDDD);
117 }
118
119 virtual void onDraw(SkCanvas* canvas) {
120 this->drawBG(canvas);
121
122 const char text[] = "Shaded Text";
123 const int textLen = SK_ARRAY_COUNT(text) - 1;
bsalomon@google.com39149582011-06-13 21:55:32 +0000124 const int pointSize = 36;
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000125
126 int w = pointSize * textLen;
127 int h = pointSize;
128
129 SkPoint pts[2] = {
130 { 0, 0 },
131 { SkIntToScalar(w), SkIntToScalar(h) }
132 };
133 SkScalar textBase = SkIntToScalar(h/2);
134
135 SkShader::TileMode tileModes[] = {
136 SkShader::kClamp_TileMode,
137 SkShader::kRepeat_TileMode,
138 SkShader::kMirror_TileMode
139 };
140
141 static const int gradCount = SK_ARRAY_COUNT(gGradData) *
142 SK_ARRAY_COUNT(gGradMakers);
143 static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
144 SK_ARRAY_COUNT(tileModes);
145 SkShader* shaders[gradCount + bmpCount];
146
147 int shdIdx = 0;
148 for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
149 for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
150 shaders[shdIdx++] = gGradMakers[m](pts,
151 gGradData[d],
152 SkShader::kClamp_TileMode,
153 NULL);
154 }
155 }
156 for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
157 for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
158 shaders[shdIdx++] = MakeBitmapShader(tileModes[tx],
159 tileModes[ty],
160 w/8, h);
161 }
162 }
163
164 SkPaint paint;
165 paint.setDither(true);
166 paint.setAntiAlias(true);
167 paint.setTextSize(SkIntToScalar(pointSize));
168
169 canvas->save();
170 canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
171
bsalomon@google.com39149582011-06-13 21:55:32 +0000172 SkPath path;
bsalomon@google.com137c4282011-06-14 17:13:22 +0000173 path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15),
174 SkIntToScalar(300), SkIntToScalar(90)),
175 SkIntToScalar(225), SkIntToScalar(90),
176 false);
bsalomon@google.com39149582011-06-13 21:55:32 +0000177 path.close();
178
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000179 static const int testsPerCol = 8;
180 static const int rowHeight = 60;
181 static const int colWidth = 300;
182 canvas->save();
183 for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
184 canvas->save();
bsalomon@google.com39149582011-06-13 21:55:32 +0000185 int i = 2*s;
186 canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
187 SkIntToScalar((i % testsPerCol) * rowHeight));
188 paint.setShader(shaders[s])->unref();
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000189 canvas->drawText(text, textLen, 0, textBase, paint);
190 canvas->restore();
bsalomon@google.com39149582011-06-13 21:55:32 +0000191 canvas->save();
192 ++i;
193 canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
194 SkIntToScalar((i % testsPerCol) * rowHeight));
195 canvas->drawTextOnPath(text, textLen, path, NULL, paint);
196 canvas->restore();
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000197 }
198 canvas->restore();
bsalomon@google.com39149582011-06-13 21:55:32 +0000199
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000200 }
201
202private:
203 typedef GM INHERITED;
204};
205
206///////////////////////////////////////////////////////////////////////////////
207
208static GM* MyFactory(void*) { return new ShaderTextGM; }
209static GMRegistry reg(MyFactory);
210
211}