1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkBlendMode.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkColor.h" 11cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h" 12cb93a386Sopenharmony_ci#include "include/core/SkMatrix.h" 13cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 14cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 15cb93a386Sopenharmony_ci#include "include/core/SkPoint.h" 16cb93a386Sopenharmony_ci#include "include/core/SkRect.h" 17cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h" 18cb93a386Sopenharmony_ci#include "include/core/SkScalar.h" 19cb93a386Sopenharmony_ci#include "include/core/SkShader.h" 20cb93a386Sopenharmony_ci#include "include/core/SkString.h" 21cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 22cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 23cb93a386Sopenharmony_ci#include "samplecode/Sample.h" 24cb93a386Sopenharmony_ci#include "src/core/SkPointPriv.h" 25cb93a386Sopenharmony_ci#include "tools/ToolUtils.h" 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ciclass SkEvent; 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci#define FAT_PIXEL_COLOR SK_ColorBLACK 30cb93a386Sopenharmony_ci#define PIXEL_CENTER_SIZE 3 31cb93a386Sopenharmony_ci#define WIRE_FRAME_COLOR 0xFFFF0000 /*0xFF00FFFF*/ 32cb93a386Sopenharmony_ci#define WIRE_FRAME_SIZE 1.5f 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_cistatic SkScalar apply_grid(SkScalar x) { 35cb93a386Sopenharmony_ci const SkScalar grid = 2; 36cb93a386Sopenharmony_ci return SkScalarRoundToScalar(x * grid) / grid; 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_cistatic void apply_grid(SkPoint pts[], int count) { 40cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 41cb93a386Sopenharmony_ci pts[i].set(apply_grid(pts[i].fX), apply_grid(pts[i].fY)); 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci} 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_cistatic void erase(SkSurface* surface) { 46cb93a386Sopenharmony_ci surface->getCanvas()->clear(SK_ColorTRANSPARENT); 47cb93a386Sopenharmony_ci} 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ciclass FatBits { 50cb93a386Sopenharmony_cipublic: 51cb93a386Sopenharmony_ci FatBits() { 52cb93a386Sopenharmony_ci fAA = false; 53cb93a386Sopenharmony_ci fStyle = kHair_Style; 54cb93a386Sopenharmony_ci fGrid = false; 55cb93a386Sopenharmony_ci fShowSkeleton = true; 56cb93a386Sopenharmony_ci fUseClip = false; 57cb93a386Sopenharmony_ci fRectAsOval = false; 58cb93a386Sopenharmony_ci fUseTriangle = false; 59cb93a386Sopenharmony_ci fStrokeCap = SkPaint::kButt_Cap; 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci fClipRect.setLTRB(2, 2, 11, 8 ); 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci int getZoom() const { return fZoom; } 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci bool getAA() const { return fAA; } 67cb93a386Sopenharmony_ci void setAA(bool aa) { fAA = aa; } 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci bool getGrid() const { return fGrid; } 70cb93a386Sopenharmony_ci void setGrid(bool g) { fGrid = g; } 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci bool getShowSkeleton() const { return fShowSkeleton; } 73cb93a386Sopenharmony_ci void setShowSkeleton(bool ss) { fShowSkeleton = ss; } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci bool getTriangle() const { return fUseTriangle; } 76cb93a386Sopenharmony_ci void setTriangle(bool ut) { fUseTriangle = ut; } 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci void toggleRectAsOval() { fRectAsOval = !fRectAsOval; } 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci void togglePixelColors() { 81cb93a386Sopenharmony_ci if (fShader == fShader0) { 82cb93a386Sopenharmony_ci fShader = fShader1; 83cb93a386Sopenharmony_ci } else { 84cb93a386Sopenharmony_ci fShader = fShader0; 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci float fStrokeWidth = 1; 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci bool getUseClip() const { return fUseClip; } 91cb93a386Sopenharmony_ci void setUseClip(bool uc) { fUseClip = uc; } 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci enum Style { 94cb93a386Sopenharmony_ci kHair_Style, 95cb93a386Sopenharmony_ci kStroke_Style, 96cb93a386Sopenharmony_ci }; 97cb93a386Sopenharmony_ci Style getStyle() const { return fStyle; } 98cb93a386Sopenharmony_ci void setStyle(Style s) { fStyle = s; } 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci void setWHZ(int width, int height, int zoom) { 101cb93a386Sopenharmony_ci fW = width; 102cb93a386Sopenharmony_ci fH = height; 103cb93a386Sopenharmony_ci fZoom = zoom; 104cb93a386Sopenharmony_ci fBounds.setIWH(width * zoom, height * zoom); 105cb93a386Sopenharmony_ci fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom)); 106cb93a386Sopenharmony_ci fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom); 107cb93a386Sopenharmony_ci fShader0 = ToolUtils::create_checkerboard_shader(0xFFDDDDDD, 0xFFFFFFFF, zoom); 108cb93a386Sopenharmony_ci fShader1 = SkShaders::Color(SK_ColorWHITE); 109cb93a386Sopenharmony_ci fShader = fShader0; 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 112cb93a386Sopenharmony_ci fMinSurface = SkSurface::MakeRaster(info); 113cb93a386Sopenharmony_ci info = info.makeWH(width * zoom, height * zoom); 114cb93a386Sopenharmony_ci fMaxSurface = SkSurface::MakeRaster(info); 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci void drawBG(SkCanvas*); 118cb93a386Sopenharmony_ci void drawFG(SkCanvas*); 119cb93a386Sopenharmony_ci void drawLine(SkCanvas*, SkPoint pts[2]); 120cb93a386Sopenharmony_ci void drawRect(SkCanvas* canvas, SkPoint pts[2]); 121cb93a386Sopenharmony_ci void drawTriangle(SkCanvas* canvas, SkPoint pts[3]); 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci SkPaint::Cap fStrokeCap; 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ciprivate: 126cb93a386Sopenharmony_ci bool fAA, fGrid, fShowSkeleton, fUseClip, fRectAsOval, fUseTriangle; 127cb93a386Sopenharmony_ci Style fStyle; 128cb93a386Sopenharmony_ci int fW, fH, fZoom; 129cb93a386Sopenharmony_ci SkMatrix fMatrix, fInverse; 130cb93a386Sopenharmony_ci SkRect fBounds, fClipRect; 131cb93a386Sopenharmony_ci sk_sp<SkShader> fShader0; 132cb93a386Sopenharmony_ci sk_sp<SkShader> fShader1; 133cb93a386Sopenharmony_ci sk_sp<SkShader> fShader; 134cb93a386Sopenharmony_ci sk_sp<SkSurface> fMinSurface; 135cb93a386Sopenharmony_ci sk_sp<SkSurface> fMaxSurface; 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci void setupPaint(SkPaint* paint) { 138cb93a386Sopenharmony_ci bool aa = this->getAA(); 139cb93a386Sopenharmony_ci paint->setStrokeCap(fStrokeCap); 140cb93a386Sopenharmony_ci switch (fStyle) { 141cb93a386Sopenharmony_ci case kHair_Style: 142cb93a386Sopenharmony_ci paint->setStrokeWidth(0); 143cb93a386Sopenharmony_ci break; 144cb93a386Sopenharmony_ci case kStroke_Style: 145cb93a386Sopenharmony_ci paint->setStrokeWidth(fStrokeWidth); 146cb93a386Sopenharmony_ci break; 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci paint->setAntiAlias(aa); 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_ci void setupSkeletonPaint(SkPaint* paint) { 152cb93a386Sopenharmony_ci paint->setStyle(SkPaint::kStroke_Style); 153cb93a386Sopenharmony_ci paint->setStrokeWidth(WIRE_FRAME_SIZE); 154cb93a386Sopenharmony_ci paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0); 155cb93a386Sopenharmony_ci paint->setAntiAlias(true); 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]); 159cb93a386Sopenharmony_ci void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]); 160cb93a386Sopenharmony_ci void drawRectSkeleton(SkCanvas* max, const SkRect& r) { 161cb93a386Sopenharmony_ci SkPaint paint; 162cb93a386Sopenharmony_ci this->setupSkeletonPaint(&paint); 163cb93a386Sopenharmony_ci SkPath path; 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci fRectAsOval ? path.addOval(r) : path.addRect(r); 166cb93a386Sopenharmony_ci max->drawPath(path, paint); 167cb93a386Sopenharmony_ci } 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci void copyMinToMax() { 170cb93a386Sopenharmony_ci erase(fMaxSurface.get()); 171cb93a386Sopenharmony_ci SkCanvas* canvas = fMaxSurface->getCanvas(); 172cb93a386Sopenharmony_ci canvas->save(); 173cb93a386Sopenharmony_ci canvas->concat(fMatrix); 174cb93a386Sopenharmony_ci fMinSurface->draw(canvas, 0, 0); 175cb93a386Sopenharmony_ci canvas->restore(); 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci SkPaint paint; 178cb93a386Sopenharmony_ci paint.setBlendMode(SkBlendMode::kClear); 179cb93a386Sopenharmony_ci for (int iy = 1; iy < fH; ++iy) { 180cb93a386Sopenharmony_ci SkScalar y = SkIntToScalar(iy * fZoom); 181cb93a386Sopenharmony_ci canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint); 182cb93a386Sopenharmony_ci } 183cb93a386Sopenharmony_ci for (int ix = 1; ix < fW; ++ix) { 184cb93a386Sopenharmony_ci SkScalar x = SkIntToScalar(ix * fZoom); 185cb93a386Sopenharmony_ci canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint); 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci } 188cb93a386Sopenharmony_ci}; 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_civoid FatBits::drawBG(SkCanvas* canvas) { 191cb93a386Sopenharmony_ci SkPaint paint; 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci paint.setShader(fShader); 194cb93a386Sopenharmony_ci canvas->drawRect(fBounds, paint); 195cb93a386Sopenharmony_ci paint.setShader(nullptr); 196cb93a386Sopenharmony_ci} 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_civoid FatBits::drawFG(SkCanvas* canvas) { 199cb93a386Sopenharmony_ci SkPaint inner, outer; 200cb93a386Sopenharmony_ci 201cb93a386Sopenharmony_ci inner.setAntiAlias(true); 202cb93a386Sopenharmony_ci inner.setColor(SK_ColorBLACK); 203cb93a386Sopenharmony_ci inner.setStrokeWidth(PIXEL_CENTER_SIZE); 204cb93a386Sopenharmony_ci 205cb93a386Sopenharmony_ci outer.setAntiAlias(true); 206cb93a386Sopenharmony_ci outer.setColor(SK_ColorWHITE); 207cb93a386Sopenharmony_ci outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2); 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci SkScalar half = SkIntToScalar(fZoom) / 2; 210cb93a386Sopenharmony_ci for (int iy = 0; iy < fH; ++iy) { 211cb93a386Sopenharmony_ci SkScalar y = SkIntToScalar(iy * fZoom) + half; 212cb93a386Sopenharmony_ci for (int ix = 0; ix < fW; ++ix) { 213cb93a386Sopenharmony_ci SkScalar x = SkIntToScalar(ix * fZoom) + half; 214cb93a386Sopenharmony_ci 215cb93a386Sopenharmony_ci canvas->drawPoint(x, y, outer); 216cb93a386Sopenharmony_ci canvas->drawPoint(x, y, inner); 217cb93a386Sopenharmony_ci } 218cb93a386Sopenharmony_ci } 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ci if (fUseClip) { 221cb93a386Sopenharmony_ci SkPaint p; 222cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 223cb93a386Sopenharmony_ci p.setColor(SK_ColorLTGRAY); 224cb93a386Sopenharmony_ci SkRect r = { 225cb93a386Sopenharmony_ci fClipRect.fLeft * fZoom, 226cb93a386Sopenharmony_ci fClipRect.fTop * fZoom, 227cb93a386Sopenharmony_ci fClipRect.fRight * fZoom, 228cb93a386Sopenharmony_ci fClipRect.fBottom * fZoom 229cb93a386Sopenharmony_ci }; 230cb93a386Sopenharmony_ci canvas->drawRect(r, p); 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci} 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_civoid FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) { 235cb93a386Sopenharmony_ci SkPaint paint; 236cb93a386Sopenharmony_ci this->setupSkeletonPaint(&paint); 237cb93a386Sopenharmony_ci 238cb93a386Sopenharmony_ci SkPath path; 239cb93a386Sopenharmony_ci path.moveTo(pts[0]); 240cb93a386Sopenharmony_ci path.lineTo(pts[1]); 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_ci if (fStyle == kStroke_Style) { 243cb93a386Sopenharmony_ci SkPaint p; 244cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 245cb93a386Sopenharmony_ci p.setStrokeWidth(fStrokeWidth * fZoom); 246cb93a386Sopenharmony_ci p.setStrokeCap(fStrokeCap); 247cb93a386Sopenharmony_ci SkPath dst; 248cb93a386Sopenharmony_ci p.getFillPath(path, &dst); 249cb93a386Sopenharmony_ci path = dst; 250cb93a386Sopenharmony_ci 251cb93a386Sopenharmony_ci path.moveTo(pts[0]); 252cb93a386Sopenharmony_ci path.lineTo(pts[1]); 253cb93a386Sopenharmony_ci } 254cb93a386Sopenharmony_ci max->drawPath(path, paint); 255cb93a386Sopenharmony_ci} 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_civoid FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) { 258cb93a386Sopenharmony_ci SkPaint paint; 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_ci fInverse.mapPoints(pts, 2); 261cb93a386Sopenharmony_ci 262cb93a386Sopenharmony_ci if (fGrid) { 263cb93a386Sopenharmony_ci apply_grid(pts, 2); 264cb93a386Sopenharmony_ci } 265cb93a386Sopenharmony_ci 266cb93a386Sopenharmony_ci erase(fMinSurface.get()); 267cb93a386Sopenharmony_ci this->setupPaint(&paint); 268cb93a386Sopenharmony_ci paint.setColor(FAT_PIXEL_COLOR); 269cb93a386Sopenharmony_ci if (fUseClip) { 270cb93a386Sopenharmony_ci fMinSurface->getCanvas()->save(); 271cb93a386Sopenharmony_ci SkRect r = fClipRect; 272cb93a386Sopenharmony_ci r.inset(SK_Scalar1/3, SK_Scalar1/3); 273cb93a386Sopenharmony_ci fMinSurface->getCanvas()->clipRect(r, SkClipOp::kIntersect, true); 274cb93a386Sopenharmony_ci } 275cb93a386Sopenharmony_ci fMinSurface->getCanvas()->drawLine(pts[0], pts[1], paint); 276cb93a386Sopenharmony_ci if (fUseClip) { 277cb93a386Sopenharmony_ci fMinSurface->getCanvas()->restore(); 278cb93a386Sopenharmony_ci } 279cb93a386Sopenharmony_ci this->copyMinToMax(); 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ci SkCanvas* max = fMaxSurface->getCanvas(); 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ci fMatrix.mapPoints(pts, 2); 284cb93a386Sopenharmony_ci this->drawLineSkeleton(max, pts); 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_ci fMaxSurface->draw(canvas, 0, 0); 287cb93a386Sopenharmony_ci} 288cb93a386Sopenharmony_ci 289cb93a386Sopenharmony_civoid FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) { 290cb93a386Sopenharmony_ci SkPaint paint; 291cb93a386Sopenharmony_ci 292cb93a386Sopenharmony_ci fInverse.mapPoints(pts, 2); 293cb93a386Sopenharmony_ci 294cb93a386Sopenharmony_ci if (fGrid) { 295cb93a386Sopenharmony_ci apply_grid(pts, 2); 296cb93a386Sopenharmony_ci } 297cb93a386Sopenharmony_ci 298cb93a386Sopenharmony_ci SkRect r; 299cb93a386Sopenharmony_ci r.setBounds(pts, 2); 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_ci erase(fMinSurface.get()); 302cb93a386Sopenharmony_ci this->setupPaint(&paint); 303cb93a386Sopenharmony_ci paint.setColor(FAT_PIXEL_COLOR); 304cb93a386Sopenharmony_ci { 305cb93a386Sopenharmony_ci SkCanvas* c = fMinSurface->getCanvas(); 306cb93a386Sopenharmony_ci fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint); 307cb93a386Sopenharmony_ci } 308cb93a386Sopenharmony_ci this->copyMinToMax(); 309cb93a386Sopenharmony_ci 310cb93a386Sopenharmony_ci SkCanvas* max = fMaxSurface->getCanvas(); 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_ci fMatrix.mapPoints(pts, 2); 313cb93a386Sopenharmony_ci r.setBounds(pts, 2); 314cb93a386Sopenharmony_ci this->drawRectSkeleton(max, r); 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_ci fMaxSurface->draw(canvas, 0, 0); 317cb93a386Sopenharmony_ci} 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_civoid FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) { 320cb93a386Sopenharmony_ci SkPaint paint; 321cb93a386Sopenharmony_ci this->setupSkeletonPaint(&paint); 322cb93a386Sopenharmony_ci 323cb93a386Sopenharmony_ci SkPath path; 324cb93a386Sopenharmony_ci path.moveTo(pts[0]); 325cb93a386Sopenharmony_ci path.lineTo(pts[1]); 326cb93a386Sopenharmony_ci path.lineTo(pts[2]); 327cb93a386Sopenharmony_ci path.close(); 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ci max->drawPath(path, paint); 330cb93a386Sopenharmony_ci} 331cb93a386Sopenharmony_ci 332cb93a386Sopenharmony_civoid FatBits::drawTriangle(SkCanvas* canvas, SkPoint pts[3]) { 333cb93a386Sopenharmony_ci SkPaint paint; 334cb93a386Sopenharmony_ci 335cb93a386Sopenharmony_ci fInverse.mapPoints(pts, 3); 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ci if (fGrid) { 338cb93a386Sopenharmony_ci apply_grid(pts, 3); 339cb93a386Sopenharmony_ci } 340cb93a386Sopenharmony_ci 341cb93a386Sopenharmony_ci SkPath path; 342cb93a386Sopenharmony_ci path.moveTo(pts[0]); 343cb93a386Sopenharmony_ci path.lineTo(pts[1]); 344cb93a386Sopenharmony_ci path.lineTo(pts[2]); 345cb93a386Sopenharmony_ci path.close(); 346cb93a386Sopenharmony_ci 347cb93a386Sopenharmony_ci erase(fMinSurface.get()); 348cb93a386Sopenharmony_ci this->setupPaint(&paint); 349cb93a386Sopenharmony_ci paint.setColor(FAT_PIXEL_COLOR); 350cb93a386Sopenharmony_ci fMinSurface->getCanvas()->drawPath(path, paint); 351cb93a386Sopenharmony_ci this->copyMinToMax(); 352cb93a386Sopenharmony_ci 353cb93a386Sopenharmony_ci SkCanvas* max = fMaxSurface->getCanvas(); 354cb93a386Sopenharmony_ci 355cb93a386Sopenharmony_ci fMatrix.mapPoints(pts, 3); 356cb93a386Sopenharmony_ci this->drawTriangleSkeleton(max, pts); 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ci fMaxSurface->draw(canvas, 0, 0); 359cb93a386Sopenharmony_ci} 360cb93a386Sopenharmony_ci 361cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////////////////////////// 362cb93a386Sopenharmony_ci 363cb93a386Sopenharmony_ciclass IndexClick : public Sample::Click { 364cb93a386Sopenharmony_ci int fIndex; 365cb93a386Sopenharmony_cipublic: 366cb93a386Sopenharmony_ci IndexClick(int index) : fIndex(index) {} 367cb93a386Sopenharmony_ci 368cb93a386Sopenharmony_ci static int GetIndex(Sample::Click* click) { 369cb93a386Sopenharmony_ci return ((IndexClick*)click)->fIndex; 370cb93a386Sopenharmony_ci } 371cb93a386Sopenharmony_ci}; 372cb93a386Sopenharmony_ci 373cb93a386Sopenharmony_ciclass DrawLineView : public Sample { 374cb93a386Sopenharmony_ci FatBits fFB; 375cb93a386Sopenharmony_ci SkPoint fPts[3]; 376cb93a386Sopenharmony_ci bool fIsRect; 377cb93a386Sopenharmony_ci int fZoom = 64; 378cb93a386Sopenharmony_cipublic: 379cb93a386Sopenharmony_ci DrawLineView() { 380cb93a386Sopenharmony_ci fFB.setWHZ(24*2, 16*2, fZoom); 381cb93a386Sopenharmony_ci fPts[0].set(1, 1); 382cb93a386Sopenharmony_ci fPts[1].set(5, 4); 383cb93a386Sopenharmony_ci fPts[2].set(2, 6); 384cb93a386Sopenharmony_ci SkMatrix::Scale(fZoom, fZoom).mapPoints(fPts, 3); 385cb93a386Sopenharmony_ci fIsRect = false; 386cb93a386Sopenharmony_ci } 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci void setStyle(FatBits::Style s) { 389cb93a386Sopenharmony_ci fFB.setStyle(s); 390cb93a386Sopenharmony_ci } 391cb93a386Sopenharmony_ci 392cb93a386Sopenharmony_ciprotected: 393cb93a386Sopenharmony_ci SkString name() override { return SkString("FatBits"); } 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci bool onChar(SkUnichar uni) override { 396cb93a386Sopenharmony_ci switch (uni) { 397cb93a386Sopenharmony_ci case 'c': 398cb93a386Sopenharmony_ci fFB.setUseClip(!fFB.getUseClip()); 399cb93a386Sopenharmony_ci return true; 400cb93a386Sopenharmony_ci case 'r': 401cb93a386Sopenharmony_ci fIsRect = !fIsRect; 402cb93a386Sopenharmony_ci return true; 403cb93a386Sopenharmony_ci case 'o': 404cb93a386Sopenharmony_ci fFB.toggleRectAsOval(); 405cb93a386Sopenharmony_ci return true; 406cb93a386Sopenharmony_ci case 'x': 407cb93a386Sopenharmony_ci fFB.setGrid(!fFB.getGrid()); 408cb93a386Sopenharmony_ci return true; 409cb93a386Sopenharmony_ci case 's': 410cb93a386Sopenharmony_ci if (FatBits::kStroke_Style == fFB.getStyle()) { 411cb93a386Sopenharmony_ci this->setStyle(FatBits::kHair_Style); 412cb93a386Sopenharmony_ci } else { 413cb93a386Sopenharmony_ci this->setStyle(FatBits::kStroke_Style); 414cb93a386Sopenharmony_ci } 415cb93a386Sopenharmony_ci return true; 416cb93a386Sopenharmony_ci case 'k': { 417cb93a386Sopenharmony_ci const SkPaint::Cap caps[] = { 418cb93a386Sopenharmony_ci SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap, 419cb93a386Sopenharmony_ci }; 420cb93a386Sopenharmony_ci fFB.fStrokeCap = caps[(fFB.fStrokeCap + 1) % 3]; 421cb93a386Sopenharmony_ci return true; 422cb93a386Sopenharmony_ci } break; 423cb93a386Sopenharmony_ci case 'a': 424cb93a386Sopenharmony_ci fFB.setAA(!fFB.getAA()); 425cb93a386Sopenharmony_ci return true; 426cb93a386Sopenharmony_ci case 'w': 427cb93a386Sopenharmony_ci fFB.setShowSkeleton(!fFB.getShowSkeleton()); 428cb93a386Sopenharmony_ci return true; 429cb93a386Sopenharmony_ci case 'g': 430cb93a386Sopenharmony_ci fFB.togglePixelColors(); 431cb93a386Sopenharmony_ci return true; 432cb93a386Sopenharmony_ci case 't': 433cb93a386Sopenharmony_ci fFB.setTriangle(!fFB.getTriangle()); 434cb93a386Sopenharmony_ci return true; 435cb93a386Sopenharmony_ci case '-': 436cb93a386Sopenharmony_ci fFB.fStrokeWidth -= 0.125f; 437cb93a386Sopenharmony_ci return true; 438cb93a386Sopenharmony_ci case '=': 439cb93a386Sopenharmony_ci fFB.fStrokeWidth += 0.125f; 440cb93a386Sopenharmony_ci return true; 441cb93a386Sopenharmony_ci } 442cb93a386Sopenharmony_ci return false; 443cb93a386Sopenharmony_ci } 444cb93a386Sopenharmony_ci 445cb93a386Sopenharmony_ci void onDrawContent(SkCanvas* canvas) override { 446cb93a386Sopenharmony_ci fFB.drawBG(canvas); 447cb93a386Sopenharmony_ci if (fFB.getTriangle()) { 448cb93a386Sopenharmony_ci fFB.drawTriangle(canvas, fPts); 449cb93a386Sopenharmony_ci } 450cb93a386Sopenharmony_ci else if (fIsRect) { 451cb93a386Sopenharmony_ci fFB.drawRect(canvas, fPts); 452cb93a386Sopenharmony_ci } else { 453cb93a386Sopenharmony_ci fFB.drawLine(canvas, fPts); 454cb93a386Sopenharmony_ci } 455cb93a386Sopenharmony_ci fFB.drawFG(canvas); 456cb93a386Sopenharmony_ci 457cb93a386Sopenharmony_ci { 458cb93a386Sopenharmony_ci SkString str; 459cb93a386Sopenharmony_ci str.printf("%s %s %s", 460cb93a386Sopenharmony_ci fFB.getAA() ? "AA" : "BW", 461cb93a386Sopenharmony_ci FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke", 462cb93a386Sopenharmony_ci fFB.getUseClip() ? "clip" : "noclip"); 463cb93a386Sopenharmony_ci SkPaint paint; 464cb93a386Sopenharmony_ci paint.setColor(SK_ColorBLUE); 465cb93a386Sopenharmony_ci SkFont font(nullptr, 16); 466cb93a386Sopenharmony_ci canvas->drawString(str, 10, 16, font, paint); 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci } 469cb93a386Sopenharmony_ci 470cb93a386Sopenharmony_ci Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override { 471cb93a386Sopenharmony_ci SkPoint pt = { x, y }; 472cb93a386Sopenharmony_ci int index = -1; 473cb93a386Sopenharmony_ci int count = fFB.getTriangle() ? 3 : 2; 474cb93a386Sopenharmony_ci SkScalar tol = 12; 475cb93a386Sopenharmony_ci 476cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 477cb93a386Sopenharmony_ci if (SkPointPriv::EqualsWithinTolerance(fPts[i], pt, tol)) { 478cb93a386Sopenharmony_ci index = i; 479cb93a386Sopenharmony_ci break; 480cb93a386Sopenharmony_ci } 481cb93a386Sopenharmony_ci } 482cb93a386Sopenharmony_ci return new IndexClick(index); 483cb93a386Sopenharmony_ci } 484cb93a386Sopenharmony_ci 485cb93a386Sopenharmony_ci bool onClick(Click* click) override { 486cb93a386Sopenharmony_ci int index = IndexClick::GetIndex(click); 487cb93a386Sopenharmony_ci if (index >= 0 && index <= 2) { 488cb93a386Sopenharmony_ci fPts[index] = click->fCurr; 489cb93a386Sopenharmony_ci } else { 490cb93a386Sopenharmony_ci SkScalar dx = click->fCurr.fX - click->fPrev.fX; 491cb93a386Sopenharmony_ci SkScalar dy = click->fCurr.fY - click->fPrev.fY; 492cb93a386Sopenharmony_ci fPts[0].offset(dx, dy); 493cb93a386Sopenharmony_ci fPts[1].offset(dx, dy); 494cb93a386Sopenharmony_ci fPts[2].offset(dx, dy); 495cb93a386Sopenharmony_ci } 496cb93a386Sopenharmony_ci return true; 497cb93a386Sopenharmony_ci } 498cb93a386Sopenharmony_ci 499cb93a386Sopenharmony_ciprivate: 500cb93a386Sopenharmony_ci 501cb93a386Sopenharmony_ci using INHERITED = Sample; 502cb93a386Sopenharmony_ci}; 503cb93a386Sopenharmony_ci 504cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 505cb93a386Sopenharmony_ci 506cb93a386Sopenharmony_ciDEF_SAMPLE( return new DrawLineView(); ) 507