blob: c6fc67f3cc263ade06d8d9b42f55c0cf66832e93 [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
reed@google.combbe66f02013-10-30 13:41:19 +000023static SkScalar apply_grid(SkScalar x) {
24 const SkScalar grid = 2;
25 return SkScalarRoundToScalar(x * grid) / grid;
26}
27
28static void apply_grid(SkPoint pts[], int count) {
29 for (int i = 0; i < count; ++i) {
30 pts[i].set(apply_grid(pts[i].fX), apply_grid(pts[i].fY));
31 }
32}
33
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000034static void erase(SkSurface* surface) {
junov@google.comdbfac8a2012-12-06 21:47:40 +000035 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000036}
37
38static SkShader* createChecker() {
reed@google.com9c0bef12012-11-02 19:59:18 +000039// SkColor colors[] = { 0xFFFDFDFD, 0xFFF4F4F4 };
40 SkColor colors[] = { 0xFFFFFFFF, 0xFFFFFFFF };
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000041 SkBitmap bm;
42 bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
43 bm.allocPixels();
44 bm.lockPixels();
reed@google.com9c0bef12012-11-02 19:59:18 +000045 *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = SkPreMultiplyColor(colors[0]);
46 *bm.getAddr32(0, 1) = *bm.getAddr32(1, 0) = SkPreMultiplyColor(colors[1]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000047 SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
48 SkShader::kRepeat_TileMode);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000049
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000050 SkMatrix m;
51 m.setScale(12, 12);
52 s->setLocalMatrix(m);
53 return s;
54}
55
56class FatBits {
57public:
58 FatBits() : fShader(createChecker()) {
59 fAA = false;
60 fStyle = kHair_Style;
61 fGrid = true;
reed@google.comc83e3522012-10-22 22:00:08 +000062 fShowSkeleton = true;
63 fUseGPU = false;
reed@google.com9c0bef12012-11-02 19:59:18 +000064 fUseClip = false;
mike@reedtribe.org64494e92013-03-06 02:18:33 +000065 fRectAsOval = false;
reed@google.combbe66f02013-10-30 13:41:19 +000066 fUseTriangle = false;
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +000067
reed@google.com9c0bef12012-11-02 19:59:18 +000068 fClipRect.set(2, 2, 11, 8 );
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000069 }
70
robertphillips@google.comca47aae2012-12-12 15:58:25 +000071 int getZoom() const { return fZoom; }
reed@google.comc83e3522012-10-22 22:00:08 +000072
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000073 bool getAA() const { return fAA; }
74 void setAA(bool aa) { fAA = aa; }
75
76 bool getGrid() const { return fGrid; }
77 void setGrid(bool g) { fGrid = g; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000078
reed@google.comc83e3522012-10-22 22:00:08 +000079 bool getShowSkeleton() const { return fShowSkeleton; }
80 void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000081
reed@google.comc83e3522012-10-22 22:00:08 +000082 bool getUseGPU() const { return fUseGPU; }
83 void setUseGPU(bool ug) { fUseGPU = ug; }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +000084
reed@google.combbe66f02013-10-30 13:41:19 +000085 bool getTriangle() const { return fUseTriangle; }
86 void setTriangle(bool ut) { fUseTriangle = ut; }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +000087
mike@reedtribe.org64494e92013-03-06 02:18:33 +000088 void toggleRectAsOval() { fRectAsOval = !fRectAsOval; }
89
reed@google.com9c0bef12012-11-02 19:59:18 +000090 bool getUseClip() const { return fUseClip; }
91 void setUseClip(bool uc) { fUseClip = uc; }
92
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000093 enum Style {
94 kHair_Style,
reed@google.comc83e3522012-10-22 22:00:08 +000095 kStroke_Style,
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000096 };
97 Style getStyle() const { return fStyle; }
98 void setStyle(Style s) { fStyle = s; }
99
100 void setWHZ(int width, int height, int zoom) {
101 fW = width;
102 fH = height;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000103 fZoom = zoom;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000104 fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom));
105 fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
106 fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
107 fShader->setLocalMatrix(fMatrix);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000108
reed@google.com2bd8b812013-11-01 13:46:54 +0000109 SkImageInfo info = {
110 width, height, kPMColor_SkColorType, kPremul_SkAlphaType
reed@google.combbe66f02013-10-30 13:41:19 +0000111 };
112 fMinSurface.reset(SkSurface::NewRaster(info));
113 info.fWidth *= zoom;
114 info.fHeight *= zoom;
115 fMaxSurface.reset(SkSurface::NewRaster(info));
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000116 }
117
118 void drawBG(SkCanvas*);
119 void drawFG(SkCanvas*);
120 void drawLine(SkCanvas*, SkPoint pts[2]);
121 void drawRect(SkCanvas* canvas, SkPoint pts[2]);
reed@google.combbe66f02013-10-30 13:41:19 +0000122 void drawTriangle(SkCanvas* canvas, SkPoint pts[3]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000123
124private:
reed@google.combbe66f02013-10-30 13:41:19 +0000125 bool fAA, fGrid, fShowSkeleton, fUseGPU, fUseClip, fRectAsOval, fUseTriangle;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000126 Style fStyle;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000127 int fW, fH, fZoom;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000128 SkMatrix fMatrix, fInverse;
reed@google.com9c0bef12012-11-02 19:59:18 +0000129 SkRect fBounds, fClipRect;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000130 SkAutoTUnref<SkShader> fShader;
131 SkAutoTUnref<SkSurface> fMinSurface;
132 SkAutoTUnref<SkSurface> fMaxSurface;
133
134 void setupPaint(SkPaint* paint) {
135 bool aa = this->getAA();
136 switch (fStyle) {
137 case kHair_Style:
138 paint->setStrokeWidth(0);
139 break;
140 case kStroke_Style:
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000141 paint->setStrokeWidth(SK_Scalar1);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000142 break;
143 }
144 paint->setAntiAlias(aa);
145 }
146
reed@google.comc83e3522012-10-22 22:00:08 +0000147 void setupSkeletonPaint(SkPaint* paint) {
148 paint->setStyle(SkPaint::kStroke_Style);
149 paint->setStrokeWidth(WIRE_FRAME_SIZE);
150 paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0);
151 paint->setAntiAlias(true);
152 }
153
reed@google.combbe66f02013-10-30 13:41:19 +0000154 void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000155 void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
156 void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
157 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000158 this->setupSkeletonPaint(&paint);
159 SkPath path;
160
161 if (fUseGPU && fAA) {
162 SkRect rr = r;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000163 rr.inset(SkIntToScalar(fZoom)/2, SkIntToScalar(fZoom)/2);
reed@google.comc83e3522012-10-22 22:00:08 +0000164 path.addRect(rr);
165 path.moveTo(rr.fLeft, rr.fTop);
166 path.lineTo(rr.fRight, rr.fBottom);
167 rr = r;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000168 rr.inset(-SkIntToScalar(fZoom)/2, -SkIntToScalar(fZoom)/2);
reed@google.comc83e3522012-10-22 22:00:08 +0000169 path.addRect(rr);
170 } else {
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000171 fRectAsOval ? path.addOval(r) : path.addRect(r);
reed@google.comc83e3522012-10-22 22:00:08 +0000172 if (fUseGPU) {
173 path.moveTo(r.fLeft, r.fTop);
174 path.lineTo(r.fRight, r.fBottom);
175 }
176 }
177 max->drawPath(path, paint);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000178 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000179
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000180 void copyMinToMax() {
181 erase(fMaxSurface);
182 SkCanvas* canvas = fMaxSurface->getCanvas();
183 canvas->save();
184 canvas->concat(fMatrix);
185 fMinSurface->draw(canvas, 0, 0, NULL);
186 canvas->restore();
187
188 SkPaint paint;
189 paint.setXfermodeMode(SkXfermode::kClear_Mode);
190 for (int iy = 1; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000191 SkScalar y = SkIntToScalar(iy * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000192 canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
193 }
194 for (int ix = 1; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000195 SkScalar x = SkIntToScalar(ix * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000196 canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
197 }
198 }
199};
200
201void FatBits::drawBG(SkCanvas* canvas) {
202 SkPaint paint;
203
204 paint.setShader(fShader);
205 canvas->drawRect(fBounds, paint);
206 paint.setShader(NULL);
207}
208
209void FatBits::drawFG(SkCanvas* canvas) {
reed@google.comc83e3522012-10-22 22:00:08 +0000210 SkPaint inner, outer;
211
212 inner.setAntiAlias(true);
213 inner.setColor(SK_ColorBLACK);
214 inner.setStrokeWidth(PIXEL_CENTER_SIZE);
215
216 outer.setAntiAlias(true);
217 outer.setColor(SK_ColorWHITE);
218 outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000219
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000220 SkScalar half = SkIntToScalar(fZoom) / 2;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000221 for (int iy = 0; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000222 SkScalar y = SkIntToScalar(iy * fZoom) + half;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000223 for (int ix = 0; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000224 SkScalar x = SkIntToScalar(ix * fZoom) + half;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000225
reed@google.comc83e3522012-10-22 22:00:08 +0000226 canvas->drawPoint(x, y, outer);
227 canvas->drawPoint(x, y, inner);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000228 }
229 }
reed@google.com9c0bef12012-11-02 19:59:18 +0000230
231 if (fUseClip) {
232 SkPaint p;
233 p.setStyle(SkPaint::kStroke_Style);
234 p.setColor(SK_ColorLTGRAY);
235 SkRect r = {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000236 fClipRect.fLeft * fZoom,
237 fClipRect.fTop * fZoom,
238 fClipRect.fRight * fZoom,
239 fClipRect.fBottom * fZoom
reed@google.com9c0bef12012-11-02 19:59:18 +0000240 };
241 canvas->drawRect(r, p);
242 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000243}
244
245void FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
246 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000247 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000248
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000249 SkPath path;
250 path.moveTo(pts[0]);
251 path.lineTo(pts[1]);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000252
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000253 switch (fStyle) {
254 case kHair_Style:
reed@google.comc83e3522012-10-22 22:00:08 +0000255 if (fUseGPU) {
256 SkPaint p;
257 p.setStyle(SkPaint::kStroke_Style);
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000258 p.setStrokeWidth(SK_Scalar1 * fZoom);
reed@google.comc83e3522012-10-22 22:00:08 +0000259 SkPath dst;
260 p.getFillPath(path, &dst);
261 path.addPath(dst);
262 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000263 break;
264 case kStroke_Style: {
265 SkPaint p;
266 p.setStyle(SkPaint::kStroke_Style);
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000267 p.setStrokeWidth(SK_Scalar1 * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000268 SkPath dst;
269 p.getFillPath(path, &dst);
270 path = dst;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000271
reed@google.comc83e3522012-10-22 22:00:08 +0000272 if (fUseGPU) {
273 path.moveTo(dst.getPoint(0));
274 path.lineTo(dst.getPoint(2));
275 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000276 } break;
277 }
278 max->drawPath(path, paint);
279}
280
281void FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) {
282 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000283
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000284 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000285
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000286 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000287 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000288 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000289
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000290 erase(fMinSurface);
291 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000292 paint.setColor(FAT_PIXEL_COLOR);
reed@google.com9c0bef12012-11-02 19:59:18 +0000293 if (fUseClip) {
294 fMinSurface->getCanvas()->save();
295 SkRect r = fClipRect;
296 r.inset(SK_Scalar1/3, SK_Scalar1/3);
297 fMinSurface->getCanvas()->clipRect(r, SkRegion::kIntersect_Op, true);
298 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000299 fMinSurface->getCanvas()->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
reed@google.com9c0bef12012-11-02 19:59:18 +0000300 if (fUseClip) {
301 fMinSurface->getCanvas()->restore();
302 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000303 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000304
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000305 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000306
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000307 fMatrix.mapPoints(pts, 2);
308 this->drawLineSkeleton(max, pts);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000309
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000310 fMaxSurface->draw(canvas, 0, 0, NULL);
311}
312
313void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
314 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000315
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000316 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000317
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000318 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000319 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000320 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000321
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000322 SkRect r;
323 r.set(pts, 2);
324
325 erase(fMinSurface);
326 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000327 paint.setColor(FAT_PIXEL_COLOR);
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000328 {
329 SkCanvas* c = fMinSurface->getCanvas();
330 fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint);
331 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000332 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000333
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000334 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000335
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000336 fMatrix.mapPoints(pts, 2);
337 r.set(pts, 2);
338 this->drawRectSkeleton(max, r);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000339
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000340 fMaxSurface->draw(canvas, 0, 0, NULL);
341}
342
reed@google.combbe66f02013-10-30 13:41:19 +0000343void FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
344 SkPaint paint;
345 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000346
reed@google.combbe66f02013-10-30 13:41:19 +0000347 SkPath path;
348 path.moveTo(pts[0]);
349 path.lineTo(pts[1]);
350 path.lineTo(pts[2]);
351 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000352
reed@google.combbe66f02013-10-30 13:41:19 +0000353 max->drawPath(path, paint);
354}
355
356void FatBits::drawTriangle(SkCanvas* canvas, SkPoint pts[3]) {
357 SkPaint paint;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000358
reed@google.combbe66f02013-10-30 13:41:19 +0000359 fInverse.mapPoints(pts, 3);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000360
reed@google.combbe66f02013-10-30 13:41:19 +0000361 if (fGrid) {
362 apply_grid(pts, 3);
363 }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000364
reed@google.combbe66f02013-10-30 13:41:19 +0000365 SkPath path;
366 path.moveTo(pts[0]);
367 path.lineTo(pts[1]);
368 path.lineTo(pts[2]);
369 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000370
reed@google.combbe66f02013-10-30 13:41:19 +0000371 erase(fMinSurface);
372 this->setupPaint(&paint);
373 paint.setColor(FAT_PIXEL_COLOR);
374 fMinSurface->getCanvas()->drawPath(path, paint);
375 this->copyMinToMax();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000376
reed@google.combbe66f02013-10-30 13:41:19 +0000377 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000378
reed@google.combbe66f02013-10-30 13:41:19 +0000379 fMatrix.mapPoints(pts, 3);
380 this->drawTriangleSkeleton(max, pts);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000381
reed@google.combbe66f02013-10-30 13:41:19 +0000382 fMaxSurface->draw(canvas, 0, 0, NULL);
383}
384
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000385///////////////////////////////////////////////////////////////////////////////////////////////////
386
387class IndexClick : public SkView::Click {
388 int fIndex;
389public:
390 IndexClick(SkView* v, int index) : SkView::Click(v), fIndex(index) {}
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000391
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000392 static int GetIndex(SkView::Click* click) {
393 return ((IndexClick*)click)->fIndex;
394 }
395};
396
397class DrawLineView : public SampleView {
398 FatBits fFB;
reed@google.combbe66f02013-10-30 13:41:19 +0000399 SkPoint fPts[3];
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000400 bool fIsRect;
401public:
402 DrawLineView() {
403 fFB.setWHZ(24, 16, 48);
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000404 fPts[0].set(48, 48);
405 fPts[1].set(48 * 5, 48 * 4);
reed@google.combbe66f02013-10-30 13:41:19 +0000406 fPts[2].set(48 * 2, 48 * 6);
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000407 fIsRect = false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000408 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000409
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000410 void setStyle(FatBits::Style s) {
411 fFB.setStyle(s);
412 this->inval(NULL);
413 }
414
415protected:
416 virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
417 if (SampleCode::TitleQ(*evt)) {
418 SampleCode::TitleR(evt, "FatBits");
419 return true;
420 }
421 SkUnichar uni;
422 if (SampleCode::CharQ(*evt, &uni)) {
423 switch (uni) {
reed@google.com9c0bef12012-11-02 19:59:18 +0000424 case 'c':
425 fFB.setUseClip(!fFB.getUseClip());
426 this->inval(NULL);
427 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000428 case 'r':
429 fIsRect = !fIsRect;
430 this->inval(NULL);
431 return true;
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000432 case 'o':
433 fFB.toggleRectAsOval();
434 this->inval(NULL);
435 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000436 case 'x':
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000437 fFB.setGrid(!fFB.getGrid());
438 this->inval(NULL);
439 return true;
440 case 's':
441 if (FatBits::kStroke_Style == fFB.getStyle()) {
442 this->setStyle(FatBits::kHair_Style);
443 } else {
444 this->setStyle(FatBits::kStroke_Style);
445 }
446 return true;
447 case 'a':
448 fFB.setAA(!fFB.getAA());
449 this->inval(NULL);
450 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000451 case 'w':
452 fFB.setShowSkeleton(!fFB.getShowSkeleton());
453 this->inval(NULL);
454 return true;
455 case 'g':
456 fFB.setUseGPU(!fFB.getUseGPU());
457 this->inval(NULL);
458 return true;
reed@google.combbe66f02013-10-30 13:41:19 +0000459 case 't':
460 fFB.setTriangle(!fFB.getTriangle());
461 this->inval(NULL);
462 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000463 }
464 }
465 return this->INHERITED::onQuery(evt);
466 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000467
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000468 virtual void onDrawContent(SkCanvas* canvas) {
469 fFB.drawBG(canvas);
reed@google.combbe66f02013-10-30 13:41:19 +0000470 if (fFB.getTriangle()) {
471 fFB.drawTriangle(canvas, fPts);
472 }
473 else if (fIsRect) {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000474 fFB.drawRect(canvas, fPts);
475 } else {
476 fFB.drawLine(canvas, fPts);
477 }
478 fFB.drawFG(canvas);
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000479
reed@google.comffe9d012012-10-23 15:33:41 +0000480 {
481 SkString str;
reed@google.com9c0bef12012-11-02 19:59:18 +0000482 str.printf("%s %s %s %s",
reed@google.comffe9d012012-10-23 15:33:41 +0000483 fFB.getAA() ? "AA" : "BW",
484 FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
reed@google.com9c0bef12012-11-02 19:59:18 +0000485 fFB.getUseGPU() ? "GPU" : "CPU",
486 fFB.getUseClip() ? "clip" : "noclip");
reed@google.comffe9d012012-10-23 15:33:41 +0000487 SkPaint paint;
488 paint.setAntiAlias(true);
489 paint.setTextSize(16);
490 paint.setColor(SK_ColorBLUE);
491 canvas->drawText(str.c_str(), str.size(), 10, 16, paint);
492 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000493 }
494
mike@reedtribe.org093455c2013-01-28 02:21:27 +0000495 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
496 unsigned modi) SK_OVERRIDE {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000497 SkPoint pt = { x, y };
498 int index = -1;
reed@google.combbe66f02013-10-30 13:41:19 +0000499 int count = fFB.getTriangle() ? 3 : 2;
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000500 SkScalar tol = 12;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000501
reed@google.combbe66f02013-10-30 13:41:19 +0000502 for (int i = 0; i < count; ++i) {
503 if (fPts[i].equalsWithinTolerance(pt, tol)) {
504 index = i;
505 break;
506 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000507 }
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000508 return new IndexClick(this, index);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000509 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000510
mike@reedtribe.org093455c2013-01-28 02:21:27 +0000511 virtual bool onClick(Click* click) SK_OVERRIDE {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000512 int index = IndexClick::GetIndex(click);
reed@google.combbe66f02013-10-30 13:41:19 +0000513 if (index >= 0 && index <= 2) {
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000514 fPts[index] = click->fCurr;
515 } else {
516 SkScalar dx = click->fCurr.fX - click->fPrev.fX;
517 SkScalar dy = click->fCurr.fY - click->fPrev.fY;
518 fPts[0].offset(dx, dy);
519 fPts[1].offset(dx, dy);
reed@google.combbe66f02013-10-30 13:41:19 +0000520 fPts[2].offset(dx, dy);
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000521 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000522 this->inval(NULL);
523 return true;
524 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000525
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000526private:
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000527
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000528 typedef SampleView INHERITED;
529};
530
531//////////////////////////////////////////////////////////////////////////////
532
533static SkView* MyFactory() { return new DrawLineView; }
534static SkViewRegister reg(MyFactory);