blob: f80fb25c611fa0039237ca131a6b62f34b88406a [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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "src/core/SkPointPriv.h"
25#include "tools/ToolUtils.h"
Ben Wagnercb3d49c2018-03-14 15:07:43 -040026
27class SkEvent;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000028
reed@google.comc83e3522012-10-22 22:00:08 +000029#define FAT_PIXEL_COLOR SK_ColorBLACK
30#define PIXEL_CENTER_SIZE 3
31#define WIRE_FRAME_COLOR 0xFFFF0000 /*0xFF00FFFF*/
32#define WIRE_FRAME_SIZE 1.5f
33
reed@google.combbe66f02013-10-30 13:41:19 +000034static SkScalar apply_grid(SkScalar x) {
35 const SkScalar grid = 2;
36 return SkScalarRoundToScalar(x * grid) / grid;
37}
38
39static void apply_grid(SkPoint pts[], int count) {
40 for (int i = 0; i < count; ++i) {
41 pts[i].set(apply_grid(pts[i].fX), apply_grid(pts[i].fY));
42 }
43}
44
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000045static void erase(SkSurface* surface) {
junov@google.comdbfac8a2012-12-06 21:47:40 +000046 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000047}
48
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000049class FatBits {
50public:
commit-bot@chromium.org5970f622014-05-12 20:42:21 +000051 FatBits() {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000052 fAA = false;
53 fStyle = kHair_Style;
reedbb886742015-08-15 07:42:31 -070054 fGrid = false;
reed@google.comc83e3522012-10-22 22:00:08 +000055 fShowSkeleton = true;
reed@google.com9c0bef12012-11-02 19:59:18 +000056 fUseClip = false;
mike@reedtribe.org64494e92013-03-06 02:18:33 +000057 fRectAsOval = false;
reed@google.combbe66f02013-10-30 13:41:19 +000058 fUseTriangle = false;
reeda5d12072015-11-16 18:57:18 -080059 fStrokeCap = SkPaint::kButt_Cap;
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +000060
Mike Reed92b33352019-08-24 19:39:13 -040061 fClipRect.setLTRB(2, 2, 11, 8 );
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000062 }
63
robertphillips@google.comca47aae2012-12-12 15:58:25 +000064 int getZoom() const { return fZoom; }
reed@google.comc83e3522012-10-22 22:00:08 +000065
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000066 bool getAA() const { return fAA; }
67 void setAA(bool aa) { fAA = aa; }
68
69 bool getGrid() const { return fGrid; }
70 void setGrid(bool g) { fGrid = g; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000071
reed@google.comc83e3522012-10-22 22:00:08 +000072 bool getShowSkeleton() const { return fShowSkeleton; }
73 void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000074
reed@google.combbe66f02013-10-30 13:41:19 +000075 bool getTriangle() const { return fUseTriangle; }
76 void setTriangle(bool ut) { fUseTriangle = ut; }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +000077
mike@reedtribe.org64494e92013-03-06 02:18:33 +000078 void toggleRectAsOval() { fRectAsOval = !fRectAsOval; }
79
reed8716a8a2016-09-19 07:10:36 -070080 void togglePixelColors() {
81 if (fShader == fShader0) {
82 fShader = fShader1;
83 } else {
84 fShader = fShader0;
85 }
86 }
87
Mike Reedce54bce2017-11-01 21:17:11 -040088 float fStrokeWidth = 1;
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 Reed92b33352019-08-24 19:39:13 -0400104 fBounds.setIWH(width * zoom, height * zoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000105 fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
106 fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
Mike Kleinea3f0142019-03-20 11:12:10 -0500107 fShader0 = ToolUtils::create_checkerboard_shader(0xFFDDDDDD, 0xFFFFFFFF, zoom);
Mike Reedc8bea7d2019-04-09 13:55:36 -0400108 fShader1 = SkShaders::Color(SK_ColorWHITE);
reed8716a8a2016-09-19 07:10:36 -0700109 fShader = fShader0;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000110
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000111 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700112 fMinSurface = SkSurface::MakeRaster(info);
reede5ea5002014-09-03 11:54:58 -0700113 info = info.makeWH(width * zoom, height * zoom);
reede8f30622016-03-23 18:59:25 -0700114 fMaxSurface = SkSurface::MakeRaster(info);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000115 }
116
117 void drawBG(SkCanvas*);
118 void drawFG(SkCanvas*);
119 void drawLine(SkCanvas*, SkPoint pts[2]);
120 void drawRect(SkCanvas* canvas, SkPoint pts[2]);
reed@google.combbe66f02013-10-30 13:41:19 +0000121 void drawTriangle(SkCanvas* canvas, SkPoint pts[3]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000122
reeda5d12072015-11-16 18:57:18 -0800123 SkPaint::Cap fStrokeCap;
124
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000125private:
reed8716a8a2016-09-19 07:10:36 -0700126 bool fAA, fGrid, fShowSkeleton, fUseClip, fRectAsOval, fUseTriangle;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000127 Style fStyle;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000128 int fW, fH, fZoom;
reed8716a8a2016-09-19 07:10:36 -0700129 SkMatrix fMatrix, fInverse;
130 SkRect fBounds, fClipRect;
131 sk_sp<SkShader> fShader0;
132 sk_sp<SkShader> fShader1;
133 sk_sp<SkShader> fShader;
134 sk_sp<SkSurface> fMinSurface;
135 sk_sp<SkSurface> fMaxSurface;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000136
137 void setupPaint(SkPaint* paint) {
138 bool aa = this->getAA();
reeda5d12072015-11-16 18:57:18 -0800139 paint->setStrokeCap(fStrokeCap);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000140 switch (fStyle) {
141 case kHair_Style:
142 paint->setStrokeWidth(0);
143 break;
144 case kStroke_Style:
Mike Reedce54bce2017-11-01 21:17:11 -0400145 paint->setStrokeWidth(fStrokeWidth);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000146 break;
147 }
148 paint->setAntiAlias(aa);
149 }
150
reed@google.comc83e3522012-10-22 22:00:08 +0000151 void setupSkeletonPaint(SkPaint* paint) {
152 paint->setStyle(SkPaint::kStroke_Style);
153 paint->setStrokeWidth(WIRE_FRAME_SIZE);
154 paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0);
155 paint->setAntiAlias(true);
156 }
157
reed@google.combbe66f02013-10-30 13:41:19 +0000158 void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000159 void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
160 void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
161 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000162 this->setupSkeletonPaint(&paint);
163 SkPath path;
164
reed8716a8a2016-09-19 07:10:36 -0700165 fRectAsOval ? path.addOval(r) : path.addRect(r);
reed@google.comc83e3522012-10-22 22:00:08 +0000166 max->drawPath(path, paint);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000167 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000168
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000169 void copyMinToMax() {
reede8f30622016-03-23 18:59:25 -0700170 erase(fMaxSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000171 SkCanvas* canvas = fMaxSurface->getCanvas();
172 canvas->save();
173 canvas->concat(fMatrix);
Mike Reedb746b1f2021-01-06 08:43:51 -0500174 fMinSurface->draw(canvas, 0, 0);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000175 canvas->restore();
176
177 SkPaint paint;
reed374772b2016-10-05 17:33:02 -0700178 paint.setBlendMode(SkBlendMode::kClear);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000179 for (int iy = 1; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000180 SkScalar y = SkIntToScalar(iy * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000181 canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
182 }
183 for (int ix = 1; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000184 SkScalar x = SkIntToScalar(ix * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000185 canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
186 }
187 }
188};
189
190void FatBits::drawBG(SkCanvas* canvas) {
191 SkPaint paint;
192
193 paint.setShader(fShader);
194 canvas->drawRect(fBounds, paint);
halcanary96fcdcc2015-08-27 07:41:13 -0700195 paint.setShader(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000196}
197
198void FatBits::drawFG(SkCanvas* canvas) {
reed@google.comc83e3522012-10-22 22:00:08 +0000199 SkPaint inner, outer;
200
201 inner.setAntiAlias(true);
202 inner.setColor(SK_ColorBLACK);
203 inner.setStrokeWidth(PIXEL_CENTER_SIZE);
204
205 outer.setAntiAlias(true);
206 outer.setColor(SK_ColorWHITE);
207 outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000208
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000209 SkScalar half = SkIntToScalar(fZoom) / 2;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000210 for (int iy = 0; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000211 SkScalar y = SkIntToScalar(iy * fZoom) + half;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000212 for (int ix = 0; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000213 SkScalar x = SkIntToScalar(ix * fZoom) + half;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000214
reed@google.comc83e3522012-10-22 22:00:08 +0000215 canvas->drawPoint(x, y, outer);
216 canvas->drawPoint(x, y, inner);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000217 }
218 }
reed@google.com9c0bef12012-11-02 19:59:18 +0000219
220 if (fUseClip) {
221 SkPaint p;
222 p.setStyle(SkPaint::kStroke_Style);
223 p.setColor(SK_ColorLTGRAY);
224 SkRect r = {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000225 fClipRect.fLeft * fZoom,
226 fClipRect.fTop * fZoom,
227 fClipRect.fRight * fZoom,
228 fClipRect.fBottom * fZoom
reed@google.com9c0bef12012-11-02 19:59:18 +0000229 };
230 canvas->drawRect(r, p);
231 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000232}
233
234void FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
235 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000236 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000237
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000238 SkPath path;
239 path.moveTo(pts[0]);
240 path.lineTo(pts[1]);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000241
reed8716a8a2016-09-19 07:10:36 -0700242 if (fStyle == kStroke_Style) {
243 SkPaint p;
244 p.setStyle(SkPaint::kStroke_Style);
Mike Reedce54bce2017-11-01 21:17:11 -0400245 p.setStrokeWidth(fStrokeWidth * fZoom);
reed8716a8a2016-09-19 07:10:36 -0700246 p.setStrokeCap(fStrokeCap);
247 SkPath dst;
248 p.getFillPath(path, &dst);
249 path = dst;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000250
reed8716a8a2016-09-19 07:10:36 -0700251 path.moveTo(pts[0]);
252 path.lineTo(pts[1]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000253 }
254 max->drawPath(path, paint);
255}
256
257void FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) {
258 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000259
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000260 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000261
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000262 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000263 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000264 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000265
reede8f30622016-03-23 18:59:25 -0700266 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000267 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000268 paint.setColor(FAT_PIXEL_COLOR);
reed@google.com9c0bef12012-11-02 19:59:18 +0000269 if (fUseClip) {
270 fMinSurface->getCanvas()->save();
271 SkRect r = fClipRect;
272 r.inset(SK_Scalar1/3, SK_Scalar1/3);
Michael Ludwig2f6e2f82021-08-03 13:08:50 -0400273 fMinSurface->getCanvas()->clipRect(r, SkClipOp::kIntersect, true);
reed@google.com9c0bef12012-11-02 19:59:18 +0000274 }
Hal Canary23e474c2017-05-15 13:35:35 -0400275 fMinSurface->getCanvas()->drawLine(pts[0], pts[1], paint);
reed@google.com9c0bef12012-11-02 19:59:18 +0000276 if (fUseClip) {
277 fMinSurface->getCanvas()->restore();
278 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000279 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000280
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000281 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000282
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000283 fMatrix.mapPoints(pts, 2);
284 this->drawLineSkeleton(max, pts);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000285
Mike Reedb746b1f2021-01-06 08:43:51 -0500286 fMaxSurface->draw(canvas, 0, 0);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000287}
288
289void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
290 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000291
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000292 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000293
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000294 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000295 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000296 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000297
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000298 SkRect r;
Mike Reed92b33352019-08-24 19:39:13 -0400299 r.setBounds(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000300
reede8f30622016-03-23 18:59:25 -0700301 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000302 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000303 paint.setColor(FAT_PIXEL_COLOR);
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000304 {
305 SkCanvas* c = fMinSurface->getCanvas();
306 fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint);
307 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000308 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000309
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000310 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000311
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000312 fMatrix.mapPoints(pts, 2);
Mike Reed92b33352019-08-24 19:39:13 -0400313 r.setBounds(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000314 this->drawRectSkeleton(max, r);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000315
Mike Reedb746b1f2021-01-06 08:43:51 -0500316 fMaxSurface->draw(canvas, 0, 0);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000317}
318
reed@google.combbe66f02013-10-30 13:41:19 +0000319void FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
320 SkPaint paint;
321 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000322
reed@google.combbe66f02013-10-30 13:41:19 +0000323 SkPath path;
324 path.moveTo(pts[0]);
325 path.lineTo(pts[1]);
326 path.lineTo(pts[2]);
327 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000328
reed@google.combbe66f02013-10-30 13:41:19 +0000329 max->drawPath(path, paint);
330}
331
332void FatBits::drawTriangle(SkCanvas* canvas, SkPoint pts[3]) {
333 SkPaint paint;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000334
reed@google.combbe66f02013-10-30 13:41:19 +0000335 fInverse.mapPoints(pts, 3);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000336
reed@google.combbe66f02013-10-30 13:41:19 +0000337 if (fGrid) {
338 apply_grid(pts, 3);
339 }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000340
reed@google.combbe66f02013-10-30 13:41:19 +0000341 SkPath path;
342 path.moveTo(pts[0]);
343 path.lineTo(pts[1]);
344 path.lineTo(pts[2]);
345 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000346
reede8f30622016-03-23 18:59:25 -0700347 erase(fMinSurface.get());
reed@google.combbe66f02013-10-30 13:41:19 +0000348 this->setupPaint(&paint);
349 paint.setColor(FAT_PIXEL_COLOR);
350 fMinSurface->getCanvas()->drawPath(path, paint);
351 this->copyMinToMax();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000352
reed@google.combbe66f02013-10-30 13:41:19 +0000353 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000354
reed@google.combbe66f02013-10-30 13:41:19 +0000355 fMatrix.mapPoints(pts, 3);
356 this->drawTriangleSkeleton(max, pts);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000357
Mike Reedb746b1f2021-01-06 08:43:51 -0500358 fMaxSurface->draw(canvas, 0, 0);
reed@google.combbe66f02013-10-30 13:41:19 +0000359}
360
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000361///////////////////////////////////////////////////////////////////////////////////////////////////
362
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400363class IndexClick : public Sample::Click {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000364 int fIndex;
365public:
Hal Canaryfcf63592019-07-12 11:32:43 -0400366 IndexClick(int index) : fIndex(index) {}
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000367
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400368 static int GetIndex(Sample::Click* click) {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000369 return ((IndexClick*)click)->fIndex;
370 }
371};
372
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400373class DrawLineView : public Sample {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000374 FatBits fFB;
reed@google.combbe66f02013-10-30 13:41:19 +0000375 SkPoint fPts[3];
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000376 bool fIsRect;
reed8716a8a2016-09-19 07:10:36 -0700377 int fZoom = 64;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000378public:
379 DrawLineView() {
reed8716a8a2016-09-19 07:10:36 -0700380 fFB.setWHZ(24*2, 16*2, fZoom);
reedbb886742015-08-15 07:42:31 -0700381 fPts[0].set(1, 1);
382 fPts[1].set(5, 4);
383 fPts[2].set(2, 6);
Mike Reed1f607332020-05-21 12:11:27 -0400384 SkMatrix::Scale(fZoom, fZoom).mapPoints(fPts, 3);
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000385 fIsRect = false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000386 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000387
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000388 void setStyle(FatBits::Style s) {
389 fFB.setStyle(s);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000390 }
391
392protected:
Hal Canary8a027312019-07-03 10:55:44 -0400393 SkString name() override { return SkString("FatBits"); }
394
Hal Canary6cc65e12019-07-03 15:53:04 -0400395 bool onChar(SkUnichar uni) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000396 switch (uni) {
reed@google.com9c0bef12012-11-02 19:59:18 +0000397 case 'c':
398 fFB.setUseClip(!fFB.getUseClip());
reed@google.com9c0bef12012-11-02 19:59:18 +0000399 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000400 case 'r':
401 fIsRect = !fIsRect;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000402 return true;
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000403 case 'o':
404 fFB.toggleRectAsOval();
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000405 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000406 case 'x':
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000407 fFB.setGrid(!fFB.getGrid());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000408 return true;
409 case 's':
410 if (FatBits::kStroke_Style == fFB.getStyle()) {
411 this->setStyle(FatBits::kHair_Style);
412 } else {
413 this->setStyle(FatBits::kStroke_Style);
414 }
415 return true;
reeda5d12072015-11-16 18:57:18 -0800416 case 'k': {
417 const SkPaint::Cap caps[] = {
418 SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap,
419 };
420 fFB.fStrokeCap = caps[(fFB.fStrokeCap + 1) % 3];
reeda5d12072015-11-16 18:57:18 -0800421 return true;
422 } break;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000423 case 'a':
424 fFB.setAA(!fFB.getAA());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000425 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000426 case 'w':
427 fFB.setShowSkeleton(!fFB.getShowSkeleton());
reed@google.comc83e3522012-10-22 22:00:08 +0000428 return true;
429 case 'g':
reed8716a8a2016-09-19 07:10:36 -0700430 fFB.togglePixelColors();
reed@google.comc83e3522012-10-22 22:00:08 +0000431 return true;
reed@google.combbe66f02013-10-30 13:41:19 +0000432 case 't':
433 fFB.setTriangle(!fFB.getTriangle());
reed@google.combbe66f02013-10-30 13:41:19 +0000434 return true;
Mike Reedce54bce2017-11-01 21:17:11 -0400435 case '-':
436 fFB.fStrokeWidth -= 0.125f;
Mike Reedce54bce2017-11-01 21:17:11 -0400437 return true;
438 case '=':
439 fFB.fStrokeWidth += 0.125f;
Mike Reedce54bce2017-11-01 21:17:11 -0400440 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000441 }
Hal Canary6cc65e12019-07-03 15:53:04 -0400442 return false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000443 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000444
mtkleinf0599002015-07-13 06:18:39 -0700445 void onDrawContent(SkCanvas* canvas) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000446 fFB.drawBG(canvas);
reed@google.combbe66f02013-10-30 13:41:19 +0000447 if (fFB.getTriangle()) {
448 fFB.drawTriangle(canvas, fPts);
449 }
450 else if (fIsRect) {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000451 fFB.drawRect(canvas, fPts);
452 } else {
453 fFB.drawLine(canvas, fPts);
454 }
455 fFB.drawFG(canvas);
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000456
reed@google.comffe9d012012-10-23 15:33:41 +0000457 {
458 SkString str;
reed8716a8a2016-09-19 07:10:36 -0700459 str.printf("%s %s %s",
reed@google.comffe9d012012-10-23 15:33:41 +0000460 fFB.getAA() ? "AA" : "BW",
461 FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
reed@google.com9c0bef12012-11-02 19:59:18 +0000462 fFB.getUseClip() ? "clip" : "noclip");
reed@google.comffe9d012012-10-23 15:33:41 +0000463 SkPaint paint;
reed@google.comffe9d012012-10-23 15:33:41 +0000464 paint.setColor(SK_ColorBLUE);
Hal Canary4484b8f2019-01-08 14:00:08 -0500465 SkFont font(nullptr, 16);
466 canvas->drawString(str, 10, 16, font, paint);
reed@google.comffe9d012012-10-23 15:33:41 +0000467 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000468 }
469
Hal Canaryb1f411a2019-08-29 10:39:22 -0400470 Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000471 SkPoint pt = { x, y };
472 int index = -1;
reed@google.combbe66f02013-10-30 13:41:19 +0000473 int count = fFB.getTriangle() ? 3 : 2;
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000474 SkScalar tol = 12;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000475
reed@google.combbe66f02013-10-30 13:41:19 +0000476 for (int i = 0; i < count; ++i) {
Cary Clarkdf429f32017-11-08 11:44:31 -0500477 if (SkPointPriv::EqualsWithinTolerance(fPts[i], pt, tol)) {
reed@google.combbe66f02013-10-30 13:41:19 +0000478 index = i;
479 break;
480 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000481 }
Hal Canaryfcf63592019-07-12 11:32:43 -0400482 return new IndexClick(index);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000483 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000484
mtklein36352bf2015-03-25 18:17:31 -0700485 bool onClick(Click* click) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000486 int index = IndexClick::GetIndex(click);
reed@google.combbe66f02013-10-30 13:41:19 +0000487 if (index >= 0 && index <= 2) {
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000488 fPts[index] = click->fCurr;
489 } else {
490 SkScalar dx = click->fCurr.fX - click->fPrev.fX;
491 SkScalar dy = click->fCurr.fY - click->fPrev.fY;
492 fPts[0].offset(dx, dy);
493 fPts[1].offset(dx, dy);
reed@google.combbe66f02013-10-30 13:41:19 +0000494 fPts[2].offset(dx, dy);
mike@reedtribe.orgc892a152012-10-23 03:10:46 +0000495 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000496 return true;
497 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000498
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000499private:
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000500
John Stiles7571f9e2020-09-02 22:42:33 -0400501 using INHERITED = Sample;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000502};
503
504//////////////////////////////////////////////////////////////////////////////
505
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400506DEF_SAMPLE( return new DrawLineView(); )