blob: dd588816a06e74168cb6cd49a7102fbf272644a2 [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
halcanaryb0cce2c2015-01-26 12:49:00 -08008#include "sk_tool_utils.h"
mike@reedtribe.org50e4c722012-10-22 03:59:34 +00009#include "SampleCode.h"
10#include "SkView.h"
11#include "SkCanvas.h"
12#include "SkPath.h"
13#include "SkRegion.h"
14#include "SkShader.h"
15#include "SkUtils.h"
16#include "SkImage.h"
17#include "SkSurface.h"
18
reed@google.comc83e3522012-10-22 22:00:08 +000019#define FAT_PIXEL_COLOR SK_ColorBLACK
20#define PIXEL_CENTER_SIZE 3
21#define WIRE_FRAME_COLOR 0xFFFF0000 /*0xFF00FFFF*/
22#define WIRE_FRAME_SIZE 1.5f
23
reed@google.combbe66f02013-10-30 13:41:19 +000024static SkScalar apply_grid(SkScalar x) {
25 const SkScalar grid = 2;
26 return SkScalarRoundToScalar(x * grid) / grid;
27}
28
29static void apply_grid(SkPoint pts[], int count) {
30 for (int i = 0; i < count; ++i) {
31 pts[i].set(apply_grid(pts[i].fX), apply_grid(pts[i].fY));
32 }
33}
34
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000035static void erase(SkSurface* surface) {
junov@google.comdbfac8a2012-12-06 21:47:40 +000036 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000037}
38
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000039class FatBits {
40public:
commit-bot@chromium.org5970f622014-05-12 20:42:21 +000041 FatBits() {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000042 fAA = false;
43 fStyle = kHair_Style;
reedbb886742015-08-15 07:42:31 -070044 fGrid = false;
reed@google.comc83e3522012-10-22 22:00:08 +000045 fShowSkeleton = true;
46 fUseGPU = false;
reed@google.com9c0bef12012-11-02 19:59:18 +000047 fUseClip = false;
mike@reedtribe.org64494e92013-03-06 02:18:33 +000048 fRectAsOval = false;
reed@google.combbe66f02013-10-30 13:41:19 +000049 fUseTriangle = false;
reeda5d12072015-11-16 18:57:18 -080050 fStrokeCap = SkPaint::kButt_Cap;
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +000051
reed@google.com9c0bef12012-11-02 19:59:18 +000052 fClipRect.set(2, 2, 11, 8 );
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000053 }
54
robertphillips@google.comca47aae2012-12-12 15:58:25 +000055 int getZoom() const { return fZoom; }
reed@google.comc83e3522012-10-22 22:00:08 +000056
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000057 bool getAA() const { return fAA; }
58 void setAA(bool aa) { fAA = aa; }
59
60 bool getGrid() const { return fGrid; }
61 void setGrid(bool g) { fGrid = g; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000062
reed@google.comc83e3522012-10-22 22:00:08 +000063 bool getShowSkeleton() const { return fShowSkeleton; }
64 void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000065
reed@google.comc83e3522012-10-22 22:00:08 +000066 bool getUseGPU() const { return fUseGPU; }
67 void setUseGPU(bool ug) { fUseGPU = ug; }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +000068
reed@google.combbe66f02013-10-30 13:41:19 +000069 bool getTriangle() const { return fUseTriangle; }
70 void setTriangle(bool ut) { fUseTriangle = ut; }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +000071
mike@reedtribe.org64494e92013-03-06 02:18:33 +000072 void toggleRectAsOval() { fRectAsOval = !fRectAsOval; }
73
reed@google.com9c0bef12012-11-02 19:59:18 +000074 bool getUseClip() const { return fUseClip; }
75 void setUseClip(bool uc) { fUseClip = uc; }
76
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000077 enum Style {
78 kHair_Style,
reed@google.comc83e3522012-10-22 22:00:08 +000079 kStroke_Style,
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000080 };
81 Style getStyle() const { return fStyle; }
82 void setStyle(Style s) { fStyle = s; }
83
84 void setWHZ(int width, int height, int zoom) {
85 fW = width;
86 fH = height;
robertphillips@google.comca47aae2012-12-12 15:58:25 +000087 fZoom = zoom;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000088 fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom));
89 fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
90 fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
reed8a21c9f2016-03-08 18:50:00 -080091 fShader = sk_tool_utils::create_checkerboard_shader(0xFFCCCCCC, 0xFFFFFFFF, zoom);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +000092
commit-bot@chromium.org32678d92014-01-15 02:38:22 +000093 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -070094 fMinSurface = SkSurface::MakeRaster(info);
reede5ea5002014-09-03 11:54:58 -070095 info = info.makeWH(width * zoom, height * zoom);
reede8f30622016-03-23 18:59:25 -070096 fMaxSurface = SkSurface::MakeRaster(info);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +000097 }
98
99 void drawBG(SkCanvas*);
100 void drawFG(SkCanvas*);
101 void drawLine(SkCanvas*, SkPoint pts[2]);
102 void drawRect(SkCanvas* canvas, SkPoint pts[2]);
reed@google.combbe66f02013-10-30 13:41:19 +0000103 void drawTriangle(SkCanvas* canvas, SkPoint pts[3]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000104
reeda5d12072015-11-16 18:57:18 -0800105 SkPaint::Cap fStrokeCap;
106
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000107private:
reed@google.combbe66f02013-10-30 13:41:19 +0000108 bool fAA, fGrid, fShowSkeleton, fUseGPU, fUseClip, fRectAsOval, fUseTriangle;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000109 Style fStyle;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000110 int fW, fH, fZoom;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000111 SkMatrix fMatrix, fInverse;
reed@google.com9c0bef12012-11-02 19:59:18 +0000112 SkRect fBounds, fClipRect;
reed8a21c9f2016-03-08 18:50:00 -0800113 sk_sp<SkShader> fShader;
reede8f30622016-03-23 18:59:25 -0700114 sk_sp<SkSurface> fMinSurface;
115 sk_sp<SkSurface> fMaxSurface;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000116
117 void setupPaint(SkPaint* paint) {
118 bool aa = this->getAA();
reeda5d12072015-11-16 18:57:18 -0800119 paint->setStrokeCap(fStrokeCap);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000120 switch (fStyle) {
121 case kHair_Style:
122 paint->setStrokeWidth(0);
123 break;
124 case kStroke_Style:
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000125 paint->setStrokeWidth(SK_Scalar1);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000126 break;
127 }
128 paint->setAntiAlias(aa);
129 }
130
reed@google.comc83e3522012-10-22 22:00:08 +0000131 void setupSkeletonPaint(SkPaint* paint) {
132 paint->setStyle(SkPaint::kStroke_Style);
133 paint->setStrokeWidth(WIRE_FRAME_SIZE);
134 paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0);
135 paint->setAntiAlias(true);
136 }
137
reed@google.combbe66f02013-10-30 13:41:19 +0000138 void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000139 void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
140 void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
141 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000142 this->setupSkeletonPaint(&paint);
143 SkPath path;
144
145 if (fUseGPU && fAA) {
146 SkRect rr = r;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000147 rr.inset(SkIntToScalar(fZoom)/2, SkIntToScalar(fZoom)/2);
reed@google.comc83e3522012-10-22 22:00:08 +0000148 path.addRect(rr);
149 path.moveTo(rr.fLeft, rr.fTop);
150 path.lineTo(rr.fRight, rr.fBottom);
151 rr = r;
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000152 rr.inset(-SkIntToScalar(fZoom)/2, -SkIntToScalar(fZoom)/2);
reed@google.comc83e3522012-10-22 22:00:08 +0000153 path.addRect(rr);
154 } else {
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000155 fRectAsOval ? path.addOval(r) : path.addRect(r);
reed@google.comc83e3522012-10-22 22:00:08 +0000156 if (fUseGPU) {
157 path.moveTo(r.fLeft, r.fTop);
158 path.lineTo(r.fRight, r.fBottom);
159 }
160 }
161 max->drawPath(path, paint);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000162 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000163
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000164 void copyMinToMax() {
reede8f30622016-03-23 18:59:25 -0700165 erase(fMaxSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000166 SkCanvas* canvas = fMaxSurface->getCanvas();
167 canvas->save();
168 canvas->concat(fMatrix);
halcanary96fcdcc2015-08-27 07:41:13 -0700169 fMinSurface->draw(canvas, 0, 0, nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000170 canvas->restore();
171
172 SkPaint paint;
173 paint.setXfermodeMode(SkXfermode::kClear_Mode);
174 for (int iy = 1; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000175 SkScalar y = SkIntToScalar(iy * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000176 canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
177 }
178 for (int ix = 1; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000179 SkScalar x = SkIntToScalar(ix * fZoom);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000180 canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
181 }
182 }
183};
184
185void FatBits::drawBG(SkCanvas* canvas) {
186 SkPaint paint;
187
188 paint.setShader(fShader);
189 canvas->drawRect(fBounds, paint);
halcanary96fcdcc2015-08-27 07:41:13 -0700190 paint.setShader(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000191}
192
193void FatBits::drawFG(SkCanvas* canvas) {
reed@google.comc83e3522012-10-22 22:00:08 +0000194 SkPaint inner, outer;
195
196 inner.setAntiAlias(true);
197 inner.setColor(SK_ColorBLACK);
198 inner.setStrokeWidth(PIXEL_CENTER_SIZE);
199
200 outer.setAntiAlias(true);
201 outer.setColor(SK_ColorWHITE);
202 outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000203
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000204 SkScalar half = SkIntToScalar(fZoom) / 2;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000205 for (int iy = 0; iy < fH; ++iy) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000206 SkScalar y = SkIntToScalar(iy * fZoom) + half;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000207 for (int ix = 0; ix < fW; ++ix) {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000208 SkScalar x = SkIntToScalar(ix * fZoom) + half;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000209
reed@google.comc83e3522012-10-22 22:00:08 +0000210 canvas->drawPoint(x, y, outer);
211 canvas->drawPoint(x, y, inner);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000212 }
213 }
reed@google.com9c0bef12012-11-02 19:59:18 +0000214
215 if (fUseClip) {
216 SkPaint p;
217 p.setStyle(SkPaint::kStroke_Style);
218 p.setColor(SK_ColorLTGRAY);
219 SkRect r = {
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000220 fClipRect.fLeft * fZoom,
221 fClipRect.fTop * fZoom,
222 fClipRect.fRight * fZoom,
223 fClipRect.fBottom * fZoom
reed@google.com9c0bef12012-11-02 19:59:18 +0000224 };
225 canvas->drawRect(r, p);
226 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000227}
228
229void FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
230 SkPaint paint;
reed@google.comc83e3522012-10-22 22:00:08 +0000231 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000232
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000233 SkPath path;
234 path.moveTo(pts[0]);
235 path.lineTo(pts[1]);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000236
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000237 switch (fStyle) {
238 case kHair_Style:
reed@google.comc83e3522012-10-22 22:00:08 +0000239 if (fUseGPU) {
240 SkPaint p;
241 p.setStyle(SkPaint::kStroke_Style);
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000242 p.setStrokeWidth(SK_Scalar1 * fZoom);
reed@google.comc83e3522012-10-22 22:00:08 +0000243 SkPath dst;
244 p.getFillPath(path, &dst);
245 path.addPath(dst);
246 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000247 break;
248 case kStroke_Style: {
249 SkPaint p;
250 p.setStyle(SkPaint::kStroke_Style);
robertphillips@google.comca47aae2012-12-12 15:58:25 +0000251 p.setStrokeWidth(SK_Scalar1 * fZoom);
reeda5d12072015-11-16 18:57:18 -0800252 p.setStrokeCap(fStrokeCap);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000253 SkPath dst;
254 p.getFillPath(path, &dst);
255 path = dst;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000256
reeda5d12072015-11-16 18:57:18 -0800257 path.moveTo(pts[0]);
258 path.lineTo(pts[1]);
259
reed@google.comc83e3522012-10-22 22:00:08 +0000260 if (fUseGPU) {
261 path.moveTo(dst.getPoint(0));
262 path.lineTo(dst.getPoint(2));
263 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000264 } break;
265 }
266 max->drawPath(path, paint);
267}
268
269void FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) {
270 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000271
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000272 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000273
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000274 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000275 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000276 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000277
reede8f30622016-03-23 18:59:25 -0700278 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000279 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000280 paint.setColor(FAT_PIXEL_COLOR);
reed@google.com9c0bef12012-11-02 19:59:18 +0000281 if (fUseClip) {
282 fMinSurface->getCanvas()->save();
283 SkRect r = fClipRect;
284 r.inset(SK_Scalar1/3, SK_Scalar1/3);
285 fMinSurface->getCanvas()->clipRect(r, SkRegion::kIntersect_Op, true);
286 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000287 fMinSurface->getCanvas()->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
reed@google.com9c0bef12012-11-02 19:59:18 +0000288 if (fUseClip) {
289 fMinSurface->getCanvas()->restore();
290 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000291 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000292
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000293 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000294
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000295 fMatrix.mapPoints(pts, 2);
296 this->drawLineSkeleton(max, pts);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000297
halcanary96fcdcc2015-08-27 07:41:13 -0700298 fMaxSurface->draw(canvas, 0, 0, nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000299}
300
301void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
302 SkPaint paint;
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000303
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000304 fInverse.mapPoints(pts, 2);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000305
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000306 if (fGrid) {
reed@google.combbe66f02013-10-30 13:41:19 +0000307 apply_grid(pts, 2);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000308 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000309
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000310 SkRect r;
311 r.set(pts, 2);
312
reede8f30622016-03-23 18:59:25 -0700313 erase(fMinSurface.get());
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000314 this->setupPaint(&paint);
reed@google.comc83e3522012-10-22 22:00:08 +0000315 paint.setColor(FAT_PIXEL_COLOR);
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000316 {
317 SkCanvas* c = fMinSurface->getCanvas();
318 fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint);
319 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000320 this->copyMinToMax();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000321
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000322 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000323
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000324 fMatrix.mapPoints(pts, 2);
325 r.set(pts, 2);
326 this->drawRectSkeleton(max, r);
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000327
halcanary96fcdcc2015-08-27 07:41:13 -0700328 fMaxSurface->draw(canvas, 0, 0, nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000329}
330
reed@google.combbe66f02013-10-30 13:41:19 +0000331void FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
332 SkPaint paint;
333 this->setupSkeletonPaint(&paint);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000334
reed@google.combbe66f02013-10-30 13:41:19 +0000335 SkPath path;
336 path.moveTo(pts[0]);
337 path.lineTo(pts[1]);
338 path.lineTo(pts[2]);
339 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000340
reed@google.combbe66f02013-10-30 13:41:19 +0000341 max->drawPath(path, paint);
342}
343
344void FatBits::drawTriangle(SkCanvas* canvas, SkPoint pts[3]) {
345 SkPaint paint;
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000346
reed@google.combbe66f02013-10-30 13:41:19 +0000347 fInverse.mapPoints(pts, 3);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000348
reed@google.combbe66f02013-10-30 13:41:19 +0000349 if (fGrid) {
350 apply_grid(pts, 3);
351 }
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000352
reed@google.combbe66f02013-10-30 13:41:19 +0000353 SkPath path;
354 path.moveTo(pts[0]);
355 path.lineTo(pts[1]);
356 path.lineTo(pts[2]);
357 path.close();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000358
reede8f30622016-03-23 18:59:25 -0700359 erase(fMinSurface.get());
reed@google.combbe66f02013-10-30 13:41:19 +0000360 this->setupPaint(&paint);
361 paint.setColor(FAT_PIXEL_COLOR);
362 fMinSurface->getCanvas()->drawPath(path, paint);
363 this->copyMinToMax();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000364
reed@google.combbe66f02013-10-30 13:41:19 +0000365 SkCanvas* max = fMaxSurface->getCanvas();
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000366
reed@google.combbe66f02013-10-30 13:41:19 +0000367 fMatrix.mapPoints(pts, 3);
368 this->drawTriangleSkeleton(max, pts);
skia.committer@gmail.com7ed98df2013-10-31 07:01:53 +0000369
halcanary96fcdcc2015-08-27 07:41:13 -0700370 fMaxSurface->draw(canvas, 0, 0, nullptr);
reed@google.combbe66f02013-10-30 13:41:19 +0000371}
372
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000373///////////////////////////////////////////////////////////////////////////////////////////////////
374
375class IndexClick : public SkView::Click {
376 int fIndex;
377public:
378 IndexClick(SkView* v, int index) : SkView::Click(v), fIndex(index) {}
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000379
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000380 static int GetIndex(SkView::Click* click) {
381 return ((IndexClick*)click)->fIndex;
382 }
383};
384
385class DrawLineView : public SampleView {
reedbb886742015-08-15 07:42:31 -0700386 enum {
387 kZoom = 96
388 };
389
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000390 FatBits fFB;
reed@google.combbe66f02013-10-30 13:41:19 +0000391 SkPoint fPts[3];
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000392 bool fIsRect;
393public:
394 DrawLineView() {
reedbb886742015-08-15 07:42:31 -0700395 fFB.setWHZ(24, 16, kZoom);
396 fPts[0].set(1, 1);
397 fPts[1].set(5, 4);
398 fPts[2].set(2, 6);
399 SkMatrix::MakeScale(kZoom, kZoom).mapPoints(fPts, 3);
reed@google.comcdbcb3e2012-10-22 22:10:20 +0000400 fIsRect = false;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000401 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000402
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000403 void setStyle(FatBits::Style s) {
404 fFB.setStyle(s);
halcanary96fcdcc2015-08-27 07:41:13 -0700405 this->inval(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000406 }
407
408protected:
mtklein36352bf2015-03-25 18:17:31 -0700409 bool onQuery(SkEvent* evt) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000410 if (SampleCode::TitleQ(*evt)) {
411 SampleCode::TitleR(evt, "FatBits");
412 return true;
413 }
414 SkUnichar uni;
415 if (SampleCode::CharQ(*evt, &uni)) {
416 switch (uni) {
reed@google.com9c0bef12012-11-02 19:59:18 +0000417 case 'c':
418 fFB.setUseClip(!fFB.getUseClip());
halcanary96fcdcc2015-08-27 07:41:13 -0700419 this->inval(nullptr);
reed@google.com9c0bef12012-11-02 19:59:18 +0000420 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000421 case 'r':
422 fIsRect = !fIsRect;
halcanary96fcdcc2015-08-27 07:41:13 -0700423 this->inval(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000424 return true;
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000425 case 'o':
426 fFB.toggleRectAsOval();
halcanary96fcdcc2015-08-27 07:41:13 -0700427 this->inval(nullptr);
mike@reedtribe.org64494e92013-03-06 02:18:33 +0000428 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000429 case 'x':
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000430 fFB.setGrid(!fFB.getGrid());
halcanary96fcdcc2015-08-27 07:41:13 -0700431 this->inval(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000432 return true;
433 case 's':
434 if (FatBits::kStroke_Style == fFB.getStyle()) {
435 this->setStyle(FatBits::kHair_Style);
436 } else {
437 this->setStyle(FatBits::kStroke_Style);
438 }
439 return true;
reeda5d12072015-11-16 18:57:18 -0800440 case 'k': {
441 const SkPaint::Cap caps[] = {
442 SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap,
443 };
444 fFB.fStrokeCap = caps[(fFB.fStrokeCap + 1) % 3];
445 this->inval(nullptr);
446 return true;
447 } break;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000448 case 'a':
449 fFB.setAA(!fFB.getAA());
halcanary96fcdcc2015-08-27 07:41:13 -0700450 this->inval(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000451 return true;
reed@google.comc83e3522012-10-22 22:00:08 +0000452 case 'w':
453 fFB.setShowSkeleton(!fFB.getShowSkeleton());
halcanary96fcdcc2015-08-27 07:41:13 -0700454 this->inval(nullptr);
reed@google.comc83e3522012-10-22 22:00:08 +0000455 return true;
456 case 'g':
457 fFB.setUseGPU(!fFB.getUseGPU());
halcanary96fcdcc2015-08-27 07:41:13 -0700458 this->inval(nullptr);
reed@google.comc83e3522012-10-22 22:00:08 +0000459 return true;
reed@google.combbe66f02013-10-30 13:41:19 +0000460 case 't':
461 fFB.setTriangle(!fFB.getTriangle());
halcanary96fcdcc2015-08-27 07:41:13 -0700462 this->inval(nullptr);
reed@google.combbe66f02013-10-30 13:41:19 +0000463 return true;
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000464 }
465 }
466 return this->INHERITED::onQuery(evt);
467 }
skia.committer@gmail.com45ba2f72012-10-23 02:01:22 +0000468
mtkleinf0599002015-07-13 06:18:39 -0700469 void onDrawContent(SkCanvas* canvas) override {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000470 fFB.drawBG(canvas);
reed@google.combbe66f02013-10-30 13:41:19 +0000471 if (fFB.getTriangle()) {
472 fFB.drawTriangle(canvas, fPts);
473 }
474 else if (fIsRect) {
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000475 fFB.drawRect(canvas, fPts);
476 } else {
477 fFB.drawLine(canvas, fPts);
478 }
479 fFB.drawFG(canvas);
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000480
reed@google.comffe9d012012-10-23 15:33:41 +0000481 {
482 SkString str;
reed@google.com9c0bef12012-11-02 19:59:18 +0000483 str.printf("%s %s %s %s",
reed@google.comffe9d012012-10-23 15:33:41 +0000484 fFB.getAA() ? "AA" : "BW",
485 FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
reed@google.com9c0bef12012-11-02 19:59:18 +0000486 fFB.getUseGPU() ? "GPU" : "CPU",
487 fFB.getUseClip() ? "clip" : "noclip");
reed@google.comffe9d012012-10-23 15:33:41 +0000488 SkPaint paint;
489 paint.setAntiAlias(true);
490 paint.setTextSize(16);
491 paint.setColor(SK_ColorBLUE);
492 canvas->drawText(str.c_str(), str.size(), 10, 16, paint);
493 }
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000494 }
495
mtkleinf0599002015-07-13 06:18:39 -0700496 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) 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
mtklein36352bf2015-03-25 18:17:31 -0700511 bool onClick(Click* click) 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 }
halcanary96fcdcc2015-08-27 07:41:13 -0700522 this->inval(nullptr);
mike@reedtribe.org50e4c722012-10-22 03:59:34 +0000523 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);