• 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 #include "SampleCode.h"
8 #include "SkBlurMask.h"
9 #include "SkCanvas.h"
10 #include "SkView.h"
11 #include "Sk1DPathEffect.h"
12 #include "Sk2DPathEffect.h"
13 #include "SkBlurMaskFilter.h"
14 #include "SkColorMatrixFilter.h"
15 #include "SkColorPriv.h"
16 #include "SkCornerPathEffect.h"
17 #include "SkDashPathEffect.h"
18 #include "SkDiscretePathEffect.h"
19 #include "SkEmbossMaskFilter.h"
20 #include "SkReadBuffer.h"
21 #include "SkWriteBuffer.h"
22 #include "SkGradientShader.h"
23 #include "SkMath.h"
24 #include "SkPath.h"
25 #include "SkPictureRecorder.h"
26 #include "SkRegion.h"
27 #include "SkShader.h"
28 #include "SkCornerPathEffect.h"
29 #include "SkPathMeasure.h"
30 #include "SkPicture.h"
31 #include "SkRandom.h"
32 #include "SkTypeface.h"
33 #include "SkUtils.h"
34 
35 #include <math.h>
36 #include "DecodeFile.h"
37 
38 class Dot2DPathEffect : public Sk2DPathEffect {
39 public:
Dot2DPathEffect(SkScalar radius,const SkMatrix & matrix)40     Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
41         : Sk2DPathEffect(matrix), fRadius(radius) {}
42 
43     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
44 
45 protected:
next(const SkPoint & loc,int u,int v,SkPath * dst) const46     void next(const SkPoint& loc, int u, int v, SkPath* dst) const override {
47         dst->addCircle(loc.fX, loc.fY, fRadius);
48     }
49 
flatten(SkWriteBuffer & buffer) const50     void flatten(SkWriteBuffer& buffer) const override {
51         this->INHERITED::flatten(buffer);
52         buffer.writeScalar(fRadius);
53     }
54 
55 private:
56     SkScalar fRadius;
57 
58     typedef Sk2DPathEffect INHERITED;
59 };
60 
61 class DemoView : public SampleView {
62 public:
DemoView()63     DemoView() {}
64 
65 protected:
66     // overrides from SkEventSink
onQuery(SkEvent * evt)67     virtual bool onQuery(SkEvent* evt) {
68         if (SampleCode::TitleQ(*evt)) {
69             SampleCode::TitleR(evt, "Demo");
70             return true;
71         }
72         return this->INHERITED::onQuery(evt);
73     }
74 
onClick(Click * click)75     virtual bool onClick(Click* click) {
76         return this->INHERITED::onClick(click);
77     }
78 
makePath(SkPath & path)79     void makePath(SkPath& path) {
80         path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
81             SkPath::kCCW_Direction);
82         for (int index = 0; index < 10; index++) {
83             SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
84             SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
85             x *= index & 1 ? 7 : 14;
86             y *= index & 1 ? 7 : 14;
87             x += SkIntToScalar(20);
88             y += SkIntToScalar(20);
89             if (index == 0)
90                 path.moveTo(x, y);
91             else
92                 path.lineTo(x, y);
93         }
94         path.close();
95     }
96 
onDrawContent(SkCanvas * canvas)97     virtual void onDrawContent(SkCanvas* canvas) {
98         canvas->save();
99         this->drawPicture(canvas, 0);
100         canvas->restore();
101 
102         {
103             SkPictureRecorder recorder;
104             {
105                 SkCanvas* record = recorder.beginRecording(320, 480, nullptr, 0);
106                 this->drawPicture(record, 120);
107             }
108             sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
109 
110             canvas->translate(0, SkIntToScalar(120));
111 
112             SkRect clip;
113             clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
114             do {
115                 canvas->save();
116                 canvas->clipRect(clip);
117                 picture->playback(canvas);
118                 canvas->restore();
119                 if (clip.fRight < SkIntToScalar(320))
120                     clip.offset(SkIntToScalar(160), 0);
121                 else if (clip.fBottom < SkIntToScalar(480))
122                     clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
123                 else
124                     break;
125             } while (true);
126         }
127     }
128 
drawPicture(SkCanvas * canvas,int spriteOffset)129     void drawPicture(SkCanvas* canvas, int spriteOffset) {
130         SkMatrix matrix; matrix.reset();
131         SkPaint paint;
132         SkPath path;
133         SkPoint start = {0, 0};
134         SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
135         SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
136         SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
137         SkScalar left = 0, top = 0, x = 0, y = 0;
138         int index;
139 
140         char ascii[] = "ascii...";
141         int asciiLength = sizeof(ascii) - 1;
142         char utf8[] = "utf8" "\xe2\x80\xa6";
143         short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
144         short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
145 
146         makePath(path);
147         SkTDArray<SkPoint> pos;
148         pos.setCount(asciiLength);
149         for (index = 0;  index < asciiLength; index++)
150             pos[index].set(SkIntToScalar((unsigned int)index * 10),
151                                        SkIntToScalar((unsigned int)index * 2));
152         SkTDArray<SkPoint> pos2;
153         pos2.setCount(asciiLength);
154         for (index = 0;  index < asciiLength; index++)
155             pos2[index].set(SkIntToScalar((unsigned int)index * 10),
156                                         SkIntToScalar(20));
157 
158         // shaders
159         SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
160         SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
161         SkScalar* linearPos = nullptr;
162         int linearCount = 2;
163         SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
164         auto linear = SkGradientShader::MakeLinear(linearPoints,
165             linearColors, linearPos, linearCount, linearMode);
166 
167         SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
168         SkScalar radialRadius = SkIntToScalar(25);
169         SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
170         SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
171         int radialCount = 3;
172         SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
173         auto radial = SkGradientShader::MakeRadial(radialCenter,
174             radialRadius, radialColors, radialPos, radialCount,
175             radialMode);
176 
177         SkEmbossMaskFilter::Light light;
178         light.fDirection[0] = SK_Scalar1/2;
179         light.fDirection[1] = SK_Scalar1/2;
180         light.fDirection[2] = SK_Scalar1/3;
181         light.fAmbient        = 0x48;
182         light.fSpecular        = 0x80;
183 
184         auto lightingFilter = SkColorMatrixFilter::MakeLightingFilter(
185             0xff89bc45, 0xff112233);
186 
187         canvas->save();
188         canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
189         paint.setAntiAlias(true);
190         paint.setFilterQuality(kLow_SkFilterQuality);
191         // !!! draw through a clip
192         paint.setColor(SK_ColorLTGRAY);
193         paint.setStyle(SkPaint::kFill_Style);
194         SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
195         canvas->clipRect(clip);
196         paint.setShader(SkShader::MakeBitmapShader(fTx,
197             SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode));
198         canvas->drawPaint(paint);
199         canvas->save();
200 
201         // line (exercises xfermode, colorShader, colorFilter, filterShader)
202         paint.setColor(SK_ColorGREEN);
203         paint.setStrokeWidth(SkIntToScalar(10));
204         paint.setStyle(SkPaint::kStroke_Style);
205         paint.setBlendMode(SkBlendMode::kXor);
206         paint.setColorFilter(lightingFilter);
207         canvas->drawLine(start, stop, paint); // should not be green
208         paint.setBlendMode(SkBlendMode::kSrcOver);
209         paint.setColorFilter(nullptr);
210 
211         // rectangle
212         paint.setStyle(SkPaint::kFill_Style);
213         canvas->translate(SkIntToScalar(50), 0);
214         paint.setColor(SK_ColorYELLOW);
215         paint.setShader(linear);
216         paint.setPathEffect(pathEffectTest());
217         canvas->drawRect(rect, paint);
218         paint.setPathEffect(nullptr);
219 
220         // circle w/ emboss & transparent (exercises 3dshader)
221         canvas->translate(SkIntToScalar(50), 0);
222         paint.setMaskFilter(SkEmbossMaskFilter::Make(
223                                      SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5), light));
224         canvas->drawOval(rect, paint);
225         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
226 //        paint.setShader(transparentShader)->unref();
227         canvas->drawOval(rect, paint);
228         canvas->translate(0, SkIntToScalar(-10));
229 
230         // path
231         canvas->translate(SkIntToScalar(50), 0);
232         paint.setColor(SK_ColorRED);
233         paint.setStyle(SkPaint::kStroke_Style);
234         paint.setStrokeWidth(SkIntToScalar(5));
235         paint.setShader(radial);
236         paint.setMaskFilter(nullptr);
237         canvas->drawPath(path, paint);
238 
239         paint.setShader(nullptr);
240         // bitmap
241         canvas->translate(SkIntToScalar(50), 0);
242         paint.setStyle(SkPaint::kFill_Style);
243         canvas->drawBitmap(fBug, left, top, &paint);
244 
245         canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
246         paint.setShader(shaderTest()); // test compose shader
247         canvas->drawRect(rect2, paint);
248         paint.setShader(nullptr);
249 
250         canvas->restore();
251         // text
252         canvas->translate(0, SkIntToScalar(60));
253         canvas->save();
254         paint.setColor(SK_ColorGRAY);
255         canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
256         canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
257 
258         canvas->translate(SkIntToScalar(50), 0);
259         paint.setColor(SK_ColorCYAN);
260         canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
261 
262         canvas->translate(SkIntToScalar(30), 0);
263         paint.setColor(SK_ColorMAGENTA);
264         paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
265         matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
266         canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
267         canvas->translate(0, SkIntToScalar(20));
268         canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
269         canvas->restore();
270 
271         canvas->translate(0, SkIntToScalar(60));
272         paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
273         canvas->restore();
274     }
275 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)276     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
277         fClickPt.set(x, y);
278         return this->INHERITED::onFindClickHandler(x, y, modi);
279     }
280 
pathEffectTest()281     sk_sp<SkPathEffect> pathEffectTest() {
282         static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
283         SkScalar gPhase = 0;
284         SkPath path;
285         path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
286         for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
287             path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
288         path.close();
289         path.offset(SkIntToScalar(-6), 0);
290         auto outer = SkPath1DPathEffect::Make(path, SkIntToScalar(12),
291             gPhase, SkPath1DPathEffect::kRotate_Style);
292         auto inner = SkDiscretePathEffect::Make(SkIntToScalar(2),
293             SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
294         return SkPathEffect::MakeCompose(outer, inner);
295     }
296 
shaderTest()297     sk_sp<SkShader> shaderTest() {
298         SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
299         SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
300         auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr,
301             2, SkShader::kClamp_TileMode);
302         pts[1].set(0, SkIntToScalar(100));
303         SkColor colors2[] = {SK_ColorBLACK,  SkColorSetARGB(0x80, 0, 0, 0)};
304         auto shaderB = SkGradientShader::MakeLinear(pts, colors2, nullptr,
305             2, SkShader::kClamp_TileMode);
306         return SkShader::MakeComposeShader(std::move(shaderA), std::move(shaderB),
307                                            SkBlendMode::kDstIn);
308     }
309 
startTest()310     virtual void startTest() {
311         decode_file("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
312         decode_file("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
313         decode_file("/Users/caryclark/Desktop/05psp04.gif", &fTx);
314     }
315 
316 private:
317     SkPoint fClickPt;
318     SkBitmap fBug, fTb, fTx;
319     typedef SampleView INHERITED;
320 };
321 
322 //////////////////////////////////////////////////////////////////////////////
323 
MyFactory()324 static SkView* MyFactory() { return new DemoView; }
325 static SkViewRegister reg(MyFactory);
326