SampleQuadStroker.cpp revision 88651aeb551fb02003a7600679e8e7df8a589e7f
188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark/* 288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark * Copyright 2012 Google Inc. 388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark * 488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark * Use of this source code is governed by a BSD-style license that can be 588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark * found in the LICENSE file. 688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark */ 788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "sk_tool_utils.h" 988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SampleCode.h" 1088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkView.h" 1188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkCanvas.h" 12b6474dd1a530a543ae799c3822e8bc60180761c0caryclark#include "SkGeometry.h" 1388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkPathMeasure.h" 1488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkRandom.h" 1588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkRRect.h" 1688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkColorPriv.h" 1788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkStrokerPriv.h" 1888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkSurface.h" 1988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 2088c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic bool hittest(const SkPoint& target, SkScalar x, SkScalar y) { 2188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkScalar TOL = 7; 2288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL; 2388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 2488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 2588c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic int getOnCurvePoints(const SkPath& path, SkPoint storage[]) { 2688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::RawIter iter(path); 2788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pts[4]; 2888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::Verb verb; 2988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 3088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = 0; 3188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 3288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (verb) { 3388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kMove_Verb: 3488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kLine_Verb: 3588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kQuad_Verb: 3688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kConic_Verb: 3788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kCubic_Verb: 3888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark storage[count++] = pts[0]; 3988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 4088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 4188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 4288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 4388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 4488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return count; 4588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 4688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 4788c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic void getContourCounts(const SkPath& path, SkTArray<int>* contourCounts) { 4888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::RawIter iter(path); 4988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pts[4]; 5088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::Verb verb; 5188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 5288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = 0; 5388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 5488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (verb) { 5588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kMove_Verb: 5688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kLine_Verb: 5788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 1; 5888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 5988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kQuad_Verb: 6088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kConic_Verb: 6188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 2; 6288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kCubic_Verb: 6488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 3; 6588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kClose_Verb: 6788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark contourCounts->push_back(count); 6888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count = 0; 6988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 7088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 7188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 7288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (count > 0) { 7588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark contourCounts->push_back(count); 7688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 7888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 7988c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic void erase(SkSurface* surface) { 8088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkCanvas* canvas = surface->getCanvas(); 8188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (canvas) { 8288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark canvas->clear(SK_ColorTRANSPARENT); 8388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 8488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 8588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 8688c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstruct StrokeTypeButton { 8788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fBounds; 8888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark char fLabel; 8988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fEnabled; 9088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark}; 9188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 9204e4d08556750ff6be4576a4cd4925964c63376fcaryclarkstruct CircleTypeButton : public StrokeTypeButton { 9304e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool fFill; 9404e4d08556750ff6be4576a4cd4925964c63376fcaryclark}; 9504e4d08556750ff6be4576a4cd4925964c63376fcaryclark 9688c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkclass QuadStrokerView : public SampleView { 9788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark enum { 9888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SKELETON_COLOR = 0xFF0000FF, 9988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark WIREFRAME_COLOR = 0x80FF0000 10088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 10188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 10288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark enum { 10388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark kCount = 18 10488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 10588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint fPts[kCount]; 10604e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect fWeightControl; 10788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkRect fRadiusControl; 10888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fErrorControl; 10988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fWidthControl; 11088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fBounds; 11188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkMatrix fMatrix, fInverse; 11288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoTUnref<SkShader> fShader; 11388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoTUnref<SkSurface> fMinSurface; 11488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoTUnref<SkSurface> fMaxSurface; 11588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fCubicButton; 11604e4d08556750ff6be4576a4cd4925964c63376fcaryclark StrokeTypeButton fConicButton; 11788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fQuadButton; 11888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark StrokeTypeButton fArcButton; 11988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fRRectButton; 12004e4d08556750ff6be4576a4cd4925964c63376fcaryclark CircleTypeButton fCircleButton; 12188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fTextButton; 12288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkString fText; 12388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fTextSize; 12404e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalar fWeight; 12588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkScalar fRadius; 12688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fWidth, fDWidth; 12788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fWidthScale; 12888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int fW, fH, fZoom; 12988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fAnimate; 13088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fDrawRibs; 13188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fDrawTangents; 132b6474dd1a530a543ae799c3822e8bc60180761c0caryclark bool fDrawTDivs; 133a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 13488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kStrokerErrorMin 0.001f 13588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kStrokerErrorMax 5 13688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 13788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kWidthMin 1 13888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kWidthMax 100 13988c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkpublic: 14088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark QuadStrokerView() { 14188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->setBGColor(SK_ColorLTGRAY); 14288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 14304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[0].set(50, 200); // cubic 14488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[1].set(50, 100); 14588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[2].set(150, 50); 14688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[3].set(300, 50); 14788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 14804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[4].set(350, 200); // conic 14988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[5].set(350, 100); 15088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[6].set(450, 50); 15188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 15204e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[7].set(150, 300); // quad 15304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[8].set(150, 200); 15404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[9].set(250, 150); 15504e4d08556750ff6be4576a4cd4925964c63376fcaryclark 15688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[10].set(250, 200); // arc 15788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[11].set(250, 300); 15888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[12].set(150, 350); 15988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark 16088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[13].set(200, 200); // rrect 16188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[14].set(400, 400); 16204e4d08556750ff6be4576a4cd4925964c63376fcaryclark 16388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[15].set(250, 250); // oval 16488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[16].set(450, 450); 16588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 16688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText = "a"; 16788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize = 12; 16888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth = 50; 16988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = 0.25f; 17004e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeight = 1; 17188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fRadius = 150; 17288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 17388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fLabel = 'C'; 17488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fEnabled = false; 17504e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fLabel = 'K'; 17688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fConicButton.fEnabled = false; 17788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fLabel = 'Q'; 17888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fEnabled = false; 17988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fArcButton.fLabel = 'A'; 18088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fArcButton.fEnabled = true; 18188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fLabel = 'R'; 18288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fEnabled = false; 18304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fLabel = 'O'; 18488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fCircleButton.fEnabled = true; 18588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fCircleButton.fFill = true; 18688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextButton.fLabel = 'T'; 18704e4d08556750ff6be4576a4cd4925964c63376fcaryclark fTextButton.fEnabled = false; 18888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fAnimate = false; 18988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setAsNeeded(); 19088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 19188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 19288c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkprotected: 19336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onQuery(SkEvent* evt) override { 19488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (SampleCode::TitleQ(*evt)) { 19588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SampleCode::TitleR(evt, "QuadStroker"); 19688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 19788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 19888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkUnichar uni; 19988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fEnabled && SampleCode::CharQ(*evt, &uni)) { 20088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (uni) { 20188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case ' ': 20288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText = ""; 20388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 20488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '-': 20588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize = SkTMax(1.0f, fTextSize - 1); 20688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 20788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '+': 20888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '=': 20988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize += 1; 21088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 21188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 21288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText.appendUnichar(uni); 21388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 21496fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->inval(nullptr); 21588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 21688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 21788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return this->INHERITED::onQuery(evt); 21888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 21988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 22036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onSizeChange() override { 22188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fRadiusControl.setXYWH(this->width() - 200, 30, 30, 400); 22204e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeightControl.setXYWH(this->width() - 150, 30, 30, 400); 22388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fErrorControl.setXYWH(this->width() - 100, 30, 30, 400); 22488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthControl.setXYWH(this->width() - 50, 30, 30, 400); 22504e4d08556750ff6be4576a4cd4925964c63376fcaryclark int buttonOffset = 450; 22604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCubicButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 22704e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 22804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 22904e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 23004e4d08556750ff6be4576a4cd4925964c63376fcaryclark fQuadButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 23104e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 23288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fArcButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 23388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark buttonOffset += 50; 23404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fRRectButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 23504e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 23604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 23704e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 23804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fTextButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 23988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->INHERITED::onSizeChange(); 24088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 24188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 24288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void copyMinToMax() { 24388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark erase(fMaxSurface); 24488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkCanvas* canvas = fMaxSurface->getCanvas(); 24588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->save(); 24688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->concat(fMatrix); 24796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMinSurface->draw(canvas, 0, 0, nullptr); 24888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->restore(); 24988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 25088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 25188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setXfermodeMode(SkXfermode::kClear_Mode); 25288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (int iy = 1; iy < fH; ++iy) { 25388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar y = SkIntToScalar(iy * fZoom); 25488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint); 25588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 25688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (int ix = 1; ix < fW; ++ix) { 25788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar x = SkIntToScalar(ix * fZoom); 25888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint); 25988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 26088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 26188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 26288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setWHZ(int width, int height, int zoom) { 26388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fZoom = zoom; 26488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom)); 26588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom)); 26688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom); 26788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fShader.reset(sk_tool_utils::create_checkerboard_shader( 26888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 0xFFCCCCCC, 0xFFFFFFFF, zoom)); 26988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 27088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 27188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fMinSurface.reset(SkSurface::NewRaster(info)); 27288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark info = info.makeWH(width * zoom, height * zoom); 27388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fMaxSurface.reset(SkSurface::NewRaster(info)); 27488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 27588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 27688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_points(SkCanvas* canvas, const SkPath& path, SkColor color, 27788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool show_lines) { 27888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 27988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(color); 28088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAlpha(0x80); 28188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 28288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int n = path.countPoints(); 28388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoSTArray<32, SkPoint> pts(n); 28488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (show_lines && fDrawTangents) { 28588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkTArray<int> contourCounts; 28688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark getContourCounts(path, &contourCounts); 28788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint* ptPtr = pts.get(); 28888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (int i = 0; i < contourCounts.count(); ++i) { 28988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = contourCounts[i]; 29088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.getPoints(ptPtr, count); 29188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, ptPtr, paint); 29288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark ptPtr += count; 29388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 29488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 29588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark n = getOnCurvePoints(path, pts.get()); 29688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 29788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStrokeWidth(5); 29888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts.get(), paint); 29988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 30088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 30188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width, 30288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkColor color) { 30388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkScalar radius = width / 2; 30488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 30588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPathMeasure meas(path, false); 30688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar total = meas.getLength(); 30788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 30888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar delta = 8; 309b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPaint paint, labelP; 31088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(color); 311b6474dd1a530a543ae799c3822e8bc60180761c0caryclark labelP.setColor(color & 0xff5f9f5f); 31288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pos, tan; 313b6474dd1a530a543ae799c3822e8bc60180761c0caryclark int index = 0; 31488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (SkScalar dist = 0; dist <= total; dist += delta) { 31588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (meas.getPosTan(dist, &pos, &tan)) { 31688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark tan.scale(radius); 31788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark tan.rotateCCW(); 31888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), 31988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark pos.x() - tan.x(), pos.y() - tan.y(), paint); 320b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (0 == index % 10) { 321b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkString label; 322b6474dd1a530a543ae799c3822e8bc60180761c0caryclark label.appendS32(index); 323b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkRect dot = SkRect::MakeXYWH(pos.x() - 2, pos.y() - 2, 4, 4); 324b6474dd1a530a543ae799c3822e8bc60180761c0caryclark canvas->drawRect(dot, labelP); 325b6474dd1a530a543ae799c3822e8bc60180761c0caryclark canvas->drawText(label.c_str(), label.size(), 326b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.x() - tan.x() * 1.25f, pos.y() - tan.y() * 1.25f, labelP); 327b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 328b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 329b6474dd1a530a543ae799c3822e8bc60180761c0caryclark ++index; 330b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 331b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 332b6474dd1a530a543ae799c3822e8bc60180761c0caryclark 333b6474dd1a530a543ae799c3822e8bc60180761c0caryclark void draw_t_divs(SkCanvas* canvas, const SkPath& path, SkScalar width, SkColor color) { 334b6474dd1a530a543ae799c3822e8bc60180761c0caryclark const SkScalar radius = width / 2; 335b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPaint paint; 336b6474dd1a530a543ae799c3822e8bc60180761c0caryclark paint.setColor(color); 337b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPathMeasure meas(path, false); 338b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkScalar total = meas.getLength(); 339b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkScalar delta = 8; 340b6474dd1a530a543ae799c3822e8bc60180761c0caryclark int ribs = 0; 341b6474dd1a530a543ae799c3822e8bc60180761c0caryclark for (SkScalar dist = 0; dist <= total; dist += delta) { 342b6474dd1a530a543ae799c3822e8bc60180761c0caryclark ++ribs; 343b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 344b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPath::RawIter iter(path); 345b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPoint pts[4]; 346b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (SkPath::kMove_Verb != iter.next(pts)) { 347b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkASSERT(0); 348b6474dd1a530a543ae799c3822e8bc60180761c0caryclark return; 349b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 350b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPath::Verb verb = iter.next(pts); 351b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkASSERT(SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb); 352b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPoint pos, tan; 353b6474dd1a530a543ae799c3822e8bc60180761c0caryclark for (int index = 0; index < ribs; ++index) { 354b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkScalar t = (SkScalar) index / ribs; 355b6474dd1a530a543ae799c3822e8bc60180761c0caryclark switch (verb) { 356b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kLine_Verb: 357b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan = pts[1] - pts[0]; 358b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos = pts[0]; 359b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.fX += tan.fX * t; 360b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.fY += tan.fY * t; 361b6474dd1a530a543ae799c3822e8bc60180761c0caryclark break; 362b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kQuad_Verb: 363b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos = SkEvalQuadAt(pts, t); 364b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan = SkEvalQuadTangentAt(pts, t); 365b6474dd1a530a543ae799c3822e8bc60180761c0caryclark break; 366b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kConic_Verb: { 367b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkConic conic(pts, iter.conicWeight()); 368b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos = conic.evalAt(t); 369b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan = conic.evalTangentAt(t); 370b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } break; 371b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kCubic_Verb: 372b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkEvalCubicAt(pts, t, &pos, &tan, nullptr); 373b6474dd1a530a543ae799c3822e8bc60180761c0caryclark break; 374b6474dd1a530a543ae799c3822e8bc60180761c0caryclark default: 375b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkASSERT(0); 376b6474dd1a530a543ae799c3822e8bc60180761c0caryclark return; 377b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 378b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan.setLength(radius); 379b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan.rotateCCW(); 380b6474dd1a530a543ae799c3822e8bc60180761c0caryclark canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), 381b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.x() - tan.x(), pos.y() - tan.y(), paint); 382b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (0 == index % 10) { 383b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkString label; 384b6474dd1a530a543ae799c3822e8bc60180761c0caryclark label.appendS32(index); 385b6474dd1a530a543ae799c3822e8bc60180761c0caryclark canvas->drawText(label.c_str(), label.size(), 386b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.x() + tan.x() * 1.25f, pos.y() + tan.y() * 1.25f, paint); 38788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 38888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 38988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 39088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 39104e4d08556750ff6be4576a4cd4925964c63376fcaryclark void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width, SkScalar scale, 39204e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool drawText) { 393612f70d5fa2d4bf7a393c791966bbce933407017caryclark if (path.isEmpty()) { 39488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return; 39588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 396612f70d5fa2d4bf7a393c791966bbce933407017caryclark SkRect bounds = path.getBounds(); 39704e4d08556750ff6be4576a4cd4925964c63376fcaryclark this->setWHZ(SkScalarCeilToInt(bounds.right()), drawText 39804e4d08556750ff6be4576a4cd4925964c63376fcaryclark ? SkScalarRoundToInt(scale * 3 / 2) : SkScalarRoundToInt(scale), 39904e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalarRoundToInt(950.0f / scale)); 40088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark erase(fMinSurface); 40188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 40288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x1f1f0f0f); 40388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 40404e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStrokeWidth(width * scale * scale); 40588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x3f0f1f3f); 40604e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (drawText) { 40704e4d08556750ff6be4576a4cd4925964c63376fcaryclark fMinSurface->getCanvas()->drawPath(path, paint); 40804e4d08556750ff6be4576a4cd4925964c63376fcaryclark this->copyMinToMax(); 40996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMaxSurface->draw(canvas, 0, 0, nullptr); 41004e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 41188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 41288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 41388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStrokeWidth(1); 41488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 41588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(SKELETON_COLOR); 41688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath scaled; 41788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkMatrix matrix; 41888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark matrix.reset(); 41904e4d08556750ff6be4576a4cd4925964c63376fcaryclark matrix.setScale(950 / scale, 950 / scale); 42088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (drawText) { 42188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.transform(matrix, &scaled); 42288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 42388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark scaled = path; 42488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 42588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(scaled, paint); 42688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_points(canvas, scaled, SKELETON_COLOR, true); 42788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 42888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fDrawRibs) { 42988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_ribs(canvas, scaled, width, 0xFF00FF00); 43088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 43188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 432b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (fDrawTDivs) { 433b6474dd1a530a543ae799c3822e8bc60180761c0caryclark draw_t_divs(canvas, scaled, width, 0xFF3F3F00); 434b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 435b6474dd1a530a543ae799c3822e8bc60180761c0caryclark 43688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath fill; 43788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 43888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint p; 43988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark p.setStyle(SkPaint::kStroke_Style); 44004e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (drawText) { 44104e4d08556750ff6be4576a4cd4925964c63376fcaryclark p.setStrokeWidth(width * scale * scale); 44204e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else { 44304e4d08556750ff6be4576a4cd4925964c63376fcaryclark p.setStrokeWidth(width); 44404e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 44588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark p.getFillPath(path, &fill); 44688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath scaledFill; 44788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (drawText) { 44888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fill.transform(matrix, &scaledFill); 44988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 45088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark scaledFill = fill; 45188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 45288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(WIREFRAME_COLOR); 45388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(scaledFill, paint); 45488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_points(canvas, scaledFill, WIREFRAME_COLOR, false); 45588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 45688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 45704e4d08556750ff6be4576a4cd4925964c63376fcaryclark void draw_fill(SkCanvas* canvas, const SkRect& rect, SkScalar width) { 45804e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (rect.isEmpty()) { 45904e4d08556750ff6be4576a4cd4925964c63376fcaryclark return; 46004e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 46104e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPaint paint; 46204e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setColor(0x1f1f0f0f); 46304e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStyle(SkPaint::kStroke_Style); 46404e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStrokeWidth(width); 46504e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPath path; 46604e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalar maxSide = SkTMax(rect.width(), rect.height()) / 2; 46704e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPoint center = { rect.fLeft + maxSide, rect.fTop + maxSide }; 46804e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide); 46904e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 47004e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStyle(SkPaint::kFill_Style); 47104e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 47204e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide - width / 2); 47304e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setColor(0x3f0f1f3f); 47404e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 47504e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 47604e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.setFillType(SkPath::kEvenOdd_FillType); 47704e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide + width / 2); 47804e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect outside = SkRect::MakeXYWH(center.fX - maxSide - width, center.fY - maxSide - width, 47904e4d08556750ff6be4576a4cd4925964c63376fcaryclark (maxSide + width) * 2, (maxSide + width) * 2); 48004e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addRect(outside); 48104e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 48204e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 48304e4d08556750ff6be4576a4cd4925964c63376fcaryclark 48488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_button(SkCanvas* canvas, const StrokeTypeButton& button) { 48588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 48688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 48788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 48888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); 48988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawRect(button.fBounds, paint); 49088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(25.0f); 49188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); 49288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextAlign(SkPaint::kCenter_Align); 49388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kFill_Style); 49488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawText(&button.fLabel, 1, button.fBounds.centerX(), button.fBounds.fBottom - 5, 49588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint); 49688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 49788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 49888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_control(SkCanvas* canvas, const SkRect& bounds, SkScalar value, 49988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar min, SkScalar max, const char* name) { 50088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 50188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 50288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 50388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawRect(bounds, paint); 50488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar scale = max - min; 50588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar yPos = bounds.fTop + (value - min) * bounds.height() / scale; 50688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0xFFFF0000); 50788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(bounds.fLeft - 5, yPos, bounds.fRight + 5, yPos, paint); 50888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkString label; 50988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark label.printf("%0.3g", value); 51088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0xFF000000); 51188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(11.0f); 51288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kFill_Style); 51388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawText(label.c_str(), label.size(), bounds.fLeft + 5, yPos - 5, paint); 51488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(13.0f); 51588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawText(name, strlen(name), bounds.fLeft, bounds.bottom() + 11, paint); 51688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 51788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 51888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setForGeometry() { 51988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDrawRibs = true; 52088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDrawTangents = true; 521b6474dd1a530a543ae799c3822e8bc60180761c0caryclark fDrawTDivs = false; 52288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthScale = 1; 52388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 52488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 52588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setForText() { 526b6474dd1a530a543ae799c3822e8bc60180761c0caryclark fDrawRibs = fDrawTangents = fDrawTDivs = false; 52788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthScale = 0.002f; 52888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 52988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 530b6474dd1a530a543ae799c3822e8bc60180761c0caryclark void setForSingles() { 531b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForGeometry(); 532b6474dd1a530a543ae799c3822e8bc60180761c0caryclark fDrawTDivs = true; 533b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 534b6474dd1a530a543ae799c3822e8bc60180761c0caryclark 53588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setAsNeeded() { 536b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabled) { 537b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 53888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } else if (fRRectButton.fEnabled || fCircleButton.fEnabled || fArcButton.fEnabled) { 53988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 54088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 54188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForText(); 54288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 54388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 54488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 54588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark bool arcCenter(SkPoint* center) { 54688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPath path; 54788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.moveTo(fPts[10]); 54888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.arcTo(fPts[11], fPts[12], fRadius); 54988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPath::Iter iter(path, false); 55088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPoint pts[4]; 55188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark iter.next(pts); 55288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (SkPath::kLine_Verb == iter.next(pts)) { 55388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark iter.next(pts); 55488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 55588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector before = pts[0] - pts[1]; 55688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector after = pts[1] - pts[2]; 55788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark before.setLength(fRadius); 55888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark after.setLength(fRadius); 55988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector beforeCCW, afterCCW; 56088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark before.rotateCCW(&beforeCCW); 56188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark after.rotateCCW(&afterCCW); 56288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark beforeCCW += pts[0]; 56388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark afterCCW += pts[2]; 56488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark *center = beforeCCW; 56588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (SkScalarNearlyEqual(beforeCCW.fX, afterCCW.fX) 56688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark && SkScalarNearlyEqual(beforeCCW.fY, afterCCW.fY)) { 56788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return true; 56888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 56988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector beforeCW, afterCW; 57088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark before.rotateCW(&beforeCW); 57188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark after.rotateCW(&afterCW); 57288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark beforeCW += pts[0]; 57388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark afterCW += pts[2]; 57488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark *center = beforeCW; 57588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return SkScalarNearlyEqual(beforeCW.fX, afterCW.fX) 57688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark && SkScalarNearlyEqual(beforeCCW.fY, afterCW.fY); 57788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 57888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark 57936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDrawContent(SkCanvas* canvas) override { 58088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath path; 58188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar width = fWidth; 58288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 58388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fCubicButton.fEnabled) { 58488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.moveTo(fPts[0]); 58588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.cubicTo(fPts[1], fPts[2], fPts[3]); 586b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 58704e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 58804e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 58904e4d08556750ff6be4576a4cd4925964c63376fcaryclark 59004e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fEnabled) { 591b6474dd1a530a543ae799c3822e8bc60180761c0caryclark path.reset(); 59204e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.moveTo(fPts[4]); 59304e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.conicTo(fPts[5], fPts[6], fWeight); 594b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 59504e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 59688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 59788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 59888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fQuadButton.fEnabled) { 59988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 60004e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.moveTo(fPts[7]); 60104e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.quadTo(fPts[8], fPts[9]); 602b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 60304e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 60488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 60588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 60688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fEnabled) { 60788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.reset(); 60888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.moveTo(fPts[10]); 60988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.arcTo(fPts[11], fPts[12], fRadius); 61088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark setForGeometry(); 61188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_stroke(canvas, path, width, 950, false); 61288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPath pathPts; 61388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark pathPts.moveTo(fPts[10]); 61488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark pathPts.lineTo(fPts[11]); 61588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark pathPts.lineTo(fPts[12]); 61688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_points(canvas, pathPts, SK_ColorDKGRAY, true); 61788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 61888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark 61988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fRRectButton.fEnabled) { 62088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar rad = 32; 62188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect r; 62288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark r.set(&fPts[13], 2); 62388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 62488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRRect rr; 62588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.setRectXY(r, rad, rad); 62688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr); 62788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 62804e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 62988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 63088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 63188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRRect rr2; 63288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.inset(width/2, width/2, &rr2); 63388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr2, SkPath::kCCW_Direction); 63488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.inset(-width/2, -width/2, &rr2); 63588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr2, SkPath::kCW_Direction); 63688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 63788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 63888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x40FF8844); 63988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(path, paint); 64088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 64188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 64204e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fEnabled) { 64304e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 64404e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect r; 64588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark r.set(&fPts[15], 2); 64604e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addOval(r); 64704e4d08556750ff6be4576a4cd4925964c63376fcaryclark setForGeometry(); 64804e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fFill) { 64988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fEnabled) { 65088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPoint center; 65188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (arcCenter(¢er)) { 65288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark r.set(center.fX - fRadius, center.fY - fRadius, center.fX + fRadius, 65388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark center.fY + fRadius); 65488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 65588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 65604e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_fill(canvas, r, width); 65704e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else { 65804e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 65904e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 66004e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 66104e4d08556750ff6be4576a4cd4925964c63376fcaryclark 66288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fEnabled) { 66388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 66488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 66588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 66688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(fTextSize); 66788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.getTextPath(fText.c_str(), fText.size(), 0, fTextSize, &path); 66888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForText(); 66904e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width * fWidthScale / fTextSize, fTextSize, true); 67088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 67188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 67288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fAnimate) { 67388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth += fDWidth; 67488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fDWidth > 0 && fWidth > kWidthMax) { 67588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = -fDWidth; 67688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else if (fDWidth < 0 && fWidth < kWidthMin) { 67788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = -fDWidth; 67888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 67988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 68088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setAsNeeded(); 68104e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fEnabled) { 68204e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_control(canvas, fWeightControl, fWeight, 0, 5, "weight"); 68304e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 68488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fEnabled) { 68588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_control(canvas, fRadiusControl, fRadius, 0, 500, "radius"); 68688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 687a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 68888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_control(canvas, fErrorControl, gDebugStrokerError, kStrokerErrorMin, kStrokerErrorMax, 68988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark "error"); 69088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 69188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_control(canvas, fWidthControl, fWidth * fWidthScale, kWidthMin * fWidthScale, 69288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark kWidthMax * fWidthScale, "width"); 69388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fQuadButton); 69488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fCubicButton); 69504e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_button(canvas, fConicButton); 69688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_button(canvas, fArcButton); 69788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fRRectButton); 69804e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_button(canvas, fCircleButton); 69988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fTextButton); 70096fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->inval(nullptr); 70188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 70288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 70388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark class MyClick : public Click { 70488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark public: 70588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int fIndex; 70688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark MyClick(SkView* target, int index) : Click(target), fIndex(index) {} 70788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 70888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 70988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, 71036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein unsigned modi) override { 71188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) { 71288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (hittest(fPts[i], x, y)) { 71388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return new MyClick(this, (int)i); 71488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 71588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 71688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkRect& rectPt = SkRect::MakeXYWH(x, y, 1, 1); 71704e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fWeightControl.contains(rectPt)) { 71804e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 1); 71904e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 72088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fRadiusControl.contains(rectPt)) { 72188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 2); 72288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 723a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 72488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fErrorControl.contains(rectPt)) { 72588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 3); 72688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 72788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 72888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fWidthControl.contains(rectPt)) { 72988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 4); 73088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 73188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fCubicButton.fBounds.contains(rectPt)) { 73288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fEnabled ^= true; 73388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 5); 73488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 73504e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fBounds.contains(rectPt)) { 73604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fEnabled ^= true; 73788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 6); 73804e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 73988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fQuadButton.fBounds.contains(rectPt)) { 74088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fEnabled ^= true; 74188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 7); 74288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 74388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fBounds.contains(rectPt)) { 74488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fArcButton.fEnabled ^= true; 74588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 8); 74688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 74788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fRRectButton.fBounds.contains(rectPt)) { 74888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fEnabled ^= true; 74988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 9); 75004e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 75104e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fBounds.contains(rectPt)) { 75204e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool wasEnabled = fCircleButton.fEnabled; 75304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fEnabled = !fCircleButton.fFill; 75404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fFill = wasEnabled && !fCircleButton.fFill; 75588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 10); 75688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 75788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fBounds.contains(rectPt)) { 75888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextButton.fEnabled ^= true; 75988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 11); 76088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 76188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return this->INHERITED::onFindClickHandler(x, y, modi); 76288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 76388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 76488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark static SkScalar MapScreenYtoValue(int y, const SkRect& control, SkScalar min, 76588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar max) { 76688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return (SkIntToScalar(y) - control.fTop) / control.height() * (max - min) + min; 76788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 76888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 76936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onClick(Click* click) override { 77088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int index = ((MyClick*)click)->fIndex; 77188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (index < (int) SK_ARRAY_COUNT(fPts)) { 77288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[index].offset(SkIntToScalar(click->fICurr.fX - click->fIPrev.fX), 77388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkIntToScalar(click->fICurr.fY - click->fIPrev.fY)); 77496fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->inval(nullptr); 77504e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else if (index == (int) SK_ARRAY_COUNT(fPts) + 1) { 77604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeight = MapScreenYtoValue(click->fICurr.fY, fWeightControl, 0, 5); 77788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } else if (index == (int) SK_ARRAY_COUNT(fPts) + 2) { 77888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fRadius = MapScreenYtoValue(click->fICurr.fY, fRadiusControl, 0, 500); 77988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 780a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 78188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark else if (index == (int) SK_ARRAY_COUNT(fPts) + 3) { 78288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark gDebugStrokerError = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY, 78388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fErrorControl, kStrokerErrorMin, kStrokerErrorMax)); 78488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark gDebugStrokerErrorSet = true; 78588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 78688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 78788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark else if (index == (int) SK_ARRAY_COUNT(fPts) + 4) { 78888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY, fWidthControl, 78988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark kWidthMin, kWidthMax)); 79088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fAnimate = fWidth <= kWidthMin; 79188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 79288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 79388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 79488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 79588c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkprivate: 79688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark typedef SkView INHERITED; 79788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark}; 79888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 79988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark/////////////////////////////////////////////////////////////////////////////// 80088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 80188c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic SkView* F2() { return new QuadStrokerView; } 80288c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic SkViewRegister gR2(F2); 803