blob: 045c399e8faf548afb894fddbcfcac03125ac8bf [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.com65245ad2011-05-19 17:36:21 +000014 int shorterDimensionAsInt = w < h ? w : h;
15 SkScalar s = SkIntToScalar(shorterDimensionAsInt);
reed@google.com38690072011-01-26 01:44:18 +000016 SkPoint pts[] = { { 0, 0 }, { s, s } };
bsalomon@google.com0fdaa222011-01-25 18:35:26 +000017 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
18 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
19 SkPaint paint;
20
21 SkUnitMapper* um = NULL;
22
23 um = new SkCosineMapper;
24
25 SkAutoUnref au(um);
26
27 paint.setDither(true);
28 paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
29 SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
30 canvas.drawPaint(paint);
31}
32
33SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty,
34 int w, int h) {
35 static SkBitmap bmp;
36 if (bmp.isNull()) {
37 makebm(&bmp, SkBitmap::kARGB_8888_Config, w/2, h/4);
38 }
39 return SkShader::CreateBitmapShader(bmp, tx, ty);
40}
41
42///////////////////////////////////////////////////////////////////////////////
43
44struct GradData {
45 int fCount;
46 const SkColor* fColors;
47 const SkScalar* fPos;
48};
49
50static const SkColor gColors[] = {
51 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
52};
53
54static const GradData gGradData[] = {
55 { 2, gColors, NULL },
56 { 5, gColors, NULL },
57};
58
59static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
60 SkShader::TileMode tm, SkUnitMapper* mapper) {
61 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
62 data.fCount, tm, mapper);
63}
64
65static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
66 SkShader::TileMode tm, SkUnitMapper* mapper) {
67 SkPoint center;
68 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
69 SkScalarAve(pts[0].fY, pts[1].fY));
70 return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
71 data.fPos, data.fCount, tm, mapper);
72}
73
74static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
75 SkShader::TileMode tm, SkUnitMapper* mapper) {
76 SkPoint center;
77 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
78 SkScalarAve(pts[0].fY, pts[1].fY));
79 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
80 data.fPos, data.fCount, mapper);
81}
82
83static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
84 SkShader::TileMode tm, SkUnitMapper* mapper) {
85 SkPoint center0, center1;
86 center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
87 SkScalarAve(pts[0].fY, pts[1].fY));
88 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
89 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
90 return SkGradientShader::CreateTwoPointRadial(
91 center1, (pts[1].fX - pts[0].fX) / 7,
92 center0, (pts[1].fX - pts[0].fX) / 2,
93 data.fColors, data.fPos, data.fCount, tm, mapper);
94}
95
96typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
97 SkShader::TileMode tm, SkUnitMapper* mapper);
98static const GradMaker gGradMakers[] = {
99 MakeLinear, MakeRadial, MakeSweep, Make2Radial
100};
101
102///////////////////////////////////////////////////////////////////////////////
103
104class ShaderTextGM : public GM {
105public:
106 ShaderTextGM() {}
107
108protected:
109
110 SkString onShortName() {
111 return SkString("shadertext");
112 }
113
114 SkISize onISize() { return make_isize(950, 500); }
115
116 void drawBG(SkCanvas* canvas) {
117 canvas->drawColor(0xFFDDDDDD);
118 }
119
120 virtual void onDraw(SkCanvas* canvas) {
121 this->drawBG(canvas);
122
123 const char text[] = "Shaded Text";
124 const int textLen = SK_ARRAY_COUNT(text) - 1;
epoger@google.com65245ad2011-05-19 17:36:21 +0000125 const int pointSize = 48;
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000126
127 int w = pointSize * textLen;
128 int h = pointSize;
129
130 SkPoint pts[2] = {
131 { 0, 0 },
132 { SkIntToScalar(w), SkIntToScalar(h) }
133 };
134 SkScalar textBase = SkIntToScalar(h/2);
135
136 SkShader::TileMode tileModes[] = {
137 SkShader::kClamp_TileMode,
138 SkShader::kRepeat_TileMode,
139 SkShader::kMirror_TileMode
140 };
141
142 static const int gradCount = SK_ARRAY_COUNT(gGradData) *
143 SK_ARRAY_COUNT(gGradMakers);
144 static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
145 SK_ARRAY_COUNT(tileModes);
146 SkShader* shaders[gradCount + bmpCount];
147
148 int shdIdx = 0;
149 for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
150 for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
151 shaders[shdIdx++] = gGradMakers[m](pts,
152 gGradData[d],
153 SkShader::kClamp_TileMode,
154 NULL);
155 }
156 }
157 for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
158 for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
159 shaders[shdIdx++] = MakeBitmapShader(tileModes[tx],
160 tileModes[ty],
161 w/8, h);
162 }
163 }
164
165 SkPaint paint;
166 paint.setDither(true);
167 paint.setAntiAlias(true);
168 paint.setTextSize(SkIntToScalar(pointSize));
169
170 canvas->save();
171 canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
172
173 static const int testsPerCol = 8;
174 static const int rowHeight = 60;
175 static const int colWidth = 300;
176 canvas->save();
177 for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
178 canvas->save();
179 canvas->translate(SkIntToScalar((s / testsPerCol) * colWidth),
180 SkIntToScalar((s % testsPerCol) * rowHeight));
181 paint.setShader(shaders[s])->ref();
182 canvas->drawText(text, textLen, 0, textBase, paint);
183 canvas->restore();
184 }
185 canvas->restore();
186 }
187
188private:
189 typedef GM INHERITED;
190};
191
192///////////////////////////////////////////////////////////////////////////////
193
194static GM* MyFactory(void*) { return new ShaderTextGM; }
195static GMRegistry reg(MyFactory);
196
197}