blob: ccecb9e1ed77ecdead68c2e8d75504473223f259 [file] [log] [blame]
mike@reedtribe.org50e4c722012-10-22 03:59:34 +00001/*
2 * Copyright 2012 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 "SkPath.h"
12#include "SkRegion.h"
13#include "SkShader.h"
14#include "SkUtils.h"
15#include "SkImage.h"
16#include "SkSurface.h"
17
reed@google.comc83e3522012-10-22 22:00:08 +000018#define FAT_PIXEL_COLOR SK_ColorBLACK
19#define PIXEL_CENTER_SIZE 3
20#define WIRE_FRAME_COLOR 0xFFFF0000 /*0xFF00FFFF*/
21#define WIRE_FRAME_SIZE 1.5f
22
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000023static void erase(SkSurface* surface) {
24 surface->getCanvas()->clear(0);
25}
26
27static SkShader* createChecker() {
reed@google.com9c0bef12012-11-02 19:59:18 +000028// SkColor colors[] = { 0xFFFDFDFD, 0xFFF4F4F4 };
29 SkColor colors[] = { 0xFFFFFFFF, 0xFFFFFFFF };
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000030 SkBitmap bm;
31 bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
32 bm.allocPixels();
33 bm.lockPixels();
reed@google.com9c0bef12012-11-02 19:59:18 +000034 *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = SkPreMultiplyColor(colors[0]);
35 *bm.getAddr32(0, 1) = *bm.getAddr32(1, 0) = SkPreMultiplyColor(colors[1]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000036 SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
37 SkShader::kRepeat_TileMode);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000038
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000039 SkMatrix m;
40 m.setScale(12, 12);
41 s->setLocalMatrix(m);
42 return s;
43}
44
45class FatBits {
46public:
47 FatBits() : fShader(createChecker()) {
48 fAA = false;
49 fStyle = kHair_Style;
50 fGrid = true;
reed@google.comc83e3522012-10-22 22:00:08 +000051 fShowSkeleton = true;
52 fUseGPU = false;
reed@google.com9c0bef12012-11-02 19:59:18 +000053 fUseClip = false;
54
55 fClipRect.set(2, 2, 11, 8 );
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000056 }
57
reed@google.comc83e3522012-10-22 22:00:08 +000058 int getZoom() const { return fZ; }
59
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000060 bool getAA() const { return fAA; }
61 void setAA(bool aa) { fAA = aa; }
62
63 bool getGrid() const { return fGrid; }
64 void setGrid(bool g) { fGrid = g; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000065
reed@google.comc83e3522012-10-22 22:00:08 +000066 bool getShowSkeleton() const { return fShowSkeleton; }
67 void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000068
reed@google.comc83e3522012-10-22 22:00:08 +000069 bool getUseGPU() const { return fUseGPU; }
70 void setUseGPU(bool ug) { fUseGPU = ug; }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000071
reed@google.com9c0bef12012-11-02 19:59:18 +000072 bool getUseClip() const { return fUseClip; }
73 void setUseClip(bool uc) { fUseClip = uc; }
74
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000075 enum Style {
76 kHair_Style,
reed@google.comc83e3522012-10-22 22:00:08 +000077 kStroke_Style,
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000078 };
79 Style getStyle() const { return fStyle; }
80 void setStyle(Style s) { fStyle = s; }
81
82 void setWHZ(int width, int height, int zoom) {
83 fW = width;
84 fH = height;
85 fZ = zoom;
86 fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom));
87 fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
88 fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
89 fShader->setLocalMatrix(fMatrix);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000090
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000091 SkImage::Info info = {
92 width, height, SkImage::kPMColor_ColorType, SkImage::kPremul_AlphaType
93 };
94 fMinSurface.reset(SkSurface::NewRaster(info, NULL));
95 info.fWidth *= zoom;
96 info.fHeight *= zoom;
97 fMaxSurface.reset(SkSurface::NewRaster(info, NULL));
98 }
99
100 void drawBG(SkCanvas*);
101 void drawFG(SkCanvas*);
102 void drawLine(SkCanvas*, SkPoint pts[2]);
103 void drawRect(SkCanvas* canvas, SkPoint pts[2]);
104
105private:
reed@google.com9c0bef12012-11-02 19:59:18 +0000106 bool fAA, fGrid, fShowSkeleton, fUseGPU, fUseClip;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000107 Style fStyle;
108 int fW, fH, fZ;
109 SkMatrix fMatrix, fInverse;
reed@google.com9c0bef12012-11-02 19:59:18 +0000110 SkRect fBounds, fClipRect;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000111 SkAutoTUnref<SkShader> fShader;
112 SkAutoTUnref<SkSurface> fMinSurface;
113 SkAutoTUnref<SkSurface> fMaxSurface;
114
115 void setupPaint(SkPaint* paint) {
116 bool aa = this->getAA();
117 switch (fStyle) {
118 case kHair_Style:
119 paint->setStrokeWidth(0);
120 break;
121 case kStroke_Style:
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000122 paint->setStrokeWidth(SK_Scalar1);
123// paint->setStrokeWidth(SK_Scalar1 + SK_Scalar1/500);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000124 break;
125 }
126 paint->setAntiAlias(aa);
127 }
128
reed@google.comc83e3522012-10-22 22:00:08 +0000129 void setupSkeletonPaint(SkPaint* paint) {
130 paint->setStyle(SkPaint::kStroke_Style);
131 paint->setStrokeWidth(WIRE_FRAME_SIZE);
132 paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0);
133 paint->setAntiAlias(true);
134 }
135
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000136 void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
137 void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
138 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000139 this->setupSkeletonPaint(&paint);
140 SkPath path;
141
142 if (fUseGPU && fAA) {
143 SkRect rr = r;
144 rr.inset(fZ/2, fZ/2);
145 path.addRect(rr);
146 path.moveTo(rr.fLeft, rr.fTop);
147 path.lineTo(rr.fRight, rr.fBottom);
148 rr = r;
149 rr.inset(-fZ/2, -fZ/2);
150 path.addRect(rr);
151 } else {
152 path.addRect(r);
153 if (fUseGPU) {
154 path.moveTo(r.fLeft, r.fTop);
155 path.lineTo(r.fRight, r.fBottom);
156 }
157 }
158 max->drawPath(path, paint);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000159 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000160
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000161 void copyMinToMax() {
162 erase(fMaxSurface);
163 SkCanvas* canvas = fMaxSurface->getCanvas();
164 canvas->save();
165 canvas->concat(fMatrix);
166 fMinSurface->draw(canvas, 0, 0, NULL);
167 canvas->restore();
168
169 SkPaint paint;
170 paint.setXfermodeMode(SkXfermode::kClear_Mode);
171 for (int iy = 1; iy < fH; ++iy) {
172 SkScalar y = SkIntToScalar(iy * fZ);
173 canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
174 }
175 for (int ix = 1; ix < fW; ++ix) {
176 SkScalar x = SkIntToScalar(ix * fZ);
177 canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
178 }
179 }
180};
181
182void FatBits::drawBG(SkCanvas* canvas) {
183 SkPaint paint;
184
185 paint.setShader(fShader);
186 canvas->drawRect(fBounds, paint);
187 paint.setShader(NULL);
188}
189
190void FatBits::drawFG(SkCanvas* canvas) {
reed@google.comc83e3522012-10-22 22:00:08 +0000191 SkPaint inner, outer;
192
193 inner.setAntiAlias(true);
194 inner.setColor(SK_ColorBLACK);
195 inner.setStrokeWidth(PIXEL_CENTER_SIZE);
196
197 outer.setAntiAlias(true);
198 outer.setColor(SK_ColorWHITE);
199 outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000200
201 SkScalar half = SkIntToScalar(fZ) / 2;
202 for (int iy = 0; iy < fH; ++iy) {
203 SkScalar y = SkIntToScalar(iy * fZ) + half;
204 for (int ix = 0; ix < fW; ++ix) {
205 SkScalar x = SkIntToScalar(ix * fZ) + half;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000206
reed@google.comc83e3522012-10-22 22:00:08 +0000207 canvas->drawPoint(x, y, outer);
208 canvas->drawPoint(x, y, inner);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000209 }
210 }
reed@google.com9c0bef12012-11-02 19:59:18 +0000211
212 if (fUseClip) {
213 SkPaint p;
214 p.setStyle(SkPaint::kStroke_Style);
215 p.setColor(SK_ColorLTGRAY);
216 SkRect r = {
217 fClipRect.fLeft * fZ,
218 fClipRect.fTop * fZ,
219 fClipRect.fRight * fZ,
220 fClipRect.fBottom * fZ
221 };
222 canvas->drawRect(r, p);
223 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000224}
225
226void FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
227 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000228 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000229
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000230 SkPath path;
231 path.moveTo(pts[0]);
232 path.lineTo(pts[1]);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000233
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000234 switch (fStyle) {
235 case kHair_Style:
reed@google.comc83e3522012-10-22 22:00:08 +0000236 if (fUseGPU) {
237 SkPaint p;
238 p.setStyle(SkPaint::kStroke_Style);
239 p.setStrokeWidth(SK_Scalar1 * fZ);
240 SkPath dst;
241 p.getFillPath(path, &dst);
242 path.addPath(dst);
243 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000244 break;
245 case kStroke_Style: {
246 SkPaint p;
247 p.setStyle(SkPaint::kStroke_Style);
248 p.setStrokeWidth(SK_Scalar1 * fZ);
249 SkPath dst;
250 p.getFillPath(path, &dst);
251 path = dst;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000252
reed@google.comc83e3522012-10-22 22:00:08 +0000253 if (fUseGPU) {
254 path.moveTo(dst.getPoint(0));
255 path.lineTo(dst.getPoint(2));
256 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000257 } break;
258 }
259 max->drawPath(path, paint);
260}
261
262void FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) {
263 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000264
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000265 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000266
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000267 if (fGrid) {
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000268 SkScalar dd = 0;//SK_Scalar1 / 50;
269 pts[0].set(SkScalarRoundToScalar(pts[0].fX) + dd,
270 SkScalarRoundToScalar(pts[0].fY) + dd);
271 pts[1].set(SkScalarRoundToScalar(pts[1].fX) + dd,
272 SkScalarRoundToScalar(pts[1].fY) + dd);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000273 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000274
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000275 erase(fMinSurface);
276 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000277 paint.setColor(FAT_PIXEL_COLOR);
reed@google.com9c0bef12012-11-02 19:59:18 +0000278 if (fUseClip) {
279 fMinSurface->getCanvas()->save();
280 SkRect r = fClipRect;
281 r.inset(SK_Scalar1/3, SK_Scalar1/3);
282 fMinSurface->getCanvas()->clipRect(r, SkRegion::kIntersect_Op, true);
283 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000284 fMinSurface->getCanvas()->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
reed@google.com9c0bef12012-11-02 19:59:18 +0000285 if (fUseClip) {
286 fMinSurface->getCanvas()->restore();
287 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000288 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000289
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000290 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000291
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000292 fMatrix.mapPoints(pts, 2);
293 this->drawLineSkeleton(max, pts);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000294
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000295 fMaxSurface->draw(canvas, 0, 0, NULL);
296}
297
298void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
299 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000300
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000301 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000302
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000303 if (fGrid) {
304 pts[0].set(SkScalarRoundToScalar(pts[0].fX), SkScalarRoundToScalar(pts[0].fY));
305 pts[1].set(SkScalarRoundToScalar(pts[1].fX), SkScalarRoundToScalar(pts[1].fY));
306 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000307
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000308 SkRect r;
309 r.set(pts, 2);
310
311 erase(fMinSurface);
312 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000313 paint.setColor(FAT_PIXEL_COLOR);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000314 fMinSurface->getCanvas()->drawRect(r, paint);
315 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000316
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000317 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000318
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000319 fMatrix.mapPoints(pts, 2);
320 r.set(pts, 2);
321 this->drawRectSkeleton(max, r);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000322
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000323 fMaxSurface->draw(canvas, 0, 0, NULL);
324}
325
326///////////////////////////////////////////////////////////////////////////////////////////////////
327
328class IndexClick : public SkView::Click {
329 int fIndex;
330public:
331 IndexClick(SkView* v, int index) : SkView::Click(v), fIndex(index) {}
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000332
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000333 static int GetIndex(SkView::Click* click) {
334 return ((IndexClick*)click)->fIndex;
335 }
336};
337
338class DrawLineView : public SampleView {
339 FatBits fFB;
340 SkPoint fPts[2];
341 bool fIsRect;
342public:
343 DrawLineView() {
344 fFB.setWHZ(24, 16, 48);
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000345 fPts[0].set(48, 48);
346 fPts[1].set(48 * 5, 48 * 4);
347 fIsRect = false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000348 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000349
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000350 void setStyle(FatBits::Style s) {
351 fFB.setStyle(s);
352 this->inval(NULL);
353 }
354
355protected:
356 virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
357 if (SampleCode::TitleQ(*evt)) {
358 SampleCode::TitleR(evt, "FatBits");
359 return true;
360 }
361 SkUnichar uni;
362 if (SampleCode::CharQ(*evt, &uni)) {
363 switch (uni) {
reed@google.com9c0bef12012-11-02 19:59:18 +0000364 case 'c':
365 fFB.setUseClip(!fFB.getUseClip());
366 this->inval(NULL);
367 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000368 case 'r':
369 fIsRect = !fIsRect;
370 this->inval(NULL);
371 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000372 case 'x':
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000373 fFB.setGrid(!fFB.getGrid());
374 this->inval(NULL);
375 return true;
376 case 's':
377 if (FatBits::kStroke_Style == fFB.getStyle()) {
378 this->setStyle(FatBits::kHair_Style);
379 } else {
380 this->setStyle(FatBits::kStroke_Style);
381 }
382 return true;
383 case 'a':
384 fFB.setAA(!fFB.getAA());
385 this->inval(NULL);
386 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000387 case 'w':
388 fFB.setShowSkeleton(!fFB.getShowSkeleton());
389 this->inval(NULL);
390 return true;
391 case 'g':
392 fFB.setUseGPU(!fFB.getUseGPU());
393 this->inval(NULL);
394 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000395 }
396 }
397 return this->INHERITED::onQuery(evt);
398 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000399
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000400 virtual void onDrawContent(SkCanvas* canvas) {
401 fFB.drawBG(canvas);
402 if (fIsRect) {
403 fFB.drawRect(canvas, fPts);
404 } else {
405 fFB.drawLine(canvas, fPts);
406 }
407 fFB.drawFG(canvas);
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000408
reed@google.comffe9d012012-10-23 15:33:41 +0000409 {
410 SkString str;
reed@google.com9c0bef12012-11-02 19:59:18 +0000411 str.printf("%s %s %s %s",
reed@google.comffe9d012012-10-23 15:33:41 +0000412 fFB.getAA() ? "AA" : "BW",
413 FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
reed@google.com9c0bef12012-11-02 19:59:18 +0000414 fFB.getUseGPU() ? "GPU" : "CPU",
415 fFB.getUseClip() ? "clip" : "noclip");
reed@google.comffe9d012012-10-23 15:33:41 +0000416 SkPaint paint;
417 paint.setAntiAlias(true);
418 paint.setTextSize(16);
419 paint.setColor(SK_ColorBLUE);
420 canvas->drawText(str.c_str(), str.size(), 10, 16, paint);
421 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000422 }
423
424 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
425 SkPoint pt = { x, y };
426 int index = -1;
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000427 SkScalar tol = 12;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000428 if (fPts[0].equalsWithinTolerance(pt, tol)) {
429 index = 0;
430 } else if (fPts[1].equalsWithinTolerance(pt, tol)) {
431 index = 1;
432 }
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000433 return new IndexClick(this, index);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000434 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000435
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000436 virtual bool onClick(Click* click) {
437 int index = IndexClick::GetIndex(click);
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000438 if (index >= 0 && index <= 1) {
439 fPts[index] = click->fCurr;
440 } else {
441 SkScalar dx = click->fCurr.fX - click->fPrev.fX;
442 SkScalar dy = click->fCurr.fY - click->fPrev.fY;
443 fPts[0].offset(dx, dy);
444 fPts[1].offset(dx, dy);
445 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000446 this->inval(NULL);
447 return true;
448 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000449
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000450private:
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000451
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000452 typedef SampleView INHERITED;
453};
454
455//////////////////////////////////////////////////////////////////////////////
456
457static SkView* MyFactory() { return new DrawLineView; }
458static SkViewRegister reg(MyFactory);
459