blob: 36692d292a57ccb3599f122b8885df235767726f [file] [log] [blame]
bsalomon@google.com0fdaa222011-01-25 18:35:26 +00001#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 = 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 SkView {
103public:
104 ShaderTextView() {}
105
106protected:
107 // overrides from SkEventSink
108 virtual bool onQuery(SkEvent* evt) {
109 if (SampleCode::TitleQ(*evt)) {
110 SampleCode::TitleR(evt, "Shader Text");
111 return true;
112 }
113 return this->INHERITED::onQuery(evt);
114 }
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;
125 static int pointSize = SkIntToScalar(48);
126
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 canvas->translate(0, SkIntToScalar(370));
188 this->inval(NULL);
189 }
190
191private:
192 typedef SkView INHERITED;
193};
194
195///////////////////////////////////////////////////////////////////////////////
196
197static SkView* MyFactory() { return new ShaderTextView; }
198static SkViewRegister reg(MyFactory);
199