• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SampleCode.h"
9 #include "SkView.h"
10 #include "SkCanvas.h"
11 #include "SkGradientShader.h"
12 
makebm(SkBitmap * bm,int w,int h)13 static void makebm(SkBitmap* bm, int w, int h) {
14     bm->allocN32Pixels(w, h);
15     bm->eraseColor(SK_ColorTRANSPARENT);
16 
17     SkCanvas    canvas(*bm);
18     SkScalar s = SkIntToScalar(w < h ? w : h);
19     SkPoint     pts[] = { { 0, 0 }, { s, s } };
20     SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
21     SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
22     SkPaint     paint;
23 
24     paint.setDither(true);
25     paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
26                                     SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode))->unref();
27     canvas.drawPaint(paint);
28 }
29 
MakeBitmapShader(SkShader::TileMode tx,SkShader::TileMode ty,int w,int h)30 static SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty,
31                            int w, int h) {
32     static SkBitmap bmp;
33     if (bmp.isNull()) {
34         makebm(&bmp, w/2, h/4);
35     }
36     return SkShader::CreateBitmapShader(bmp, tx, ty);
37 }
38 
39 ///////////////////////////////////////////////////////////////////////////////
40 
41 struct GradData {
42     int             fCount;
43     const SkColor*  fColors;
44     const SkScalar* fPos;
45 };
46 
47 static const SkColor gColors[] = {
48     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
49 };
50 
51 static const GradData gGradData[] = {
52     { 2, gColors, NULL },
53     { 5, gColors, NULL },
54 };
55 
MakeLinear(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm)56 static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
57     return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
58 }
59 
MakeRadial(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm)60 static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
61     SkPoint center;
62     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
63                SkScalarAve(pts[0].fY, pts[1].fY));
64     return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
65                                           data.fPos, data.fCount, tm);
66 }
67 
MakeSweep(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm)68 static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
69     SkPoint center;
70     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
71                SkScalarAve(pts[0].fY, pts[1].fY));
72     return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
73 }
74 
Make2Radial(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm)75 static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
76     SkPoint center0, center1;
77     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
78                 SkScalarAve(pts[0].fY, pts[1].fY));
79     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
80                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
81     return SkGradientShader::CreateTwoPointRadial(
82                             center1, (pts[1].fX - pts[0].fX) / 7,
83                             center0, (pts[1].fX - pts[0].fX) / 2,
84                             data.fColors, data.fPos, data.fCount, tm);
85 }
86 
87 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
88 
89 static const GradMaker gGradMakers[] = {
90     MakeLinear, MakeRadial, MakeSweep, Make2Radial
91 };
92 
93 ///////////////////////////////////////////////////////////////////////////////
94 
95 class ShaderTextView : public SampleView {
96 public:
ShaderTextView()97     ShaderTextView() {
98         this->setBGColor(0xFFDDDDDD);
99     }
100 
101 protected:
102     // overrides from SkEventSink
onQuery(SkEvent * evt)103     virtual bool onQuery(SkEvent* evt) {
104         if (SampleCode::TitleQ(*evt)) {
105             SampleCode::TitleR(evt, "Shader Text");
106             return true;
107         }
108         return this->INHERITED::onQuery(evt);
109     }
110 
onDrawContent(SkCanvas * canvas)111     virtual void onDrawContent(SkCanvas* canvas) {
112         const char text[] = "Shaded Text";
113         const int textLen = SK_ARRAY_COUNT(text) - 1;
114         static int pointSize = 36;
115 
116         int w = pointSize * textLen;
117         int h = pointSize;
118 
119         SkPoint pts[2] = {
120             { 0, 0 },
121             { SkIntToScalar(w), SkIntToScalar(h) }
122         };
123         SkScalar textBase = SkIntToScalar(h/2);
124 
125         SkShader::TileMode tileModes[] = {
126             SkShader::kClamp_TileMode,
127             SkShader::kRepeat_TileMode,
128             SkShader::kMirror_TileMode
129         };
130 
131         static const int gradCount = SK_ARRAY_COUNT(gGradData) *
132                                      SK_ARRAY_COUNT(gGradMakers);
133         static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
134                                     SK_ARRAY_COUNT(tileModes);
135         SkShader* shaders[gradCount + bmpCount];
136 
137         int shdIdx = 0;
138         for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
139             for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
140                 shaders[shdIdx++] = gGradMakers[m](pts,
141                                                    gGradData[d],
142                                                    SkShader::kClamp_TileMode);
143             }
144         }
145         for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
146             for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
147                 shaders[shdIdx++] = MakeBitmapShader(tileModes[tx],
148                                                      tileModes[ty],
149                                                      w/8, h);
150             }
151         }
152 
153         SkPaint paint;
154         paint.setDither(true);
155         paint.setAntiAlias(true);
156         paint.setTextSize(SkIntToScalar(pointSize));
157 
158         canvas->save();
159         canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
160 
161         SkPath path;
162         path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15),
163                                     SkIntToScalar(300), SkIntToScalar(90)),
164                                     SkIntToScalar(225), SkIntToScalar(90),
165                                     false);
166         path.close();
167 
168         static const int testsPerCol = 8;
169         static const int rowHeight = 60;
170         static const int colWidth = 300;
171         canvas->save();
172         for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
173             canvas->save();
174             size_t i = 2*s;
175             canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
176                               SkIntToScalar((i % testsPerCol) * rowHeight));
177             paint.setShader(shaders[s])->unref();
178             canvas->drawText(text, textLen, 0, textBase, paint);
179             canvas->restore();
180             canvas->save();
181             ++i;
182             canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
183                               SkIntToScalar((i % testsPerCol) * rowHeight));
184             canvas->drawTextOnPath(text, textLen, path, NULL, paint);
185             canvas->restore();
186         }
187         canvas->restore();
188     }
189 
190 private:
191     typedef SampleView INHERITED;
192 };
193 
194 ///////////////////////////////////////////////////////////////////////////////
195 
MyFactory()196 static SkView* MyFactory() { return new ShaderTextView; }
197 static SkViewRegister reg(MyFactory);
198