blob: 4f4116b3b0e09dc0afabcb9a9a0bb2c345828b0b [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SampleCode.h"
robertphillips@google.comb7061172013-09-06 14:16:12 +00009#include "SkBlurMask.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#include "SkCanvas.h"
11#include "SkView.h"
12#include "Sk1DPathEffect.h"
13#include "Sk2DPathEffect.h"
14#include "SkAvoidXfermode.h"
15#include "SkBlurMaskFilter.h"
16#include "SkColorFilter.h"
17#include "SkColorPriv.h"
18#include "SkCornerPathEffect.h"
19#include "SkDashPathEffect.h"
20#include "SkDiscretePathEffect.h"
21#include "SkEmbossMaskFilter.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000022#include "SkReadBuffer.h"
23#include "SkWriteBuffer.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000024#include "SkGradientShader.h"
25#include "SkImageDecoder.h"
26#include "SkLayerRasterizer.h"
27#include "SkMath.h"
28#include "SkPath.h"
29#include "SkRegion.h"
30#include "SkShader.h"
reed@android.comaa5a7db2009-05-27 01:20:10 +000031#include "SkComposeShader.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000032#include "SkCornerPathEffect.h"
33#include "SkPathMeasure.h"
34#include "SkPicture.h"
35#include "SkRandom.h"
36#include "SkTransparentShader.h"
37#include "SkTypeface.h"
38#include "SkUnitMappers.h"
39#include "SkUtils.h"
40#include "SkXfermode.h"
41
42#include <math.h>
rmistry@google.comae933ce2012-08-23 18:19:56 +000043
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000044static inline SkPMColor rgb2gray(SkPMColor c) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000045 unsigned r = SkGetPackedR32(c);
46 unsigned g = SkGetPackedG32(c);
47 unsigned b = SkGetPackedB32(c);
rmistry@google.comae933ce2012-08-23 18:19:56 +000048
reed@android.comf2b98d62010-12-20 18:26:13 +000049 unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
rmistry@google.comae933ce2012-08-23 18:19:56 +000050
reed@android.com8a1c16f2008-12-17 15:59:43 +000051 return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
52}
53
54class SkGrayScaleColorFilter : public SkColorFilter {
55public:
mike@reedtribe.org61490fa2012-12-24 14:38:46 +000056 virtual void filterSpan(const SkPMColor src[], int count,
57 SkPMColor result[]) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +000058 for (int i = 0; i < count; i++)
59 result[i] = rgb2gray(src[i]);
60 }
61};
62
63class SkChannelMaskColorFilter : public SkColorFilter {
64public:
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000065 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000066 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
67 }
68
mike@reedtribe.org61490fa2012-12-24 14:38:46 +000069 virtual void filterSpan(const SkPMColor src[], int count,
70 SkPMColor result[]) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +000071 SkPMColor mask = fMask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000072 for (int i = 0; i < count; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000073 result[i] = src[i] & mask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000074 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000075 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000076
reed@android.com8a1c16f2008-12-17 15:59:43 +000077private:
78 SkPMColor fMask;
79};
80
81///////////////////////////////////////////////////////////
82
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000083static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
robertphillips@google.comb7061172013-09-06 14:16:12 +000084 p.setMaskFilter(SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle,
85 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)),
robertphillips@google.com7ce661d2013-08-27 16:14:03 +000086 SkBlurMaskFilter::kNone_BlurFlag))->unref();
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000087 rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
reed@android.com8a1c16f2008-12-17 15:59:43 +000088
89 p.setMaskFilter(NULL);
90 p.setStyle(SkPaint::kStroke_Style);
91 p.setStrokeWidth(SK_Scalar1);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000092 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +000093
94 p.setAlpha(0x11);
95 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +000096 p.setXfermodeMode(SkXfermode::kSrc_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000097 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +000098}
99
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000100static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
101 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102
103 p.setAlpha(0x40);
reed@android.com0baf1932009-06-24 12:41:42 +0000104 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105 p.setStyle(SkPaint::kStroke_Style);
106 p.setStrokeWidth(SK_Scalar1*2);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000107 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000109
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000110static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111 p.setStyle(SkPaint::kStrokeAndFill_Style);
112 p.setStrokeWidth(SK_Scalar1*4);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000113 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000114
115 p.setStyle(SkPaint::kStroke_Style);
116 p.setStrokeWidth(SK_Scalar1*3/2);
reed@android.com0baf1932009-06-24 12:41:42 +0000117 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000118 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119}
120
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000121static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122 p.setStyle(SkPaint::kStroke_Style);
123 p.setStrokeWidth(SK_Scalar1*3);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000124 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000125
126 p.setAlpha(0x20);
127 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +0000128 p.setXfermodeMode(SkXfermode::kSrc_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000129 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000130}
131
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000132static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000133 p.setAlpha(0x60);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000134 rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135
136 p.setAlpha(0xFF);
reed@android.com0baf1932009-06-24 12:41:42 +0000137 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000138 rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000139
140 p.setXfermode(NULL);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000141 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000142}
143
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000144static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
145 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146
commit-bot@chromium.org0a2bf902014-02-20 20:40:19 +0000147 p.setPathEffect(SkDiscretePathEffect::Create(SK_Scalar1*4, SK_Scalar1*3))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000148 p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000149 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000150}
151
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000152static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
153 rastBuilder->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000154
reed@android.com8a1c16f2008-12-17 15:59:43 +0000155 p.setAntiAlias(false);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000156 SkLayerRasterizer::Builder rastBuilder2;
157 r5(&rastBuilder2, p);
158 p.setRasterizer(rastBuilder2.detachRasterizer())->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000159 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000160 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000161}
162
163class Dot2DPathEffect : public Sk2DPathEffect {
164public:
165 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
166 : Sk2DPathEffect(matrix), fRadius(radius) {}
167
djsollen@google.comba28d032012-03-26 17:57:35 +0000168 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000169
170protected:
mike@reedtribe.org61490fa2012-12-24 14:38:46 +0000171 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000172 dst->addCircle(loc.fX, loc.fY, fRadius);
173 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000174
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000175 Dot2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000176 fRadius = buffer.readScalar();
177 }
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000178 virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
djsollen@google.com54924242012-03-29 15:18:04 +0000179 this->INHERITED::flatten(buffer);
180 buffer.writeScalar(fRadius);
181 }
182
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183private:
184 SkScalar fRadius;
185
reed@android.com8a1c16f2008-12-17 15:59:43 +0000186 typedef Sk2DPathEffect INHERITED;
187};
188
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000189static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000190 SkMatrix lattice;
191 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
192 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
193 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000194 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000195}
196
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000197static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
198 rastBuilder->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000199
reed@android.com8a1c16f2008-12-17 15:59:43 +0000200 SkMatrix lattice;
201 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
202 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
203 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000204 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000205 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000206
207 p.setPathEffect(NULL);
208 p.setXfermode(NULL);
209 p.setStyle(SkPaint::kStroke_Style);
210 p.setStrokeWidth(SK_Scalar1);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000211 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000212}
213
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000214static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
215 rastBuilder->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000216
reed@android.com8a1c16f2008-12-17 15:59:43 +0000217 SkMatrix lattice;
218 lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
219 lattice.postRotate(SkIntToScalar(30), 0, 0);
commit-bot@chromium.org0a2bf902014-02-20 20:40:19 +0000220 p.setPathEffect(SkLine2DPathEffect::Create(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000221 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000222 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000223
224 p.setPathEffect(NULL);
225 p.setXfermode(NULL);
226 p.setStyle(SkPaint::kStroke_Style);
227 p.setStrokeWidth(SK_Scalar1);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000228 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000229}
230
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000231typedef void (*raster_proc)(SkLayerRasterizer::Builder*, SkPaint&);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000232
233static const raster_proc gRastProcs[] = {
234 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
235};
236
237static const struct {
238 SkColor fMul, fAdd;
239} gLightingColors[] = {
240 { 0x808080, 0x800000 }, // general case
241 { 0x707070, 0x707070 }, // no-pin case
242 { 0xFFFFFF, 0x800000 }, // just-add case
243 { 0x808080, 0x000000 }, // just-mul case
244 { 0xFFFFFF, 0x000000 } // identity case
245};
246
rmistry@google.comae933ce2012-08-23 18:19:56 +0000247static void apply_shader(SkPaint* paint, int index) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000248 raster_proc proc = gRastProcs[index];
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000249 if (proc) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000250 SkPaint p;
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000251 SkLayerRasterizer::Builder rastBuilder;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000252
253 p.setAntiAlias(true);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000254 proc(&rastBuilder, p);
255 paint->setRasterizer(rastBuilder.detachRasterizer())->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000256 }
257
258#if 1
259 SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
robertphillips@google.comb7061172013-09-06 14:16:12 +0000260 paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(
261 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), dir,
262 SK_Scalar1/4, SkIntToScalar(4)))->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000263 paint->setColor(SK_ColorBLUE);
264#endif
265}
266
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000267class DemoView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000268public:
reed@google.com2f3dc9d2011-05-02 17:33:45 +0000269 DemoView() {}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000270
reed@android.com8a1c16f2008-12-17 15:59:43 +0000271protected:
272 // overrides from SkEventSink
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000273 virtual bool onQuery(SkEvent* evt) {
274 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000275 SampleCode::TitleR(evt, "Demo");
276 return true;
277 }
278 return this->INHERITED::onQuery(evt);
279 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000280
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000281 virtual bool onClick(Click* click) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000282 return this->INHERITED::onClick(click);
283 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000284
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000285 void makePath(SkPath& path) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000286 path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
287 SkPath::kCCW_Direction);
288 for (int index = 0; index < 10; index++) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000289 SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
290 SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000291 x *= index & 1 ? 7 : 14;
292 y *= index & 1 ? 7 : 14;
293 x += SkIntToScalar(20);
294 y += SkIntToScalar(20);
295 if (index == 0)
296 path.moveTo(x, y);
297 else
298 path.lineTo(x, y);
299 }
300 path.close();
301 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000302
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000303 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000304 canvas->save();
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000305 this->drawPicture(canvas, 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000306 canvas->restore();
307
308 {
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000309 SkPictureRecorder recorder;
310 {
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000311 SkCanvas* record = recorder.beginRecording(320, 480, NULL, 0);
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000312 this->drawPicture(record, 120);
313 }
314 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
315
reed@android.com8a1c16f2008-12-17 15:59:43 +0000316 canvas->translate(0, SkIntToScalar(120));
317
318 SkRect clip;
319 clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
320 do {
321 canvas->save();
322 canvas->clipRect(clip);
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000323 picture->draw(canvas);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000324 canvas->restore();
325 if (clip.fRight < SkIntToScalar(320))
326 clip.offset(SkIntToScalar(160), 0);
327 else if (clip.fBottom < SkIntToScalar(480))
328 clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
329 else
330 break;
331 } while (true);
332 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000333 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000334
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000335 void drawPicture(SkCanvas* canvas, int spriteOffset) {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000336 SkMatrix matrix; matrix.reset();
337 SkPaint paint;
338 SkPath path;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000339 SkPoint start = {0, 0};
340 SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000341 SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
342 SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
343 SkScalar left = 0, top = 0, x = 0, y = 0;
reed@google.com7fa2a652014-01-27 13:42:58 +0000344 int index;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000345
346 char ascii[] = "ascii...";
reed@google.com7fa2a652014-01-27 13:42:58 +0000347 int asciiLength = sizeof(ascii) - 1;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000348 char utf8[] = "utf8" "\xe2\x80\xa6";
349 short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
350 short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
351
reed@android.com8a1c16f2008-12-17 15:59:43 +0000352 makePath(path);
353 SkTDArray<SkPoint>(pos);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000354 pos.setCount(asciiLength);
355 for (index = 0; index < asciiLength; index++)
356 pos[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000357 SkIntToScalar((unsigned int)index * 2));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000358 SkTDArray<SkPoint>(pos2);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000359 pos2.setCount(asciiLength);
360 for (index = 0; index < asciiLength; index++)
361 pos2[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000362 SkIntToScalar(20));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000363
reed@android.com8a1c16f2008-12-17 15:59:43 +0000364 // shaders
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000365 SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000366 SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
367 SkScalar* linearPos = NULL;
368 int linearCount = 2;
369 SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
370 SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
371 SkAutoUnref unmapLinearMapper(linearMapper);
372 SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
373 linearColors, linearPos, linearCount, linearMode, linearMapper);
374
375 SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
376 SkScalar radialRadius = SkIntToScalar(25);
377 SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
378 SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
379 int radialCount = 3;
380 SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
381 SkUnitMapper* radialMapper = new SkCosineMapper();
382 SkAutoUnref unmapRadialMapper(radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000383 SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000384 radialRadius, radialColors, radialPos, radialCount,
385 radialMode, radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000386
reed@android.com8a1c16f2008-12-17 15:59:43 +0000387 SkTransparentShader* transparentShader = new SkTransparentShader();
388 SkEmbossMaskFilter::Light light;
389 light.fDirection[0] = SK_Scalar1/2;
390 light.fDirection[1] = SK_Scalar1/2;
391 light.fDirection[2] = SK_Scalar1/3;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000392 light.fAmbient = 0x48;
393 light.fSpecular = 0x80;
robertphillips@google.comb7061172013-09-06 14:16:12 +0000394 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5);
commit-bot@chromium.org7c9d0f32014-02-21 10:13:32 +0000395 SkEmbossMaskFilter* embossFilter = SkEmbossMaskFilter::Create(sigma, light);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000396
reed@android.com048522d2009-06-23 12:19:41 +0000397 SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000398 SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
399 0xff89bc45, 0xff112233);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000400
reed@android.com8a1c16f2008-12-17 15:59:43 +0000401 canvas->save();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000402 canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
reed@google.com9cfc83c2013-07-22 17:18:18 +0000403 paint.setAntiAlias(true);
404 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000405 // !!! draw through a clip
406 paint.setColor(SK_ColorLTGRAY);
407 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000408 SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
409 canvas->clipRect(clip);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000410 paint.setShader(SkShader::CreateBitmapShader(fTx,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000411 SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000412 canvas->drawPaint(paint);
413 canvas->save();
414
reed@android.com8a1c16f2008-12-17 15:59:43 +0000415 // line (exercises xfermode, colorShader, colorFilter, filterShader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000416 paint.setColor(SK_ColorGREEN);
417 paint.setStrokeWidth(SkIntToScalar(10));
418 paint.setStyle(SkPaint::kStroke_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000419 paint.setXfermode(xfermode)->unref();
420 paint.setColorFilter(lightingFilter)->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000421 canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
422 paint.setXfermode(NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000423 paint.setColorFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000424
reed@android.com8a1c16f2008-12-17 15:59:43 +0000425 // rectangle
rmistry@google.comae933ce2012-08-23 18:19:56 +0000426 paint.setStyle(SkPaint::kFill_Style);
427 canvas->translate(SkIntToScalar(50), 0);
428 paint.setColor(SK_ColorYELLOW);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000429 paint.setShader(linear)->unref();
430 paint.setPathEffect(pathEffectTest())->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000431 canvas->drawRect(rect, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000432 paint.setPathEffect(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000433
reed@android.com8a1c16f2008-12-17 15:59:43 +0000434 // circle w/ emboss & transparent (exercises 3dshader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000435 canvas->translate(SkIntToScalar(50), 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000436 paint.setMaskFilter(embossFilter)->unref();
437 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000438 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000439 paint.setShader(transparentShader)->unref();
440 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000441 canvas->translate(0, SkIntToScalar(-10));
442
reed@android.com8a1c16f2008-12-17 15:59:43 +0000443 // path
rmistry@google.comae933ce2012-08-23 18:19:56 +0000444 canvas->translate(SkIntToScalar(50), 0);
445 paint.setColor(SK_ColorRED);
446 paint.setStyle(SkPaint::kStroke_Style);
447 paint.setStrokeWidth(SkIntToScalar(5));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000448 paint.setShader(radial)->unref();
449 paint.setMaskFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000450 canvas->drawPath(path, paint);
451
reed@android.com8a1c16f2008-12-17 15:59:43 +0000452 paint.setShader(NULL);
453 // bitmap, sprite
rmistry@google.comae933ce2012-08-23 18:19:56 +0000454 canvas->translate(SkIntToScalar(50), 0);
455 paint.setStyle(SkPaint::kFill_Style);
456 canvas->drawBitmap(fBug, left, top, &paint);
457 canvas->translate(SkIntToScalar(30), 0);
458 canvas->drawSprite(fTb,
reed@google.come1ca7052013-12-17 19:22:07 +0000459 SkScalarRoundToInt(canvas->getTotalMatrix().getTranslateX()),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000460 spriteOffset + 10, &paint);
461
rmistry@google.comae933ce2012-08-23 18:19:56 +0000462 canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000463 paint.setShader(shaderTest())->unref(); // test compose shader
rmistry@google.comae933ce2012-08-23 18:19:56 +0000464 canvas->drawRect(rect2, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000465 paint.setShader(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000466
reed@android.com8a1c16f2008-12-17 15:59:43 +0000467 canvas->restore();
468 // text
reed@android.com8a1c16f2008-12-17 15:59:43 +0000469 canvas->translate(0, SkIntToScalar(60));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000470 canvas->save();
471 paint.setColor(SK_ColorGRAY);
472 canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
473 canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
474
475 canvas->translate(SkIntToScalar(50), 0);
476 paint.setColor(SK_ColorCYAN);
477 canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
478
479 canvas->translate(SkIntToScalar(30), 0);
480 paint.setColor(SK_ColorMAGENTA);
481 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
482 matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
483 canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
484 canvas->translate(0, SkIntToScalar(20));
485 canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
486 canvas->restore();
487
488 canvas->translate(0, SkIntToScalar(60));
489 paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000490 canvas->restore();
491 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000492
reed@android.com8a1c16f2008-12-17 15:59:43 +0000493 /*
494./SkColorFilter.h:25:class SkColorFilter : public SkFlattenable { -- abstract
495 static SkColorFilter* CreatXfermodeFilter() *** untested ***
496 static SkColorFilter* CreatePorterDuffFilter() *** untested ***
497 static SkColorFilter* CreateLightingFilter() -- tested
498./SkDrawLooper.h:9:class SkDrawLooper : public SkFlattenable { -- virtually abstract
499 ./SkBlurDrawLooper.h:9:class SkBlurDrawLooper : public SkDrawLooper { *** untested ***
500./SkMaskFilter.h:41:class SkMaskFilter : public SkFlattenable { -- abstract chmod +w .h
501 ./SkEmbossMaskFilter.h:27:class SkEmbossMaskFilter : public SkMaskFilter { -- tested
502./SkPathEffect.h:33:class SkPathEffect : public SkFlattenable { -- abstract
503 ./Sk1DPathEffect.h:27:class Sk1DPathEffect : public SkPathEffect { -- abstract
504 ./Sk1DPathEffect.h:48:class SkPath1DPathEffect : public Sk1DPathEffect { -- tested
505 ./Sk2DPathEffect.h:25:class Sk2DPathEffect : public SkPathEffect { *** untested ***
506 ./SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect { *** untested ***
507 ./SkDashPathEffect.h:27:class SkDashPathEffect : public SkPathEffect {
508 ./SkDiscretePathEffect.h:27:class SkDiscretePathEffect : public SkPathEffect {
509 ./SkPaint.h:760:class SkStrokePathEffect : public SkPathEffect {
510 ./SkPathEffect.h:58:class SkPairPathEffect : public SkPathEffect {
511 ./SkPathEffect.h:78:class SkComposePathEffect : public SkPairPathEffect {
512 ./SkPathEffect.h:114:class SkSumPathEffect : public SkPairPathEffect {
513./SkRasterizer.h:29:class SkRasterizer : public SkFlattenable {
514 ./SkLayerRasterizer.h:27:class SkLayerRasterizer : public SkRasterizer {
515./SkShader.h:36:class SkShader : public SkFlattenable {
516 ./SkColorFilter.h:59:class SkFilterShader : public SkShader {
517 ./SkColorShader.h:26:class SkColorShader : public SkShader {
518 ./SkShaderExtras.h:31:class SkComposeShader : public SkShader {
519 ./SkTransparentShader.h:23:class SkTransparentShader : public SkShader {
520./SkUnitMapper.h:24:class SkUnitMapper : public SkFlattenable {
521 ./SkUnitMapper.h:33:class SkDiscreteMapper : public SkUnitMapper {
522 ./SkUnitMapper.h:51:class SkFlipCosineMapper : public SkUnitMapper {
523./SkXfermode.h:32:class SkXfermode : public SkFlattenable {
524 ./SkAvoidXfermode.h:28:class SkAvoidXfermode : public SkXfermode { *** not done *** chmod +w .h .cpp
525 ./SkXfermode.h:54:class SkProcXfermode : public SkXfermode {
526 */
rmistry@google.comae933ce2012-08-23 18:19:56 +0000527
reed@android.com8a1c16f2008-12-17 15:59:43 +0000528 /*
529./SkBlurMaskFilter.h:25:class SkBlurMaskFilter {
530 chmod +w SkBlurMaskFilter.cpp
531./SkGradientShader.h:30:class SkGradientShader {
532 */
533 // save layer, bounder, looper
534 // matrix
535 // clip /path/region
536 // bitmap proc shader ?
537
538/* untested:
539SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect {
540*/
rmistry@google.comae933ce2012-08-23 18:19:56 +0000541
reed@google.com4d5c26d2013-01-08 16:17:50 +0000542 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000543 fClickPt.set(x, y);
544 this->inval(NULL);
reed@google.com4d5c26d2013-01-08 16:17:50 +0000545 return this->INHERITED::onFindClickHandler(x, y, modi);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000546 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000547
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000548 SkPathEffect* pathEffectTest() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000549 static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
550 SkScalar gPhase = 0;
551 SkPath path;
552 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
553 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
554 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
555 path.close();
556 path.offset(SkIntToScalar(-6), 0);
commit-bot@chromium.org0a2bf902014-02-20 20:40:19 +0000557 SkPathEffect* outer = SkPath1DPathEffect::Create(path, SkIntToScalar(12),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000558 gPhase, SkPath1DPathEffect::kRotate_Style);
commit-bot@chromium.org0a2bf902014-02-20 20:40:19 +0000559 SkPathEffect* inner = SkDiscretePathEffect::Create(SkIntToScalar(2),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000560 SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
commit-bot@chromium.org0a2bf902014-02-20 20:40:19 +0000561 SkPathEffect* result = SkComposePathEffect::Create(outer, inner);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000562 outer->unref();
563 inner->unref();
564 return result;
565 }
reed@google.com963a8fa2012-05-10 13:04:59 +0000566
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000567 SkShader* shaderTest() {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000568 SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000569 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000570 SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000571 2, SkShader::kClamp_TileMode);
572 pts[1].set(0, SkIntToScalar(100));
573 SkColor colors2[] = {SK_ColorBLACK, SkColorSetARGB(0x80, 0, 0, 0)};
rmistry@google.comae933ce2012-08-23 18:19:56 +0000574 SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000575 2, SkShader::kClamp_TileMode);
reed@android.com048522d2009-06-23 12:19:41 +0000576 SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000577 SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
578 shaderA->unref();
579 shaderB->unref();
580 mode->unref();
581 return result;
582 }
583
584 virtual void startTest() {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000585 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
586 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
587 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
588 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000589
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000590 void drawRaster(SkCanvas* canvas) {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000591 for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000592 drawOneRaster(canvas);
593 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000594
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000595 void drawOneRaster(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000596 canvas->save();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000597
598 SkScalar x = SkIntToScalar(20);
599 SkScalar y = SkIntToScalar(40);
600 SkPaint paint;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000601
reed@android.com8a1c16f2008-12-17 15:59:43 +0000602 paint.setAntiAlias(true);
603 paint.setTextSize(SkIntToScalar(48));
reed@android.comaa5a7db2009-05-27 01:20:10 +0000604 paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
605 SkTypeface::kBold));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000606
607 SkString str("GOOGLE");
608
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000609 for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
reed@google.com7fa2a652014-01-27 13:42:58 +0000610 apply_shader(&paint, (int)i);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000611
reed@android.com8a1c16f2008-12-17 15:59:43 +0000612 // paint.setMaskFilter(NULL);
613 // paint.setColor(SK_ColorBLACK);
614
615#if 01
616 int index = i % SK_ARRAY_COUNT(gLightingColors);
617 paint.setColorFilter(SkColorFilter::CreateLightingFilter(
618 gLightingColors[index].fMul,
619 gLightingColors[index].fAdd))->unref();
620#endif
rmistry@google.comae933ce2012-08-23 18:19:56 +0000621
reed@android.com8a1c16f2008-12-17 15:59:43 +0000622 canvas->drawText(str.c_str(), str.size(), x, y, paint);
623 SkRect oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
624 paint.setStyle(SkPaint::kStroke_Style);
625 canvas->drawOval(oval, paint);
626 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000627
628 y += paint.getFontSpacing();
629 }
630
631 canvas->restore();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000632
reed@android.com6b82d1a2009-06-03 02:35:01 +0000633 if (1) {
commit-bot@chromium.org0a2bf902014-02-20 20:40:19 +0000634 SkAutoTUnref<SkAvoidXfermode> mode(SkAvoidXfermode::Create(SK_ColorWHITE, 0xFF,
635 SkAvoidXfermode::kTargetColor_Mode));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000636 SkPaint paint;
637 x += SkIntToScalar(20);
638 SkRect r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) };
commit-bot@chromium.org0a2bf902014-02-20 20:40:19 +0000639 paint.setXfermode(mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000640 paint.setColor(SK_ColorGREEN);
641 paint.setAntiAlias(true);
642 canvas->drawOval(r, paint);
643 }
644 }
645
646private:
647 SkPoint fClickPt;
648 SkBitmap fBug, fTb, fTx;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000649 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000650};
651
652//////////////////////////////////////////////////////////////////////////////
653
654static SkView* MyFactory() { return new DemoView; }
655static SkViewRegister reg(MyFactory);