Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
FatBitsSlide.cpp
Go to the documentation of this file.
1/*
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
11#include "include/core/SkFont.h"
15#include "include/core/SkPath.h"
18#include "include/core/SkRect.h"
26#include "tools/ToolUtils.h"
29#include "tools/viewer/Slide.h"
30
31#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
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
47static void erase(SkSurface* surface) {
48 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
49}
50
51class FatBits {
52public:
54 fAA = false;
55 fStyle = kHair_Style;
56 fGrid = false;
57 fShowSkeleton = true;
58 fUseClip = false;
59 fRectAsOval = false;
60 fUseTriangle = false;
62
63 fClipRect.setLTRB(2, 2, 11, 8);
64 }
65
66 int getZoom() const { return fZoom; }
67
68 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; }
73
74 bool getShowSkeleton() const { return fShowSkeleton; }
75 void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
76
77 bool getTriangle() const { return fUseTriangle; }
78 void setTriangle(bool ut) { fUseTriangle = ut; }
79
80 void toggleRectAsOval() { fRectAsOval = !fRectAsOval; }
81
83 if (fShader == fShader0) {
84 fShader = fShader1;
85 } else {
86 fShader = fShader0;
87 }
88 }
89
90 float fStrokeWidth = 1;
91
92 bool getUseClip() const { return fUseClip; }
93 void setUseClip(bool uc) { fUseClip = uc; }
94
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;
105 fZoom = zoom;
106 fBounds.setIWH(width * zoom, height * zoom);
107 fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
108 fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
109 fShader0 = ToolUtils::create_checkerboard_shader(0xFFDDDDDD, 0xFFFFFFFF, zoom);
110 fShader1 = SkShaders::Color(SK_ColorWHITE);
111 fShader = fShader0;
112
114 fMinSurface = SkSurfaces::Raster(info);
115 info = info.makeWH(width * zoom, height * zoom);
116 fMaxSurface = SkSurfaces::Raster(info);
117 }
118
119 void drawBG(SkCanvas*);
120 void drawFG(SkCanvas*);
121 void drawLine(SkCanvas*, SkPoint pts[2]);
122 void drawRect(SkCanvas* canvas, SkPoint pts[2]);
123 void drawTriangle(SkCanvas* canvas, SkPoint pts[3]);
124
126
127private:
128 bool fAA, fGrid, fShowSkeleton, fUseClip, fRectAsOval, fUseTriangle;
129 Style fStyle;
130 int fW, fH, fZoom;
131 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;
138
139 void setupPaint(SkPaint* paint) {
140 bool aa = this->getAA();
141 paint->setStrokeCap(fStrokeCap);
142 switch (fStyle) {
143 case kHair_Style:
144 paint->setStrokeWidth(0);
145 break;
146 case kStroke_Style:
147 paint->setStrokeWidth(fStrokeWidth);
148 break;
149 }
150 paint->setAntiAlias(aa);
151 }
152
153 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
160 void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]);
161 void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
162 void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
164 this->setupSkeletonPaint(&paint);
165 SkPath path;
166
167 fRectAsOval ? path.addOval(r) : path.addRect(r);
168 max->drawPath(path, paint);
169 }
170
171 void copyMinToMax() {
172 erase(fMaxSurface.get());
173 SkCanvas* canvas = fMaxSurface->getCanvas();
174 canvas->save();
175 canvas->concat(fMatrix);
176 fMinSurface->draw(canvas, 0, 0);
177 canvas->restore();
178
180 paint.setBlendMode(SkBlendMode::kClear);
181 for (int iy = 1; iy < fH; ++iy) {
182 SkScalar y = SkIntToScalar(iy * fZoom);
183 canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
184 }
185 for (int ix = 1; ix < fW; ++ix) {
186 SkScalar x = SkIntToScalar(ix * fZoom);
187 canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
188 }
189 }
190};
191
194
195 paint.setShader(fShader);
196 canvas->drawRect(fBounds, paint);
197 paint.setShader(nullptr);
198}
199
201 SkPaint inner, outer;
202
203 inner.setAntiAlias(true);
204 inner.setColor(SK_ColorBLACK);
206
207 outer.setAntiAlias(true);
208 outer.setColor(SK_ColorWHITE);
210
211 SkScalar half = SkIntToScalar(fZoom) / 2;
212 for (int iy = 0; iy < fH; ++iy) {
213 SkScalar y = SkIntToScalar(iy * fZoom) + half;
214 for (int ix = 0; ix < fW; ++ix) {
215 SkScalar x = SkIntToScalar(ix * fZoom) + half;
216
217 canvas->drawPoint(x, y, outer);
218 canvas->drawPoint(x, y, inner);
219 }
220 }
221
222 if (fUseClip) {
223 SkPaint p;
224 p.setStyle(SkPaint::kStroke_Style);
225 p.setColor(SK_ColorLTGRAY);
226 SkRect r = {
227 fClipRect.fLeft * fZoom,
228 fClipRect.fTop * fZoom,
229 fClipRect.fRight * fZoom,
230 fClipRect.fBottom * fZoom
231 };
232 canvas->drawRect(r, p);
233 }
234}
235
236void FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
238 this->setupSkeletonPaint(&paint);
239
240 SkPath path;
241 path.moveTo(pts[0]);
242 path.lineTo(pts[1]);
243
244 if (fStyle == kStroke_Style) {
245 SkPaint p;
246 p.setStyle(SkPaint::kStroke_Style);
247 p.setStrokeWidth(fStrokeWidth * fZoom);
248 p.setStrokeCap(fStrokeCap);
249 SkPath dst;
250 skpathutils::FillPathWithPaint(path, p, &dst);
251 path = dst;
252
253 path.moveTo(pts[0]);
254 path.lineTo(pts[1]);
255 }
256 max->drawPath(path, paint);
257}
258
259void FatBits::drawLine(SkCanvas* canvas, SkPoint pts[2]) {
261
262 fInverse.mapPoints(pts, 2);
263
264 if (fGrid) {
265 apply_grid(pts, 2);
266 }
267
268 erase(fMinSurface.get());
269 this->setupPaint(&paint);
270 paint.setColor(FAT_PIXEL_COLOR);
271 if (fUseClip) {
272 fMinSurface->getCanvas()->save();
273 SkRect r = fClipRect;
275 fMinSurface->getCanvas()->clipRect(r, SkClipOp::kIntersect, true);
276 }
277 fMinSurface->getCanvas()->drawLine(pts[0], pts[1], paint);
278 if (fUseClip) {
279 fMinSurface->getCanvas()->restore();
280 }
281 this->copyMinToMax();
282
283 SkCanvas* max = fMaxSurface->getCanvas();
284
285 fMatrix.mapPoints(pts, 2);
286 this->drawLineSkeleton(max, pts);
287
288 fMaxSurface->draw(canvas, 0, 0);
289}
290
291void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
293
294 fInverse.mapPoints(pts, 2);
295
296 if (fGrid) {
297 apply_grid(pts, 2);
298 }
299
300 SkRect r;
301 r.setBounds(pts, 2);
302
303 erase(fMinSurface.get());
304 this->setupPaint(&paint);
305 paint.setColor(FAT_PIXEL_COLOR);
306 {
307 SkCanvas* c = fMinSurface->getCanvas();
308 fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint);
309 }
310 this->copyMinToMax();
311
312 SkCanvas* max = fMaxSurface->getCanvas();
313
314 fMatrix.mapPoints(pts, 2);
315 r.setBounds(pts, 2);
316 this->drawRectSkeleton(max, r);
317
318 fMaxSurface->draw(canvas, 0, 0);
319}
320
321void FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
323 this->setupSkeletonPaint(&paint);
324
325 SkPath path;
326 path.moveTo(pts[0]);
327 path.lineTo(pts[1]);
328 path.lineTo(pts[2]);
329 path.close();
330
331 max->drawPath(path, paint);
332}
333
336
337 fInverse.mapPoints(pts, 3);
338
339 if (fGrid) {
340 apply_grid(pts, 3);
341 }
342
343 SkPath path;
344 path.moveTo(pts[0]);
345 path.lineTo(pts[1]);
346 path.lineTo(pts[2]);
347 path.close();
348
349 erase(fMinSurface.get());
350 this->setupPaint(&paint);
351 paint.setColor(FAT_PIXEL_COLOR);
352 fMinSurface->getCanvas()->drawPath(path, paint);
353 this->copyMinToMax();
354
355 SkCanvas* max = fMaxSurface->getCanvas();
356
357 fMatrix.mapPoints(pts, 3);
358 this->drawTriangleSkeleton(max, pts);
359
360 fMaxSurface->draw(canvas, 0, 0);
361}
362
363///////////////////////////////////////////////////////////////////////////////////////////////////
364
366 int fIndex;
367
368public:
369 IndexClick(int index) : fIndex(index) {}
370
371 static int GetIndex(Click* click) { return ((IndexClick*)click)->fIndex; }
372};
373
375 FatBits fFB;
376 SkPoint fPts[3];
377 bool fIsRect;
378 int fZoom = 64;
379
380public:
382 fFB.setWHZ(24*2, 16*2, fZoom);
383 fPts[0].set(1, 1);
384 fPts[1].set(5, 4);
385 fPts[2].set(2, 6);
386 SkMatrix::Scale(fZoom, fZoom).mapPoints(fPts, 3);
387 fIsRect = false;
388 fName = "FatBits";
389 }
390
392
393 bool onChar(SkUnichar uni) override {
394 switch (uni) {
395 case 'c':
396 fFB.setUseClip(!fFB.getUseClip());
397 return true;
398 case 'r':
399 fIsRect = !fIsRect;
400 return true;
401 case 'o':
402 fFB.toggleRectAsOval();
403 return true;
404 case 'x':
405 fFB.setGrid(!fFB.getGrid());
406 return true;
407 case 's':
408 if (FatBits::kStroke_Style == fFB.getStyle()) {
410 } else {
412 }
413 return true;
414 case 'k': {
415 const SkPaint::Cap caps[] = {
417 };
418 fFB.fStrokeCap = caps[(fFB.fStrokeCap + 1) % 3];
419 return true;
420 }
421 case 'a':
422 fFB.setAA(!fFB.getAA());
423 return true;
424 case 'w':
426 return true;
427 case 'g':
428 fFB.togglePixelColors();
429 return true;
430 case 't':
431 fFB.setTriangle(!fFB.getTriangle());
432 return true;
433 case '-':
434 fFB.fStrokeWidth -= 0.125f;
435 return true;
436 case '=':
437 fFB.fStrokeWidth += 0.125f;
438 return true;
439 }
440 return false;
441 }
442
443 void draw(SkCanvas* canvas) override {
444 fFB.drawBG(canvas);
445 if (fFB.getTriangle()) {
446 fFB.drawTriangle(canvas, fPts);
447 } else if (fIsRect) {
448 fFB.drawRect(canvas, fPts);
449 } else {
450 fFB.drawLine(canvas, fPts);
451 }
452 fFB.drawFG(canvas);
453
454 {
455 SkString str;
456 str.printf("%s %s %s",
457 fFB.getAA() ? "AA" : "BW",
458 FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
459 fFB.getUseClip() ? "clip" : "noclip");
461 paint.setColor(SK_ColorBLUE);
463 canvas->drawString(str, 10, 16, font, paint);
464 }
465 }
466
467protected:
469 SkPoint pt = { x, y };
470 int index = -1;
471 int count = fFB.getTriangle() ? 3 : 2;
472 SkScalar tol = 12;
473
474 for (int i = 0; i < count; ++i) {
475 if (SkPointPriv::EqualsWithinTolerance(fPts[i], pt, tol)) {
476 index = i;
477 break;
478 }
479 }
480 return new IndexClick(index);
481 }
482
483 bool onClick(Click* click) override {
484 int index = IndexClick::GetIndex(click);
485 if (index >= 0 && index <= 2) {
486 fPts[index] = click->fCurr;
487 } else {
488 SkScalar dx = click->fCurr.fX - click->fPrev.fX;
489 SkScalar dy = click->fCurr.fY - click->fPrev.fY;
490 fPts[0].offset(dx, dy);
491 fPts[1].offset(dx, dy);
492 fPts[2].offset(dx, dy);
493 }
494 return true;
495 }
496};
497
498//////////////////////////////////////////////////////////////////////////////
499
500DEF_SLIDE(return new DrawLineSlide();)
SkPoint fPts[2]
SkStrokeRec::Style fStyle
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
#define WIRE_FRAME_COLOR
#define FAT_PIXEL_COLOR
static SkScalar apply_grid(SkScalar x)
#define WIRE_FRAME_SIZE
static void erase(SkSurface *surface)
#define PIXEL_CENTER_SIZE
int count
const SkRect fBounds
@ kClear
r = 0
constexpr SkColor SK_ColorLTGRAY
Definition SkColor.h:118
constexpr SkColor SK_ColorTRANSPARENT
Definition SkColor.h:99
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
#define SK_Scalar1
Definition SkScalar.h:18
#define SK_ScalarHalf
Definition SkScalar.h:19
#define SkIntToScalar(x)
Definition SkScalar.h:57
#define SkScalarRoundToScalar(x)
Definition SkScalar.h:32
int32_t SkUnichar
Definition SkTypes.h:175
#define DEF_SLIDE(code)
Definition Slide.h:25
void setStyle(FatBits::Style s)
Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override
bool onChar(SkUnichar uni) override
bool onClick(Click *click) override
void draw(SkCanvas *canvas) override
void drawLine(SkCanvas *, SkPoint pts[2])
void setGrid(bool g)
void setTriangle(bool ut)
bool getAA() const
bool getUseClip() const
void setWHZ(int width, int height, int zoom)
void setShowSkeleton(bool ss)
void setAA(bool aa)
void togglePixelColors()
void drawTriangle(SkCanvas *canvas, SkPoint pts[3])
void toggleRectAsOval()
void setUseClip(bool uc)
SkPaint::Cap fStrokeCap
void drawRect(SkCanvas *canvas, SkPoint pts[2])
void drawBG(SkCanvas *)
float fStrokeWidth
void setStyle(Style s)
int getZoom() const
bool getTriangle() const
bool getShowSkeleton() const
Style getStyle() const
void drawFG(SkCanvas *)
bool getGrid() const
static int GetIndex(Click *click)
IndexClick(int index)
void drawRect(const SkRect &rect, const SkPaint &paint)
void drawOval(const SkRect &oval, const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void drawPoint(SkScalar x, SkScalar y, const SkPaint &paint)
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
int save()
Definition SkCanvas.cpp:451
void concat(const SkMatrix &matrix)
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition SkCanvas.h:1803
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:296
@ kRound_Cap
adds circle
Definition SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition SkPaint.h:334
@ kSquare_Cap
adds square
Definition SkPaint.h:336
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition SkPaint.h:170
void setStrokeCap(Cap cap)
Definition SkPaint.cpp:179
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
void setStrokeWidth(SkScalar width)
Definition SkPaint.cpp:159
static bool EqualsWithinTolerance(const SkPoint &p1, const SkPoint &p2)
Definition SkPointPriv.h:54
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:534
SkString fName
Definition Slide.h:54
T * get() const
Definition SkRefCnt.h:303
const Paint & paint
VkSurfaceKHR surface
Definition main.cc:49
float SkScalar
Definition extension.cpp:12
struct MyStruct s
static float max(float r, float g, float b)
Definition hsl.cpp:49
double y
double x
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
sk_sp< SkShader > create_checkerboard_shader(SkColor c1, SkColor c2, int size)
sk_sp< SkTypeface > DefaultTypeface()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
ModifierKey
Definition ModifierKey.h:9
int32_t height
int32_t width
static SkImageInfo MakeN32Premul(int width, int height)
float fX
x-axis value
void offset(float dx, float dy)
void set(float x, float y)
float fY
y-axis value
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
void inset(float dx, float dy)
Definition SkRect.h:1060
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
void setIWH(int32_t width, int32_t height)
Definition SkRect.h:950
void setLTRB(float left, float top, float right, float bottom)
Definition SkRect.h:865
void setBounds(const SkPoint pts[], int count)
Definition SkRect.h:881
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15