blob: dedf04d72a3494e48456072f478c5ca23933cc0b [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);
reed@google.com261b8e22011-04-14 17:53:24 +000013 SkScalar s = SkIntToScalar(w < h ? w : h);
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +000014 SkPoint pts[] = { { 0, 0 }, { s, s } };
bsalomon@google.com0fdaa222011-01-25 18:35:26 +000015 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
reed@google.comf2183392011-04-22 14:10:48 +0000102class ShaderTextView : public SampleView {
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000103public:
reed@google.comf2183392011-04-22 14:10:48 +0000104 ShaderTextView() {
105 this->setBGColor(0xFFDDDDDD);
106 }
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000107
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
reed@google.comf2183392011-04-22 14:10:48 +0000118 virtual void onDrawContent(SkCanvas* canvas) {
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000119 const char text[] = "Shaded Text";
120 const int textLen = SK_ARRAY_COUNT(text) - 1;
bsalomon@google.com39149582011-06-13 21:55:32 +0000121 static int pointSize = 36;
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000122
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
bsalomon@google.com39149582011-06-13 21:55:32 +0000169 SkPath path;
170 path.arcTo(SkRect::MakeXYWH(-40, 15, 300, 90),
171 SK_Scalar1 * 225, SK_Scalar1 * 90, false);
172 path.close();
173
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000174 static const int testsPerCol = 8;
175 static const int rowHeight = 60;
176 static const int colWidth = 300;
177 canvas->save();
178 for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
179 canvas->save();
bsalomon@google.com39149582011-06-13 21:55:32 +0000180 int i = 2*s;
181 canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
182 SkIntToScalar((i % testsPerCol) * rowHeight));
senorblanco@chromium.orge580bc12011-05-19 18:33:33 +0000183 paint.setShader(shaders[s])->unref();
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000184 canvas->drawText(text, textLen, 0, textBase, paint);
185 canvas->restore();
bsalomon@google.com39149582011-06-13 21:55:32 +0000186 canvas->save();
187 ++i;
188 canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
189 SkIntToScalar((i % testsPerCol) * rowHeight));
190 canvas->drawTextOnPath(text, textLen, path, NULL, paint);
191 canvas->restore();
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000192 }
193 canvas->restore();
194
195 canvas->translate(0, SkIntToScalar(370));
196 this->inval(NULL);
197 }
198
199private:
reed@google.comf2183392011-04-22 14:10:48 +0000200 typedef SampleView INHERITED;
bsalomon@google.com0fdaa222011-01-25 18:35:26 +0000201};
202
203///////////////////////////////////////////////////////////////////////////////
204
205static SkView* MyFactory() { return new ShaderTextView; }
206static SkViewRegister reg(MyFactory);
207