• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "gm.h"
2 #include "SkCanvas.h"
3 #include "SkGradientShader.h"
4 #include "SkUnitMappers.h"
5 
6 namespace skiagm {
7 
makebm(SkBitmap * bm,SkBitmap::Config config,int w,int h)8 static 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);
14     SkScalar    s = SkIntToScalar(SkMin32(w, h));
15     SkPoint     pts[] = { { 0, 0 }, { s, s } };
16     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 
MakeBitmapShader(SkShader::TileMode tx,SkShader::TileMode ty,int w,int h)32 SkShader* 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 
43 struct GradData {
44     int             fCount;
45     const SkColor*  fColors;
46     const SkScalar* fPos;
47 };
48 
49 static const SkColor gColors[] = {
50     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
51 };
52 
53 static const GradData gGradData[] = {
54     { 2, gColors, NULL },
55     { 5, gColors, NULL },
56 };
57 
MakeLinear(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)58 static 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 
MakeRadial(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)64 static 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 
MakeSweep(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)73 static 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 
Make2Radial(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)82 static 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 
95 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
96                      SkShader::TileMode tm, SkUnitMapper* mapper);
97 static const GradMaker gGradMakers[] = {
98     MakeLinear, MakeRadial, MakeSweep, Make2Radial
99 };
100 
101 ///////////////////////////////////////////////////////////////////////////////
102 
103 class ShaderTextGM : public GM {
104 public:
ShaderTextGM()105 	ShaderTextGM() {}
106 
107 protected:
108 
onShortName()109     SkString onShortName() {
110         return SkString("shadertext");
111     }
112 
onISize()113 	SkISize onISize() { return make_isize(950, 500); }
114 
drawBG(SkCanvas * canvas)115     void drawBG(SkCanvas* canvas) {
116         canvas->drawColor(0xFFDDDDDD);
117     }
118 
onDraw(SkCanvas * canvas)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;
124         const int pointSize = 48;
125 
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 
172         static const int testsPerCol = 8;
173         static const int rowHeight = 60;
174         static const int colWidth = 300;
175         canvas->save();
176         for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
177             canvas->save();
178             canvas->translate(SkIntToScalar((s / testsPerCol) * colWidth),
179                               SkIntToScalar((s % testsPerCol) * rowHeight));
180                               paint.setShader(shaders[s])->ref();
181             canvas->drawText(text, textLen, 0, textBase, paint);
182             canvas->restore();
183         }
184         canvas->restore();
185     }
186 
187 private:
188     typedef GM INHERITED;
189 };
190 
191 ///////////////////////////////////////////////////////////////////////////////
192 
MyFactory(void *)193 static GM* MyFactory(void*) { return new ShaderTextGM; }
194 static GMRegistry reg(MyFactory);
195 
196 }
197