blob: abc6707302191e8769e9647eef557e7291a80809 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkBlendMode.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkColor.h"
11#include "include/core/SkImageInfo.h"
12#include "include/core/SkMatrix.h"
13#include "include/core/SkPaint.h"
14#include "include/core/SkPath.h"
15#include "include/core/SkPoint.h"
16#include "include/core/SkRect.h"
17#include "include/core/SkRefCnt.h"
18#include "include/core/SkScalar.h"
19#include "include/core/SkShader.h"
20#include "include/core/SkString.h"
21#include "include/core/SkSurface.h"
22#include "include/core/SkTypes.h"
23#include "samplecode/Sample.h"
24#include "src/core/SkClipOpPriv.h"
25#include "src/core/SkPointPriv.h"
26#include "tools/ToolUtils.h"
Ben Wagnercb3d49c2018-03-14 15:07:43 -040027
28class SkEvent;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000029
reed@google.comc83e3522012-10-22 22:00:08 +000030#define FAT_PIXEL_COLOR SK_ColorBLACK
31#define PIXEL_CENTER_SIZE 3
32#define WIRE_FRAME_COLOR 0xFFFF0000 /*0xFF00FFFF*/
33#define WIRE_FRAME_SIZE 1.5f
34
reed@google.combbe66f02013-10-30 13:41:19 +000035static SkScalar apply_grid(SkScalar x) {
36 const SkScalar grid = 2;
37 return SkScalarRoundToScalar(x * grid) / grid;
38}
39
40static void apply_grid(SkPoint pts[], int count) {
41 for (int i = 0; i < count; ++i) {
42 pts[i].set(apply_grid(pts[i].fX), apply_grid(pts[i].fY));
43 }
44}
45
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000046static void erase(SkSurface* surface) {
junov@google.comdbfac8a2012-12-06 21:47:40 +000047 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000048}
49
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000050class FatBits {
51public:
commit-bot@chromium.org5970f622014-05-12 20:42:21 +000052 FatBits() {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000053 fAA = false;
54 fStyle = kHair_Style;
reedbb886742015-08-15 07:42:31 -070055 fGrid = false;
reed@google.comc83e3522012-10-22 22:00:08 +000056 fShowSkeleton = true;
reed@google.com9c0bef12012-11-02 19:59:18 +000057 fUseClip = false;
mike@reedtribe.org64494e92013-03-06 02:18:33 +000058 fRectAsOval = false;
reed@google.combbe66f02013-10-30 13:41:19 +000059 fUseTriangle = false;
reeda5d12072015-11-16 18:57:18 -080060 fStrokeCap = SkPaint::kButt_Cap;
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +000061
Mike Reed92b33352019-08-24 19:39:13 -040062 fClipRect.setLTRB(2, 2, 11, 8 );
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000063 }
64
robertphillips@google.comca47aae2012-12-12 15:58:25 +000065 int getZoom() const { return fZoom; }
reed@google.comc83e3522012-10-22 22:00:08 +000066
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000067 bool getAA() const { return fAA; }
68 void setAA(bool aa) { fAA = aa; }
69
70 bool getGrid() const { return fGrid; }
71 void setGrid(bool g) { fGrid = g; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000072
reed@google.comc83e3522012-10-22 22:00:08 +000073 bool getShowSkeleton() const { return fShowSkeleton; }
74 void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000075
reed@google.combbe66f02013-10-30 13:41:19 +000076 bool getTriangle() const { return fUseTriangle; }
77 void setTriangle(bool ut) { fUseTriangle = ut; }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +000078
mike@reedtribe.org64494e92013-03-06 02:18:33 +000079 void toggleRectAsOval() { fRectAsOval = !fRectAsOval; }
80
reed8716a8a2016-09-19 07:10:36 -070081 void togglePixelColors() {
82 if (fShader == fShader0) {
83 fShader = fShader1;
84 } else {
85 fShader = fShader0;
86 }
87 }
88
Mike Reedce54bce2017-11-01 21:17:11 -040089 float fStrokeWidth = 1;
90
reed@google.com9c0bef12012-11-02 19:59:18 +000091 bool getUseClip() const { return fUseClip; }
92 void setUseClip(bool uc) { fUseClip = uc; }
93
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000094 enum Style {
95 kHair_Style,
reed@google.comc83e3522012-10-22 22:00:08 +000096 kStroke_Style,
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000097 };
98 Style getStyle() const { return fStyle; }
99 void setStyle(Style s) { fStyle = s; }
100
101 void setWHZ(int width, int height, int zoom) {
102 fW = width;
103 fH = height;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000104 fZoom = zoom;
Mike Reed92b33352019-08-24 19:39:13 -0400105 fBounds.setIWH(width * zoom, height * zoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000106 fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
107 fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
Mike Kleinea3f0142019-03-20 11:12:10 -0500108 fShader0 = ToolUtils::create_checkerboard_shader(0xFFDDDDDD, 0xFFFFFFFF, zoom);
Mike Reedc8bea7d2019-04-09 13:55:36 -0400109 fShader1 = SkShaders::Color(SK_ColorWHITE);
reed8716a8a2016-09-19 07:10:36 -0700110 fShader = fShader0;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000111
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000112 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700113 fMinSurface = SkSurface::MakeRaster(info);
reede5ea5002014-09-03 11:54:58 -0700114 info = info.makeWH(width * zoom, height * zoom);
reede8f30622016-03-23 18:59:25 -0700115 fMaxSurface = SkSurface::MakeRaster(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
reeda5d12072015-11-16 18:57:18 -0800124 SkPaint::Cap fStrokeCap;
125
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000126private:
reed8716a8a2016-09-19 07:10:36 -0700127 bool fAA, fGrid, fShowSkeleton, fUseClip, fRectAsOval, fUseTriangle;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000128 Style fStyle;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000129 int fW, fH, fZoom;
reed8716a8a2016-09-19 07:10:36 -0700130 SkMatrix fMatrix, fInverse;
131 SkRect fBounds, fClipRect;
132 sk_sp<SkShader> fShader0;
133 sk_sp<SkShader> fShader1;
134 sk_sp<SkShader> fShader;
135 sk_sp<SkSurface> fMinSurface;
136 sk_sp<SkSurface> fMaxSurface;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000137
138 void setupPaint(SkPaint* paint) {
139 bool aa = this->getAA();
reeda5d12072015-11-16 18:57:18 -0800140 paint->setStrokeCap(fStrokeCap);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000141 switch (fStyle) {
142 case kHair_Style:
143 paint->setStrokeWidth(0);
144 break;
145 case kStroke_Style:
Mike Reedce54bce2017-11-01 21:17:11 -0400146 paint->setStrokeWidth(fStrokeWidth);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000147 break;
148 }
149 paint->setAntiAlias(aa);
150 }
151
reed@google.comc83e3522012-10-22 22:00:08 +0000152 void setupSkeletonPaint(SkPaint* paint) {
153 paint->setStyle(SkPaint::kStroke_Style);
154 paint->setStrokeWidth(WIRE_FRAME_SIZE);
155 paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0);
156 paint->setAntiAlias(true);
157 }
158
reed@google.combbe66f02013-10-30 13:41:19 +0000159 void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000160 void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
161 void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
162 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000163 this->setupSkeletonPaint(&paint);
164 SkPath path;
165
reed8716a8a2016-09-19 07:10:36 -0700166 fRectAsOval ? path.addOval(r) : path.addRect(r);
reed@google.comc83e3522012-10-22 22:00:08 +0000167 max->drawPath(path, paint);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000168 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000169
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000170 void copyMinToMax() {
reede8f30622016-03-23 18:59:25 -0700171 erase(fMaxSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000172 SkCanvas* canvas = fMaxSurface->getCanvas();
173 canvas->save();
174 canvas->concat(fMatrix);
Mike Reedb746b1f2021-01-06 08:43:51 -0500175 fMinSurface->draw(canvas, 0, 0);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000176 canvas->restore();
177
178 SkPaint paint;
reed374772b2016-10-05 17:33:02 -0700179 paint.setBlendMode(SkBlendMode::kClear);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000180 for (int iy = 1; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000181 SkScalar y = SkIntToScalar(iy * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000182 canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
183 }
184 for (int ix = 1; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000185 SkScalar x = SkIntToScalar(ix * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000186 canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
187 }
188 }
189};
190
191void FatBits::drawBG(SkCanvas* canvas) {
192 SkPaint paint;
193
194 paint.setShader(fShader);
195 canvas->drawRect(fBounds, paint);
halcanary96fcdcc2015-08-27 07:41:13 -0700196 paint.setShader(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000197}
198
199void FatBits::drawFG(SkCanvas* canvas) {
reed@google.comc83e3522012-10-22 22:00:08 +0000200 SkPaint inner, outer;
201
202 inner.setAntiAlias(true);
203 inner.setColor(SK_ColorBLACK);
204 inner.setStrokeWidth(PIXEL_CENTER_SIZE);
205
206 outer.setAntiAlias(true);
207 outer.setColor(SK_ColorWHITE);
208 outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000209
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000210 SkScalar half = SkIntToScalar(fZoom) / 2;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000211 for (int iy = 0; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000212 SkScalar y = SkIntToScalar(iy * fZoom) + half;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000213 for (int ix = 0; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000214 SkScalar x = SkIntToScalar(ix * fZoom) + half;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000215
reed@google.comc83e3522012-10-22 22:00:08 +0000216 canvas->drawPoint(x, y, outer);
217 canvas->drawPoint(x, y, inner);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000218 }
219 }
reed@google.com9c0bef12012-11-02 19:59:18 +0000220
221 if (fUseClip) {
222 SkPaint p;
223 p.setStyle(SkPaint::kStroke_Style);
224 p.setColor(SK_ColorLTGRAY);
225 SkRect r = {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000226 fClipRect.fLeft * fZoom,
227 fClipRect.fTop * fZoom,
228 fClipRect.fRight * fZoom,
229 fClipRect.fBottom * fZoom
reed@google.com9c0bef12012-11-02 19:59:18 +0000230 };
231 canvas->drawRect(r, p);
232 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000233}
234
235void FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
236 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000237 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000238
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000239 SkPath path;
240 path.moveTo(pts[0]);
241 path.lineTo(pts[1]);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000242
reed8716a8a2016-09-19 07:10:36 -0700243 if (fStyle == kStroke_Style) {
244 SkPaint p;
245 p.setStyle(SkPaint::kStroke_Style);
Mike Reedce54bce2017-11-01 21:17:11 -0400246 p.setStrokeWidth(fStrokeWidth * fZoom);
reed8716a8a2016-09-19 07:10:36 -0700247 p.setStrokeCap(fStrokeCap);
248 SkPath dst;
249 p.getFillPath(path, &dst);
250 path = dst;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000251
reed8716a8a2016-09-19 07:10:36 -0700252 path.moveTo(pts[0]);
253 path.lineTo(pts[1]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000254 }
255 max->drawPath(path, paint);
256}
257
258void FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) {
259 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000260
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000261 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000262
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000263 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000264 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000265 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000266
reede8f30622016-03-23 18:59:25 -0700267 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000268 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000269 paint.setColor(FAT_PIXEL_COLOR);
reed@google.com9c0bef12012-11-02 19:59:18 +0000270 if (fUseClip) {
271 fMinSurface->getCanvas()->save();
272 SkRect r = fClipRect;
273 r.inset(SK_Scalar1/3, SK_Scalar1/3);
Mike Reedc1f77742016-12-09 09:00:50 -0500274 fMinSurface->getCanvas()->clipRect(r, kIntersect_SkClipOp, true);
reed@google.com9c0bef12012-11-02 19:59:18 +0000275 }
Hal Canary23e474c2017-05-15 13:35:35 -0400276 fMinSurface->getCanvas()->drawLine(pts[0], pts[1], paint);
reed@google.com9c0bef12012-11-02 19:59:18 +0000277 if (fUseClip) {
278 fMinSurface->getCanvas()->restore();
279 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000280 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000281
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000282 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000283
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000284 fMatrix.mapPoints(pts, 2);
285 this->drawLineSkeleton(max, pts);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000286
Mike Reedb746b1f2021-01-06 08:43:51 -0500287 fMaxSurface->draw(canvas, 0, 0);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000288}
289
290void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
291 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000292
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000293 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000294
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000295 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000296 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000297 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000298
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000299 SkRect r;
Mike Reed92b33352019-08-24 19:39:13 -0400300 r.setBounds(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000301
reede8f30622016-03-23 18:59:25 -0700302 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000303 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000304 paint.setColor(FAT_PIXEL_COLOR);
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000305 {
306 SkCanvas* c = fMinSurface->getCanvas();
307 fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint);
308 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000309 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000310
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000311 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000312
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000313 fMatrix.mapPoints(pts, 2);
Mike Reed92b33352019-08-24 19:39:13 -0400314 r.setBounds(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000315 this->drawRectSkeleton(max, r);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000316
Mike Reedb746b1f2021-01-06 08:43:51 -0500317 fMaxSurface->draw(canvas, 0, 0);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000318}
319
reed@google.combbe66f02013-10-30 13:41:19 +0000320void FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
321 SkPaint paint;
322 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000323
reed@google.combbe66f02013-10-30 13:41:19 +0000324 SkPath path;
325 path.moveTo(pts[0]);
326 path.lineTo(pts[1]);
327 path.lineTo(pts[2]);
328 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000329
reed@google.combbe66f02013-10-30 13:41:19 +0000330 max->drawPath(path, paint);
331}
332
333void FatBits::drawTriangle(SkCanvas* canvas, SkPoint pts[3]) {
334 SkPaint paint;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000335
reed@google.combbe66f02013-10-30 13:41:19 +0000336 fInverse.mapPoints(pts, 3);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000337
reed@google.combbe66f02013-10-30 13:41:19 +0000338 if (fGrid) {
339 apply_grid(pts, 3);
340 }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000341
reed@google.combbe66f02013-10-30 13:41:19 +0000342 SkPath path;
343 path.moveTo(pts[0]);
344 path.lineTo(pts[1]);
345 path.lineTo(pts[2]);
346 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000347
reede8f30622016-03-23 18:59:25 -0700348 erase(fMinSurface.get());
reed@google.combbe66f02013-10-30 13:41:19 +0000349 this->setupPaint(&paint);
350 paint.setColor(FAT_PIXEL_COLOR);
351 fMinSurface->getCanvas()->drawPath(path, paint);
352 this->copyMinToMax();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000353
reed@google.combbe66f02013-10-30 13:41:19 +0000354 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000355
reed@google.combbe66f02013-10-30 13:41:19 +0000356 fMatrix.mapPoints(pts, 3);
357 this->drawTriangleSkeleton(max, pts);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000358
Mike Reedb746b1f2021-01-06 08:43:51 -0500359 fMaxSurface->draw(canvas, 0, 0);
reed@google.combbe66f02013-10-30 13:41:19 +0000360}
361
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000362///////////////////////////////////////////////////////////////////////////////////////////////////
363
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400364class IndexClick : public Sample::Click {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000365 int fIndex;
366public:
Hal Canaryfcf63592019-07-12 11:32:43 -0400367 IndexClick(int index) : fIndex(index) {}
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000368
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400369 static int GetIndex(Sample::Click* click) {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000370 return ((IndexClick*)click)->fIndex;
371 }
372};
373
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400374class DrawLineView : public Sample {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000375 FatBits fFB;
reed@google.combbe66f02013-10-30 13:41:19 +0000376 SkPoint fPts[3];
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000377 bool fIsRect;
reed8716a8a2016-09-19 07:10:36 -0700378 int fZoom = 64;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000379public:
380 DrawLineView() {
reed8716a8a2016-09-19 07:10:36 -0700381 fFB.setWHZ(24*2, 16*2, fZoom);
reedbb886742015-08-15 07:42:31 -0700382 fPts[0].set(1, 1);
383 fPts[1].set(5, 4);
384 fPts[2].set(2, 6);
Mike Reed1f607332020-05-21 12:11:27 -0400385 SkMatrix::Scale(fZoom, fZoom).mapPoints(fPts, 3);
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000386 fIsRect = false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000387 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000388
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000389 void setStyle(FatBits::Style s) {
390 fFB.setStyle(s);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000391 }
392
393protected:
Hal Canary8a027312019-07-03 10:55:44 -0400394 SkString name() override { return SkString("FatBits"); }
395
Hal Canary6cc65e12019-07-03 15:53:04 -0400396 bool onChar(SkUnichar uni) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000397 switch (uni) {
reed@google.com9c0bef12012-11-02 19:59:18 +0000398 case 'c':
399 fFB.setUseClip(!fFB.getUseClip());
reed@google.com9c0bef12012-11-02 19:59:18 +0000400 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000401 case 'r':
402 fIsRect = !fIsRect;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000403 return true;
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000404 case 'o':
405 fFB.toggleRectAsOval();
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000406 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000407 case 'x':
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000408 fFB.setGrid(!fFB.getGrid());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000409 return true;
410 case 's':
411 if (FatBits::kStroke_Style == fFB.getStyle()) {
412 this->setStyle(FatBits::kHair_Style);
413 } else {
414 this->setStyle(FatBits::kStroke_Style);
415 }
416 return true;
reeda5d12072015-11-16 18:57:18 -0800417 case 'k': {
418 const SkPaint::Cap caps[] = {
419 SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap,
420 };
421 fFB.fStrokeCap = caps[(fFB.fStrokeCap + 1) % 3];
reeda5d12072015-11-16 18:57:18 -0800422 return true;
423 } break;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000424 case 'a':
425 fFB.setAA(!fFB.getAA());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000426 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000427 case 'w':
428 fFB.setShowSkeleton(!fFB.getShowSkeleton());
reed@google.comc83e3522012-10-22 22:00:08 +0000429 return true;
430 case 'g':
reed8716a8a2016-09-19 07:10:36 -0700431 fFB.togglePixelColors();
reed@google.comc83e3522012-10-22 22:00:08 +0000432 return true;
reed@google.combbe66f02013-10-30 13:41:19 +0000433 case 't':
434 fFB.setTriangle(!fFB.getTriangle());
reed@google.combbe66f02013-10-30 13:41:19 +0000435 return true;
Mike Reedce54bce2017-11-01 21:17:11 -0400436 case '-':
437 fFB.fStrokeWidth -= 0.125f;
Mike Reedce54bce2017-11-01 21:17:11 -0400438 return true;
439 case '=':
440 fFB.fStrokeWidth += 0.125f;
Mike Reedce54bce2017-11-01 21:17:11 -0400441 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000442 }
Hal Canary6cc65e12019-07-03 15:53:04 -0400443 return false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000444 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000445
mtkleinf0599002015-07-13 06:18:39 -0700446 void onDrawContent(SkCanvas* canvas) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000447 fFB.drawBG(canvas);
reed@google.combbe66f02013-10-30 13:41:19 +0000448 if (fFB.getTriangle()) {
449 fFB.drawTriangle(canvas, fPts);
450 }
451 else if (fIsRect) {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000452 fFB.drawRect(canvas, fPts);
453 } else {
454 fFB.drawLine(canvas, fPts);
455 }
456 fFB.drawFG(canvas);
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000457
reed@google.comffe9d012012-10-23 15:33:41 +0000458 {
459 SkString str;
reed8716a8a2016-09-19 07:10:36 -0700460 str.printf("%s %s %s",
reed@google.comffe9d012012-10-23 15:33:41 +0000461 fFB.getAA() ? "AA" : "BW",
462 FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
reed@google.com9c0bef12012-11-02 19:59:18 +0000463 fFB.getUseClip() ? "clip" : "noclip");
reed@google.comffe9d012012-10-23 15:33:41 +0000464 SkPaint paint;
reed@google.comffe9d012012-10-23 15:33:41 +0000465 paint.setColor(SK_ColorBLUE);
Hal Canary4484b8f2019-01-08 14:00:08 -0500466 SkFont font(nullptr, 16);
467 canvas->drawString(str, 10, 16, font, paint);
reed@google.comffe9d012012-10-23 15:33:41 +0000468 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000469 }
470
Hal Canaryb1f411a2019-08-29 10:39:22 -0400471 Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000472 SkPoint pt = { x, y };
473 int index = -1;
reed@google.combbe66f02013-10-30 13:41:19 +0000474 int count = fFB.getTriangle() ? 3 : 2;
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000475 SkScalar tol = 12;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000476
reed@google.combbe66f02013-10-30 13:41:19 +0000477 for (int i = 0; i < count; ++i) {
Cary Clarkdf429f32017-11-08 11:44:31 -0500478 if (SkPointPriv::EqualsWithinTolerance(fPts[i], pt, tol)) {
reed@google.combbe66f02013-10-30 13:41:19 +0000479 index = i;
480 break;
481 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000482 }
Hal Canaryfcf63592019-07-12 11:32:43 -0400483 return new IndexClick(index);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000484 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000485
mtklein36352bf2015-03-25 18:17:31 -0700486 bool onClick(Click* click) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000487 int index = IndexClick::GetIndex(click);
reed@google.combbe66f02013-10-30 13:41:19 +0000488 if (index >= 0 && index <= 2) {
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000489 fPts[index] = click->fCurr;
490 } else {
491 SkScalar dx = click->fCurr.fX - click->fPrev.fX;
492 SkScalar dy = click->fCurr.fY - click->fPrev.fY;
493 fPts[0].offset(dx, dy);
494 fPts[1].offset(dx, dy);
reed@google.combbe66f02013-10-30 13:41:19 +0000495 fPts[2].offset(dx, dy);
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000496 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000497 return true;
498 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000499
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000500private:
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000501
John Stiles7571f9e2020-09-02 22:42:33 -0400502 using INHERITED = Sample;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000503};
504
505//////////////////////////////////////////////////////////////////////////////
506
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400507DEF_SAMPLE( return new DrawLineView(); )