blob: 2074856fcbd21888b75e27ecb8bd5c50504ba283 [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"
Ben Wagnercb3d49c2018-03-14 15:07:43 -04009#include "SkBlendMode.h"
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000010#include "SkCanvas.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050011#include "SkClipOpPriv.h"
Ben Wagnercb3d49c2018-03-14 15:07:43 -040012#include "SkColor.h"
13#include "SkImageInfo.h"
14#include "SkMatrix.h"
15#include "SkPaint.h"
16#include "SkPath.h"
17#include "SkPoint.h"
18#include "SkPointPriv.h"
19#include "SkRect.h"
20#include "SkRefCnt.h"
21#include "SkScalar.h"
22#include "SkShader.h"
23#include "SkString.h"
24#include "SkSurface.h"
25#include "SkTypes.h"
26#include "SkView.h"
27#include "sk_tool_utils.h"
28
29class SkEvent;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000030
reed@google.comc83e3522012-10-22 22:00:08 +000031#define FAT_PIXEL_COLOR SK_ColorBLACK
32#define PIXEL_CENTER_SIZE 3
33#define WIRE_FRAME_COLOR 0xFFFF0000 /*0xFF00FFFF*/
34#define WIRE_FRAME_SIZE 1.5f
35
reed@google.combbe66f02013-10-30 13:41:19 +000036static SkScalar apply_grid(SkScalar x) {
37 const SkScalar grid = 2;
38 return SkScalarRoundToScalar(x * grid) / grid;
39}
40
41static void apply_grid(SkPoint pts[], int count) {
42 for (int i = 0; i < count; ++i) {
43 pts[i].set(apply_grid(pts[i].fX), apply_grid(pts[i].fY));
44 }
45}
46
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000047static void erase(SkSurface* surface) {
junov@google.comdbfac8a2012-12-06 21:47:40 +000048 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000049}
50
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000051class FatBits {
52public:
commit-bot@chromium.org5970f622014-05-12 20:42:21 +000053 FatBits() {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000054 fAA = false;
55 fStyle = kHair_Style;
reedbb886742015-08-15 07:42:31 -070056 fGrid = false;
reed@google.comc83e3522012-10-22 22:00:08 +000057 fShowSkeleton = true;
reed@google.com9c0bef12012-11-02 19:59:18 +000058 fUseClip = false;
mike@reedtribe.org64494e92013-03-06 02:18:33 +000059 fRectAsOval = false;
reed@google.combbe66f02013-10-30 13:41:19 +000060 fUseTriangle = false;
reeda5d12072015-11-16 18:57:18 -080061 fStrokeCap = SkPaint::kButt_Cap;
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +000062
reed@google.com9c0bef12012-11-02 19:59:18 +000063 fClipRect.set(2, 2, 11, 8 );
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000064 }
65
robertphillips@google.comca47aae2012-12-12 15:58:25 +000066 int getZoom() const { return fZoom; }
reed@google.comc83e3522012-10-22 22:00:08 +000067
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000068 bool getAA() const { return fAA; }
69 void setAA(bool aa) { fAA = aa; }
70
71 bool getGrid() const { return fGrid; }
72 void setGrid(bool g) { fGrid = g; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000073
reed@google.comc83e3522012-10-22 22:00:08 +000074 bool getShowSkeleton() const { return fShowSkeleton; }
75 void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000076
reed@google.combbe66f02013-10-30 13:41:19 +000077 bool getTriangle() const { return fUseTriangle; }
78 void setTriangle(bool ut) { fUseTriangle = ut; }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +000079
mike@reedtribe.org64494e92013-03-06 02:18:33 +000080 void toggleRectAsOval() { fRectAsOval = !fRectAsOval; }
81
reed8716a8a2016-09-19 07:10:36 -070082 void togglePixelColors() {
83 if (fShader == fShader0) {
84 fShader = fShader1;
85 } else {
86 fShader = fShader0;
87 }
88 }
89
Mike Reedce54bce2017-11-01 21:17:11 -040090 float fStrokeWidth = 1;
91
reed@google.com9c0bef12012-11-02 19:59:18 +000092 bool getUseClip() const { return fUseClip; }
93 void setUseClip(bool uc) { fUseClip = uc; }
94
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000095 enum Style {
96 kHair_Style,
reed@google.comc83e3522012-10-22 22:00:08 +000097 kStroke_Style,
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000098 };
99 Style getStyle() const { return fStyle; }
100 void setStyle(Style s) { fStyle = s; }
101
102 void setWHZ(int width, int height, int zoom) {
103 fW = width;
104 fH = height;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000105 fZoom = zoom;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000106 fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom));
107 fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
108 fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
reed8716a8a2016-09-19 07:10:36 -0700109 fShader0 = sk_tool_utils::create_checkerboard_shader(0xFFDDDDDD, 0xFFFFFFFF, zoom);
110 fShader1 = SkShader::MakeColorShader(SK_ColorWHITE);
111 fShader = fShader0;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000112
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000113 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700114 fMinSurface = SkSurface::MakeRaster(info);
reede5ea5002014-09-03 11:54:58 -0700115 info = info.makeWH(width * zoom, height * zoom);
reede8f30622016-03-23 18:59:25 -0700116 fMaxSurface = SkSurface::MakeRaster(info);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000117 }
118
119 void drawBG(SkCanvas*);
120 void drawFG(SkCanvas*);
121 void drawLine(SkCanvas*, SkPoint pts[2]);
122 void drawRect(SkCanvas* canvas, SkPoint pts[2]);
reed@google.combbe66f02013-10-30 13:41:19 +0000123 void drawTriangle(SkCanvas* canvas, SkPoint pts[3]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000124
reeda5d12072015-11-16 18:57:18 -0800125 SkPaint::Cap fStrokeCap;
126
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000127private:
reed8716a8a2016-09-19 07:10:36 -0700128 bool fAA, fGrid, fShowSkeleton, fUseClip, fRectAsOval, fUseTriangle;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000129 Style fStyle;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000130 int fW, fH, fZoom;
reed8716a8a2016-09-19 07:10:36 -0700131 SkMatrix fMatrix, fInverse;
132 SkRect fBounds, fClipRect;
133 sk_sp<SkShader> fShader0;
134 sk_sp<SkShader> fShader1;
135 sk_sp<SkShader> fShader;
136 sk_sp<SkSurface> fMinSurface;
137 sk_sp<SkSurface> fMaxSurface;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000138
139 void setupPaint(SkPaint* paint) {
140 bool aa = this->getAA();
reeda5d12072015-11-16 18:57:18 -0800141 paint->setStrokeCap(fStrokeCap);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000142 switch (fStyle) {
143 case kHair_Style:
144 paint->setStrokeWidth(0);
145 break;
146 case kStroke_Style:
Mike Reedce54bce2017-11-01 21:17:11 -0400147 paint->setStrokeWidth(fStrokeWidth);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000148 break;
149 }
150 paint->setAntiAlias(aa);
151 }
152
reed@google.comc83e3522012-10-22 22:00:08 +0000153 void setupSkeletonPaint(SkPaint* paint) {
154 paint->setStyle(SkPaint::kStroke_Style);
155 paint->setStrokeWidth(WIRE_FRAME_SIZE);
156 paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0);
157 paint->setAntiAlias(true);
158 }
159
reed@google.combbe66f02013-10-30 13:41:19 +0000160 void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000161 void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
162 void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
163 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000164 this->setupSkeletonPaint(&paint);
165 SkPath path;
166
reed8716a8a2016-09-19 07:10:36 -0700167 fRectAsOval ? path.addOval(r) : path.addRect(r);
reed@google.comc83e3522012-10-22 22:00:08 +0000168 max->drawPath(path, paint);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000169 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000170
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000171 void copyMinToMax() {
reede8f30622016-03-23 18:59:25 -0700172 erase(fMaxSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000173 SkCanvas* canvas = fMaxSurface->getCanvas();
174 canvas->save();
175 canvas->concat(fMatrix);
halcanary96fcdcc2015-08-27 07:41:13 -0700176 fMinSurface->draw(canvas, 0, 0, nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000177 canvas->restore();
178
179 SkPaint paint;
reed374772b2016-10-05 17:33:02 -0700180 paint.setBlendMode(SkBlendMode::kClear);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000181 for (int iy = 1; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000182 SkScalar y = SkIntToScalar(iy * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000183 canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
184 }
185 for (int ix = 1; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000186 SkScalar x = SkIntToScalar(ix * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000187 canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
188 }
189 }
190};
191
192void FatBits::drawBG(SkCanvas* canvas) {
193 SkPaint paint;
194
195 paint.setShader(fShader);
196 canvas->drawRect(fBounds, paint);
halcanary96fcdcc2015-08-27 07:41:13 -0700197 paint.setShader(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000198}
199
200void FatBits::drawFG(SkCanvas* canvas) {
reed@google.comc83e3522012-10-22 22:00:08 +0000201 SkPaint inner, outer;
202
203 inner.setAntiAlias(true);
204 inner.setColor(SK_ColorBLACK);
205 inner.setStrokeWidth(PIXEL_CENTER_SIZE);
206
207 outer.setAntiAlias(true);
208 outer.setColor(SK_ColorWHITE);
209 outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000210
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000211 SkScalar half = SkIntToScalar(fZoom) / 2;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000212 for (int iy = 0; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000213 SkScalar y = SkIntToScalar(iy * fZoom) + half;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000214 for (int ix = 0; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000215 SkScalar x = SkIntToScalar(ix * fZoom) + half;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000216
reed@google.comc83e3522012-10-22 22:00:08 +0000217 canvas->drawPoint(x, y, outer);
218 canvas->drawPoint(x, y, inner);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000219 }
220 }
reed@google.com9c0bef12012-11-02 19:59:18 +0000221
222 if (fUseClip) {
223 SkPaint p;
224 p.setStyle(SkPaint::kStroke_Style);
225 p.setColor(SK_ColorLTGRAY);
226 SkRect r = {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000227 fClipRect.fLeft * fZoom,
228 fClipRect.fTop * fZoom,
229 fClipRect.fRight * fZoom,
230 fClipRect.fBottom * fZoom
reed@google.com9c0bef12012-11-02 19:59:18 +0000231 };
232 canvas->drawRect(r, p);
233 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000234}
235
236void FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
237 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000238 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000239
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000240 SkPath path;
241 path.moveTo(pts[0]);
242 path.lineTo(pts[1]);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000243
reed8716a8a2016-09-19 07:10:36 -0700244 if (fStyle == kStroke_Style) {
245 SkPaint p;
246 p.setStyle(SkPaint::kStroke_Style);
Mike Reedce54bce2017-11-01 21:17:11 -0400247 p.setStrokeWidth(fStrokeWidth * fZoom);
reed8716a8a2016-09-19 07:10:36 -0700248 p.setStrokeCap(fStrokeCap);
249 SkPath dst;
250 p.getFillPath(path, &dst);
251 path = dst;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000252
reed8716a8a2016-09-19 07:10:36 -0700253 path.moveTo(pts[0]);
254 path.lineTo(pts[1]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000255 }
256 max->drawPath(path, paint);
257}
258
259void FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) {
260 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000261
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000262 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000263
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000264 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000265 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000266 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000267
reede8f30622016-03-23 18:59:25 -0700268 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000269 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000270 paint.setColor(FAT_PIXEL_COLOR);
reed@google.com9c0bef12012-11-02 19:59:18 +0000271 if (fUseClip) {
272 fMinSurface->getCanvas()->save();
273 SkRect r = fClipRect;
274 r.inset(SK_Scalar1/3, SK_Scalar1/3);
Mike Reedc1f77742016-12-09 09:00:50 -0500275 fMinSurface->getCanvas()->clipRect(r, kIntersect_SkClipOp, true);
reed@google.com9c0bef12012-11-02 19:59:18 +0000276 }
Hal Canary23e474c2017-05-15 13:35:35 -0400277 fMinSurface->getCanvas()->drawLine(pts[0], pts[1], paint);
reed@google.com9c0bef12012-11-02 19:59:18 +0000278 if (fUseClip) {
279 fMinSurface->getCanvas()->restore();
280 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000281 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000282
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000283 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000284
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000285 fMatrix.mapPoints(pts, 2);
286 this->drawLineSkeleton(max, pts);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000287
halcanary96fcdcc2015-08-27 07:41:13 -0700288 fMaxSurface->draw(canvas, 0, 0, nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000289}
290
291void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
292 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000293
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000294 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000295
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000296 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000297 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000298 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000299
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000300 SkRect r;
301 r.set(pts, 2);
302
reede8f30622016-03-23 18:59:25 -0700303 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000304 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000305 paint.setColor(FAT_PIXEL_COLOR);
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000306 {
307 SkCanvas* c = fMinSurface->getCanvas();
308 fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint);
309 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000310 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000311
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000312 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000313
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000314 fMatrix.mapPoints(pts, 2);
315 r.set(pts, 2);
316 this->drawRectSkeleton(max, r);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000317
halcanary96fcdcc2015-08-27 07:41:13 -0700318 fMaxSurface->draw(canvas, 0, 0, nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000319}
320
reed@google.combbe66f02013-10-30 13:41:19 +0000321void FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
322 SkPaint paint;
323 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000324
reed@google.combbe66f02013-10-30 13:41:19 +0000325 SkPath path;
326 path.moveTo(pts[0]);
327 path.lineTo(pts[1]);
328 path.lineTo(pts[2]);
329 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000330
reed@google.combbe66f02013-10-30 13:41:19 +0000331 max->drawPath(path, paint);
332}
333
334void FatBits::drawTriangle(SkCanvas* canvas, SkPoint pts[3]) {
335 SkPaint paint;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000336
reed@google.combbe66f02013-10-30 13:41:19 +0000337 fInverse.mapPoints(pts, 3);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000338
reed@google.combbe66f02013-10-30 13:41:19 +0000339 if (fGrid) {
340 apply_grid(pts, 3);
341 }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000342
reed@google.combbe66f02013-10-30 13:41:19 +0000343 SkPath path;
344 path.moveTo(pts[0]);
345 path.lineTo(pts[1]);
346 path.lineTo(pts[2]);
347 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000348
reede8f30622016-03-23 18:59:25 -0700349 erase(fMinSurface.get());
reed@google.combbe66f02013-10-30 13:41:19 +0000350 this->setupPaint(&paint);
351 paint.setColor(FAT_PIXEL_COLOR);
352 fMinSurface->getCanvas()->drawPath(path, paint);
353 this->copyMinToMax();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000354
reed@google.combbe66f02013-10-30 13:41:19 +0000355 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000356
reed@google.combbe66f02013-10-30 13:41:19 +0000357 fMatrix.mapPoints(pts, 3);
358 this->drawTriangleSkeleton(max, pts);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000359
halcanary96fcdcc2015-08-27 07:41:13 -0700360 fMaxSurface->draw(canvas, 0, 0, nullptr);
reed@google.combbe66f02013-10-30 13:41:19 +0000361}
362
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000363///////////////////////////////////////////////////////////////////////////////////////////////////
364
365class IndexClick : public SkView::Click {
366 int fIndex;
367public:
368 IndexClick(SkView* v, int index) : SkView::Click(v), fIndex(index) {}
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000369
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000370 static int GetIndex(SkView::Click* click) {
371 return ((IndexClick*)click)->fIndex;
372 }
373};
374
375class DrawLineView : public SampleView {
376 FatBits fFB;
reed@google.combbe66f02013-10-30 13:41:19 +0000377 SkPoint fPts[3];
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000378 bool fIsRect;
reed8716a8a2016-09-19 07:10:36 -0700379 int fZoom = 64;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000380public:
381 DrawLineView() {
reed8716a8a2016-09-19 07:10:36 -0700382 fFB.setWHZ(24*2, 16*2, fZoom);
reedbb886742015-08-15 07:42:31 -0700383 fPts[0].set(1, 1);
384 fPts[1].set(5, 4);
385 fPts[2].set(2, 6);
reed8716a8a2016-09-19 07:10:36 -0700386 SkMatrix::MakeScale(SkIntToScalar(fZoom)).mapPoints(fPts, 3);
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000387 fIsRect = false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000388 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000389
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000390 void setStyle(FatBits::Style s) {
391 fFB.setStyle(s);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000392 }
393
394protected:
mtklein36352bf2015-03-25 18:17:31 -0700395 bool onQuery(SkEvent* evt) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000396 if (SampleCode::TitleQ(*evt)) {
397 SampleCode::TitleR(evt, "FatBits");
398 return true;
399 }
400 SkUnichar uni;
401 if (SampleCode::CharQ(*evt, &uni)) {
402 switch (uni) {
reed@google.com9c0bef12012-11-02 19:59:18 +0000403 case 'c':
404 fFB.setUseClip(!fFB.getUseClip());
reed@google.com9c0bef12012-11-02 19:59:18 +0000405 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000406 case 'r':
407 fIsRect = !fIsRect;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000408 return true;
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000409 case 'o':
410 fFB.toggleRectAsOval();
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000411 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000412 case 'x':
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000413 fFB.setGrid(!fFB.getGrid());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000414 return true;
415 case 's':
416 if (FatBits::kStroke_Style == fFB.getStyle()) {
417 this->setStyle(FatBits::kHair_Style);
418 } else {
419 this->setStyle(FatBits::kStroke_Style);
420 }
421 return true;
reeda5d12072015-11-16 18:57:18 -0800422 case 'k': {
423 const SkPaint::Cap caps[] = {
424 SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap,
425 };
426 fFB.fStrokeCap = caps[(fFB.fStrokeCap + 1) % 3];
reeda5d12072015-11-16 18:57:18 -0800427 return true;
428 } break;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000429 case 'a':
430 fFB.setAA(!fFB.getAA());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000431 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000432 case 'w':
433 fFB.setShowSkeleton(!fFB.getShowSkeleton());
reed@google.comc83e3522012-10-22 22:00:08 +0000434 return true;
435 case 'g':
reed8716a8a2016-09-19 07:10:36 -0700436 fFB.togglePixelColors();
reed@google.comc83e3522012-10-22 22:00:08 +0000437 return true;
reed@google.combbe66f02013-10-30 13:41:19 +0000438 case 't':
439 fFB.setTriangle(!fFB.getTriangle());
reed@google.combbe66f02013-10-30 13:41:19 +0000440 return true;
Mike Reedce54bce2017-11-01 21:17:11 -0400441 case '-':
442 fFB.fStrokeWidth -= 0.125f;
Mike Reedce54bce2017-11-01 21:17:11 -0400443 return true;
444 case '=':
445 fFB.fStrokeWidth += 0.125f;
Mike Reedce54bce2017-11-01 21:17:11 -0400446 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000447 }
448 }
449 return this->INHERITED::onQuery(evt);
450 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000451
mtkleinf0599002015-07-13 06:18:39 -0700452 void onDrawContent(SkCanvas* canvas) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000453 fFB.drawBG(canvas);
reed@google.combbe66f02013-10-30 13:41:19 +0000454 if (fFB.getTriangle()) {
455 fFB.drawTriangle(canvas, fPts);
456 }
457 else if (fIsRect) {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000458 fFB.drawRect(canvas, fPts);
459 } else {
460 fFB.drawLine(canvas, fPts);
461 }
462 fFB.drawFG(canvas);
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000463
reed@google.comffe9d012012-10-23 15:33:41 +0000464 {
465 SkString str;
reed8716a8a2016-09-19 07:10:36 -0700466 str.printf("%s %s %s",
reed@google.comffe9d012012-10-23 15:33:41 +0000467 fFB.getAA() ? "AA" : "BW",
468 FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
reed@google.com9c0bef12012-11-02 19:59:18 +0000469 fFB.getUseClip() ? "clip" : "noclip");
reed@google.comffe9d012012-10-23 15:33:41 +0000470 SkPaint paint;
471 paint.setAntiAlias(true);
472 paint.setTextSize(16);
473 paint.setColor(SK_ColorBLUE);
Cary Clark2a475ea2017-04-28 15:35:12 -0400474 canvas->drawString(str, 10, 16, paint);
reed@google.comffe9d012012-10-23 15:33:41 +0000475 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000476 }
477
mtkleinf0599002015-07-13 06:18:39 -0700478 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000479 SkPoint pt = { x, y };
480 int index = -1;
reed@google.combbe66f02013-10-30 13:41:19 +0000481 int count = fFB.getTriangle() ? 3 : 2;
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000482 SkScalar tol = 12;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000483
reed@google.combbe66f02013-10-30 13:41:19 +0000484 for (int i = 0; i < count; ++i) {
Cary Clarkdf429f32017-11-08 11:44:31 -0500485 if (SkPointPriv::EqualsWithinTolerance(fPts[i], pt, tol)) {
reed@google.combbe66f02013-10-30 13:41:19 +0000486 index = i;
487 break;
488 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000489 }
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000490 return new IndexClick(this, index);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000491 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000492
mtklein36352bf2015-03-25 18:17:31 -0700493 bool onClick(Click* click) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000494 int index = IndexClick::GetIndex(click);
reed@google.combbe66f02013-10-30 13:41:19 +0000495 if (index >= 0 && index <= 2) {
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000496 fPts[index] = click->fCurr;
497 } else {
498 SkScalar dx = click->fCurr.fX - click->fPrev.fX;
499 SkScalar dy = click->fCurr.fY - click->fPrev.fY;
500 fPts[0].offset(dx, dy);
501 fPts[1].offset(dx, dy);
reed@google.combbe66f02013-10-30 13:41:19 +0000502 fPts[2].offset(dx, dy);
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000503 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000504 return true;
505 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000506
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000507private:
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000508
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000509 typedef SampleView INHERITED;
510};
511
512//////////////////////////////////////////////////////////////////////////////
513
514static SkView* MyFactory() { return new DrawLineView; }
515static SkViewRegister reg(MyFactory);