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" 14df429f3beac1c191289ba1e3bd918bf84df57bf5Cary Clark#include "SkPointPriv.h" 1588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkRandom.h" 1688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkRRect.h" 1788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkColorPriv.h" 1888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkStrokerPriv.h" 1988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkSurface.h" 2088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 2188c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic bool hittest(const SkPoint& target, SkScalar x, SkScalar y) { 2288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkScalar TOL = 7; 2388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL; 2488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 2588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 2688c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic int getOnCurvePoints(const SkPath& path, SkPoint storage[]) { 2788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::RawIter iter(path); 2888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pts[4]; 2988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::Verb verb; 3088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 3188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = 0; 3288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 3388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (verb) { 3488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kMove_Verb: 3588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kLine_Verb: 3688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kQuad_Verb: 3788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kConic_Verb: 3888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kCubic_Verb: 3988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark storage[count++] = pts[0]; 4088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 4188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 4288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 4388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 4488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 4588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return count; 4688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 4788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 4888c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic void getContourCounts(const SkPath& path, SkTArray<int>* contourCounts) { 4988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::RawIter iter(path); 5088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pts[4]; 5188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::Verb verb; 5288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 5388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = 0; 5488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 5588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (verb) { 5688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kMove_Verb: 5788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kLine_Verb: 5888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 1; 5988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kQuad_Verb: 6188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kConic_Verb: 6288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 2; 6388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kCubic_Verb: 6588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 3; 6688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kClose_Verb: 6888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark contourCounts->push_back(count); 6988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count = 0; 7088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 7188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 7288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 7388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (count > 0) { 7688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark contourCounts->push_back(count); 7788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 7988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 80e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic void erase(const sk_sp<SkSurface>& surface) { 8188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkCanvas* canvas = surface->getCanvas(); 8288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (canvas) { 8388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark canvas->clear(SK_ColorTRANSPARENT); 8488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 8588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 8688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 8788c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstruct StrokeTypeButton { 8888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fBounds; 8988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark char fLabel; 9088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fEnabled; 9188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark}; 9288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 9304e4d08556750ff6be4576a4cd4925964c63376fcaryclarkstruct CircleTypeButton : public StrokeTypeButton { 9404e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool fFill; 9504e4d08556750ff6be4576a4cd4925964c63376fcaryclark}; 9604e4d08556750ff6be4576a4cd4925964c63376fcaryclark 9788c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkclass QuadStrokerView : public SampleView { 9888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark enum { 9988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SKELETON_COLOR = 0xFF0000FF, 10088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark WIREFRAME_COLOR = 0x80FF0000 10188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 10288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 10388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark enum { 10488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark kCount = 18 10588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 10688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint fPts[kCount]; 10704e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect fWeightControl; 10888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkRect fRadiusControl; 10988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fErrorControl; 11088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fWidthControl; 11188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fBounds; 11288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkMatrix fMatrix, fInverse; 1138a21c9fe7f5fef9e87115defef27bd7218419f28reed sk_sp<SkShader> fShader; 114e8f3062a36d3682f4019309a32b5b84dc9eddf8creed sk_sp<SkSurface> fMinSurface; 115e8f3062a36d3682f4019309a32b5b84dc9eddf8creed sk_sp<SkSurface> fMaxSurface; 11688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fCubicButton; 11704e4d08556750ff6be4576a4cd4925964c63376fcaryclark StrokeTypeButton fConicButton; 11888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fQuadButton; 11988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark StrokeTypeButton fArcButton; 12088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fRRectButton; 12104e4d08556750ff6be4576a4cd4925964c63376fcaryclark CircleTypeButton fCircleButton; 12288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fTextButton; 12388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkString fText; 12488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fTextSize; 12504e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalar fWeight; 12688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkScalar fRadius; 12788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fWidth, fDWidth; 12888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fWidthScale; 12988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int fW, fH, fZoom; 13088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fAnimate; 13188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fDrawRibs; 13288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fDrawTangents; 133b6474dd1a530a543ae799c3822e8bc60180761c0caryclark bool fDrawTDivs; 134a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 13588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kStrokerErrorMin 0.001f 13688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kStrokerErrorMax 5 13788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 13888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kWidthMin 1 13988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kWidthMax 100 14088c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkpublic: 14188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark QuadStrokerView() { 14288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->setBGColor(SK_ColorLTGRAY); 14388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 14404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[0].set(50, 200); // cubic 14588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[1].set(50, 100); 14688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[2].set(150, 50); 14788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[3].set(300, 50); 14888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 14904e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[4].set(350, 200); // conic 15088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[5].set(350, 100); 15188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[6].set(450, 50); 15288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 15304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[7].set(150, 300); // quad 15404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[8].set(150, 200); 15504e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[9].set(250, 150); 15604e4d08556750ff6be4576a4cd4925964c63376fcaryclark 15788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[10].set(250, 200); // arc 15888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[11].set(250, 300); 15988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[12].set(150, 350); 16088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark 16188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[13].set(200, 200); // rrect 16288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[14].set(400, 400); 16304e4d08556750ff6be4576a4cd4925964c63376fcaryclark 16488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[15].set(250, 250); // oval 16588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fPts[16].set(450, 450); 16688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 16788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText = "a"; 16888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize = 12; 16988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth = 50; 17088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = 0.25f; 17104e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeight = 1; 17288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fRadius = 150; 17388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 17488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fLabel = 'C'; 17588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fEnabled = false; 17604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fLabel = 'K'; 17788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fConicButton.fEnabled = false; 17888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fLabel = 'Q'; 17988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fEnabled = false; 18088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fArcButton.fLabel = 'A'; 18188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fArcButton.fEnabled = true; 18288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fLabel = 'R'; 18388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fEnabled = false; 18404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fLabel = 'O'; 18588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fCircleButton.fEnabled = true; 18688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fCircleButton.fFill = true; 18788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextButton.fLabel = 'T'; 18804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fTextButton.fEnabled = false; 18988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fAnimate = false; 19088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setAsNeeded(); 19188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 19288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 19388c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkprotected: 19436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onQuery(SkEvent* evt) override { 19588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (SampleCode::TitleQ(*evt)) { 19688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SampleCode::TitleR(evt, "QuadStroker"); 19788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 19888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 19988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkUnichar uni; 20088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fEnabled && SampleCode::CharQ(*evt, &uni)) { 20188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (uni) { 20288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case ' ': 20388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText = ""; 20488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 20588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '-': 20688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize = SkTMax(1.0f, fTextSize - 1); 20788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 20888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '+': 20988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '=': 21088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize += 1; 21188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 21288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 21388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText.appendUnichar(uni); 21488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 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; 251374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(SkBlendMode::kClear); 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); 2678a21c9fe7f5fef9e87115defef27bd7218419f28reed fShader = sk_tool_utils::create_checkerboard_shader(0xFFCCCCCC, 0xFFFFFFFF, zoom); 26888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 26988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 270e8f3062a36d3682f4019309a32b5b84dc9eddf8creed fMinSurface = SkSurface::MakeRaster(info); 27188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark info = info.makeWH(width * zoom, height * zoom); 272e8f3062a36d3682f4019309a32b5b84dc9eddf8creed fMaxSurface = SkSurface::MakeRaster(info); 27388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 27488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 27588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_points(SkCanvas* canvas, const SkPath& path, SkColor color, 27688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool show_lines) { 27788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 27888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(color); 27988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAlpha(0x80); 28088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 28188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int n = path.countPoints(); 28288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoSTArray<32, SkPoint> pts(n); 28388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (show_lines && fDrawTangents) { 28488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkTArray<int> contourCounts; 28588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark getContourCounts(path, &contourCounts); 28688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint* ptPtr = pts.get(); 28788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (int i = 0; i < contourCounts.count(); ++i) { 28888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = contourCounts[i]; 28988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.getPoints(ptPtr, count); 29088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, ptPtr, paint); 29188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark ptPtr += count; 29288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 29388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 29488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark n = getOnCurvePoints(path, pts.get()); 29588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 29688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStrokeWidth(5); 29788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts.get(), paint); 29888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 29988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 30088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width, 30188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkColor color) { 30288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkScalar radius = width / 2; 30388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 30488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPathMeasure meas(path, false); 30588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar total = meas.getLength(); 30688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 30788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar delta = 8; 308b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPaint paint, labelP; 30988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(color); 310b6474dd1a530a543ae799c3822e8bc60180761c0caryclark labelP.setColor(color & 0xff5f9f5f); 31188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pos, tan; 312b6474dd1a530a543ae799c3822e8bc60180761c0caryclark int index = 0; 31388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (SkScalar dist = 0; dist <= total; dist += delta) { 31488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (meas.getPosTan(dist, &pos, &tan)) { 31588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark tan.scale(radius); 316df429f3beac1c191289ba1e3bd918bf84df57bf5Cary Clark SkPointPriv::RotateCCW(&tan); 31788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), 31888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark pos.x() - tan.x(), pos.y() - tan.y(), paint); 319b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (0 == index % 10) { 320b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkString label; 321b6474dd1a530a543ae799c3822e8bc60180761c0caryclark label.appendS32(index); 322b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkRect dot = SkRect::MakeXYWH(pos.x() - 2, pos.y() - 2, 4, 4); 323b6474dd1a530a543ae799c3822e8bc60180761c0caryclark canvas->drawRect(dot, labelP); 3242a475eae622adc1e8fa29206be1eaf862c23548eCary Clark canvas->drawString(label, 325b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.x() - tan.x() * 1.25f, pos.y() - tan.y() * 1.25f, labelP); 326b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 327b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 328b6474dd1a530a543ae799c3822e8bc60180761c0caryclark ++index; 329b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 330b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 331b6474dd1a530a543ae799c3822e8bc60180761c0caryclark 332b6474dd1a530a543ae799c3822e8bc60180761c0caryclark void draw_t_divs(SkCanvas* canvas, const SkPath& path, SkScalar width, SkColor color) { 333b6474dd1a530a543ae799c3822e8bc60180761c0caryclark const SkScalar radius = width / 2; 334b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPaint paint; 335b6474dd1a530a543ae799c3822e8bc60180761c0caryclark paint.setColor(color); 336b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPathMeasure meas(path, false); 337b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkScalar total = meas.getLength(); 338b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkScalar delta = 8; 339b6474dd1a530a543ae799c3822e8bc60180761c0caryclark int ribs = 0; 340b6474dd1a530a543ae799c3822e8bc60180761c0caryclark for (SkScalar dist = 0; dist <= total; dist += delta) { 341b6474dd1a530a543ae799c3822e8bc60180761c0caryclark ++ribs; 342b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 343b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPath::RawIter iter(path); 344b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPoint pts[4]; 345b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (SkPath::kMove_Verb != iter.next(pts)) { 346b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkASSERT(0); 347b6474dd1a530a543ae799c3822e8bc60180761c0caryclark return; 348b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 349b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPath::Verb verb = iter.next(pts); 350b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkASSERT(SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb); 351b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkPoint pos, tan; 352b6474dd1a530a543ae799c3822e8bc60180761c0caryclark for (int index = 0; index < ribs; ++index) { 353b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkScalar t = (SkScalar) index / ribs; 354b6474dd1a530a543ae799c3822e8bc60180761c0caryclark switch (verb) { 355b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kLine_Verb: 356b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan = pts[1] - pts[0]; 357b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos = pts[0]; 358b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.fX += tan.fX * t; 359b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.fY += tan.fY * t; 360b6474dd1a530a543ae799c3822e8bc60180761c0caryclark break; 361b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kQuad_Verb: 362b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos = SkEvalQuadAt(pts, t); 363b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan = SkEvalQuadTangentAt(pts, t); 364b6474dd1a530a543ae799c3822e8bc60180761c0caryclark break; 365b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kConic_Verb: { 366b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkConic conic(pts, iter.conicWeight()); 367b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos = conic.evalAt(t); 368b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan = conic.evalTangentAt(t); 369b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } break; 370b6474dd1a530a543ae799c3822e8bc60180761c0caryclark case SkPath::kCubic_Verb: 371b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkEvalCubicAt(pts, t, &pos, &tan, nullptr); 372b6474dd1a530a543ae799c3822e8bc60180761c0caryclark break; 373b6474dd1a530a543ae799c3822e8bc60180761c0caryclark default: 374b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkASSERT(0); 375b6474dd1a530a543ae799c3822e8bc60180761c0caryclark return; 376b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 377b6474dd1a530a543ae799c3822e8bc60180761c0caryclark tan.setLength(radius); 378df429f3beac1c191289ba1e3bd918bf84df57bf5Cary Clark SkPointPriv::RotateCCW(&tan); 379b6474dd1a530a543ae799c3822e8bc60180761c0caryclark canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), 380b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.x() - tan.x(), pos.y() - tan.y(), paint); 381b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (0 == index % 10) { 382b6474dd1a530a543ae799c3822e8bc60180761c0caryclark SkString label; 383b6474dd1a530a543ae799c3822e8bc60180761c0caryclark label.appendS32(index); 3842a475eae622adc1e8fa29206be1eaf862c23548eCary Clark canvas->drawString(label, 385b6474dd1a530a543ae799c3822e8bc60180761c0caryclark pos.x() + tan.x() * 1.25f, pos.y() + tan.y() * 1.25f, paint); 38688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 38788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 38888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 38988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 39004e4d08556750ff6be4576a4cd4925964c63376fcaryclark void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width, SkScalar scale, 39104e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool drawText) { 392612f70d5fa2d4bf7a393c791966bbce933407017caryclark if (path.isEmpty()) { 39388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return; 39488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 395612f70d5fa2d4bf7a393c791966bbce933407017caryclark SkRect bounds = path.getBounds(); 3969d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary this->setWHZ(SkScalarCeilToInt(bounds.right()), drawText 39704e4d08556750ff6be4576a4cd4925964c63376fcaryclark ? SkScalarRoundToInt(scale * 3 / 2) : SkScalarRoundToInt(scale), 39804e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalarRoundToInt(950.0f / scale)); 39988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark erase(fMinSurface); 40088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 40188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x1f1f0f0f); 40288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 40304e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStrokeWidth(width * scale * scale); 40488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x3f0f1f3f); 40504e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (drawText) { 40604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fMinSurface->getCanvas()->drawPath(path, paint); 40704e4d08556750ff6be4576a4cd4925964c63376fcaryclark this->copyMinToMax(); 40896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMaxSurface->draw(canvas, 0, 0, nullptr); 40904e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 41088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 41188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 41288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStrokeWidth(1); 41388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 41488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(SKELETON_COLOR); 41588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath scaled; 41688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkMatrix matrix; 41788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark matrix.reset(); 41804e4d08556750ff6be4576a4cd4925964c63376fcaryclark matrix.setScale(950 / scale, 950 / scale); 41988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (drawText) { 42088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.transform(matrix, &scaled); 42188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 42288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark scaled = path; 42388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 42488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(scaled, paint); 42588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_points(canvas, scaled, SKELETON_COLOR, true); 42688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 42788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fDrawRibs) { 42888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_ribs(canvas, scaled, width, 0xFF00FF00); 42988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 43088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 431b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (fDrawTDivs) { 432b6474dd1a530a543ae799c3822e8bc60180761c0caryclark draw_t_divs(canvas, scaled, width, 0xFF3F3F00); 433b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 434b6474dd1a530a543ae799c3822e8bc60180761c0caryclark 43588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath fill; 43688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 43788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint p; 43888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark p.setStyle(SkPaint::kStroke_Style); 43904e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (drawText) { 44004e4d08556750ff6be4576a4cd4925964c63376fcaryclark p.setStrokeWidth(width * scale * scale); 44104e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else { 44204e4d08556750ff6be4576a4cd4925964c63376fcaryclark p.setStrokeWidth(width); 44304e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 44488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark p.getFillPath(path, &fill); 44588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath scaledFill; 44688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (drawText) { 44788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fill.transform(matrix, &scaledFill); 44888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 44988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark scaledFill = fill; 45088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 45188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(WIREFRAME_COLOR); 45288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(scaledFill, paint); 45388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_points(canvas, scaledFill, WIREFRAME_COLOR, false); 45488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 45588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 45604e4d08556750ff6be4576a4cd4925964c63376fcaryclark void draw_fill(SkCanvas* canvas, const SkRect& rect, SkScalar width) { 45704e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (rect.isEmpty()) { 45804e4d08556750ff6be4576a4cd4925964c63376fcaryclark return; 45904e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 46004e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPaint paint; 46104e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setColor(0x1f1f0f0f); 46204e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStyle(SkPaint::kStroke_Style); 46304e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStrokeWidth(width); 46404e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPath path; 46504e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalar maxSide = SkTMax(rect.width(), rect.height()) / 2; 46604e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPoint center = { rect.fLeft + maxSide, rect.fTop + maxSide }; 46704e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide); 46804e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 46904e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStyle(SkPaint::kFill_Style); 47004e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 47104e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide - width / 2); 47204e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setColor(0x3f0f1f3f); 47304e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 47404e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 47504e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.setFillType(SkPath::kEvenOdd_FillType); 47604e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide + width / 2); 4779d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary SkRect outside = SkRect::MakeXYWH(center.fX - maxSide - width, center.fY - maxSide - width, 47804e4d08556750ff6be4576a4cd4925964c63376fcaryclark (maxSide + width) * 2, (maxSide + width) * 2); 47904e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addRect(outside); 48004e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 48104e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 48204e4d08556750ff6be4576a4cd4925964c63376fcaryclark 48388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_button(SkCanvas* canvas, const StrokeTypeButton& button) { 48488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 48588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 48688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 48788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); 48888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawRect(button.fBounds, paint); 48988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(25.0f); 49088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); 49188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextAlign(SkPaint::kCenter_Align); 49288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kFill_Style); 49388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawText(&button.fLabel, 1, button.fBounds.centerX(), button.fBounds.fBottom - 5, 49488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint); 49588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 49688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 49788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_control(SkCanvas* canvas, const SkRect& bounds, SkScalar value, 49888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar min, SkScalar max, const char* name) { 49988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 50088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 50188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 50288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawRect(bounds, paint); 50388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar scale = max - min; 50488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar yPos = bounds.fTop + (value - min) * bounds.height() / scale; 50588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0xFFFF0000); 50688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(bounds.fLeft - 5, yPos, bounds.fRight + 5, yPos, paint); 50788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkString label; 50888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark label.printf("%0.3g", value); 50988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0xFF000000); 51088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(11.0f); 51188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kFill_Style); 5122a475eae622adc1e8fa29206be1eaf862c23548eCary Clark canvas->drawString(label, bounds.fLeft + 5, yPos - 5, paint); 51388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(13.0f); 5142a475eae622adc1e8fa29206be1eaf862c23548eCary Clark canvas->drawString(name, bounds.fLeft, bounds.bottom() + 11, paint); 51588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 51688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 51788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setForGeometry() { 51888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDrawRibs = true; 51988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDrawTangents = true; 520b6474dd1a530a543ae799c3822e8bc60180761c0caryclark fDrawTDivs = false; 52188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthScale = 1; 52288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 52388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 52488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setForText() { 525b6474dd1a530a543ae799c3822e8bc60180761c0caryclark fDrawRibs = fDrawTangents = fDrawTDivs = false; 52688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthScale = 0.002f; 52788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 52888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 529b6474dd1a530a543ae799c3822e8bc60180761c0caryclark void setForSingles() { 530b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForGeometry(); 531b6474dd1a530a543ae799c3822e8bc60180761c0caryclark fDrawTDivs = true; 532b6474dd1a530a543ae799c3822e8bc60180761c0caryclark } 533b6474dd1a530a543ae799c3822e8bc60180761c0caryclark 53488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setAsNeeded() { 535b6474dd1a530a543ae799c3822e8bc60180761c0caryclark if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabled) { 536b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 53788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } else if (fRRectButton.fEnabled || fCircleButton.fEnabled || fArcButton.fEnabled) { 53888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 53988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 54088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForText(); 54188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 54288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 54388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 54488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark bool arcCenter(SkPoint* center) { 54588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPath path; 54688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.moveTo(fPts[10]); 54788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.arcTo(fPts[11], fPts[12], fRadius); 54888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPath::Iter iter(path, false); 54988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPoint pts[4]; 55088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark iter.next(pts); 55188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (SkPath::kLine_Verb == iter.next(pts)) { 55288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark iter.next(pts); 55388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 55488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector before = pts[0] - pts[1]; 55588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector after = pts[1] - pts[2]; 55688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark before.setLength(fRadius); 55788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark after.setLength(fRadius); 55888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector beforeCCW, afterCCW; 559df429f3beac1c191289ba1e3bd918bf84df57bf5Cary Clark SkPointPriv::RotateCCW(before, &beforeCCW); 560df429f3beac1c191289ba1e3bd918bf84df57bf5Cary Clark SkPointPriv::RotateCCW(after, &afterCCW); 56188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark beforeCCW += pts[0]; 56288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark afterCCW += pts[2]; 56388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark *center = beforeCCW; 56488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (SkScalarNearlyEqual(beforeCCW.fX, afterCCW.fX) 56588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark && SkScalarNearlyEqual(beforeCCW.fY, afterCCW.fY)) { 56688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return true; 56788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 56888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkVector beforeCW, afterCW; 569df429f3beac1c191289ba1e3bd918bf84df57bf5Cary Clark SkPointPriv::RotateCW(before, &beforeCW); 570df429f3beac1c191289ba1e3bd918bf84df57bf5Cary Clark SkPointPriv::RotateCW(after, &afterCW); 57188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark beforeCW += pts[0]; 57288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark afterCW += pts[2]; 57388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark *center = beforeCW; 57488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return SkScalarNearlyEqual(beforeCW.fX, afterCW.fX) 57588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark && SkScalarNearlyEqual(beforeCCW.fY, afterCW.fY); 57688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 57788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark 57836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDrawContent(SkCanvas* canvas) override { 57988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath path; 58088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar width = fWidth; 58188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 58288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fCubicButton.fEnabled) { 58388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.moveTo(fPts[0]); 58488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.cubicTo(fPts[1], fPts[2], fPts[3]); 585b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 58604e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 58704e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 58804e4d08556750ff6be4576a4cd4925964c63376fcaryclark 58904e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fEnabled) { 590b6474dd1a530a543ae799c3822e8bc60180761c0caryclark path.reset(); 59104e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.moveTo(fPts[4]); 59204e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.conicTo(fPts[5], fPts[6], fWeight); 593b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 59404e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 59588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 59688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 59788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fQuadButton.fEnabled) { 59888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 59904e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.moveTo(fPts[7]); 60004e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.quadTo(fPts[8], fPts[9]); 601b6474dd1a530a543ae799c3822e8bc60180761c0caryclark setForSingles(); 60204e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 60388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 60488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 60588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fEnabled) { 60688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.reset(); 60788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.moveTo(fPts[10]); 60888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark path.arcTo(fPts[11], fPts[12], fRadius); 60988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark setForGeometry(); 61088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_stroke(canvas, path, width, 950, false); 61188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPath pathPts; 61288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark pathPts.moveTo(fPts[10]); 61388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark pathPts.lineTo(fPts[11]); 61488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark pathPts.lineTo(fPts[12]); 61588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_points(canvas, pathPts, SK_ColorDKGRAY, true); 61688651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 61788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark 61888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fRRectButton.fEnabled) { 61988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar rad = 32; 62088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect r; 62188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark r.set(&fPts[13], 2); 62288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 62388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRRect rr; 62488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.setRectXY(r, rad, rad); 62588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr); 62688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 62704e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 62888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 62988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 63088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRRect rr2; 63188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.inset(width/2, width/2, &rr2); 63288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr2, SkPath::kCCW_Direction); 63388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.inset(-width/2, -width/2, &rr2); 63488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr2, SkPath::kCW_Direction); 63588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 63688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 63788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x40FF8844); 63888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(path, paint); 63988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 64088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 64104e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fEnabled) { 64204e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 64304e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect r; 64488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark r.set(&fPts[15], 2); 64504e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addOval(r); 64604e4d08556750ff6be4576a4cd4925964c63376fcaryclark setForGeometry(); 64704e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fFill) { 64888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fEnabled) { 64988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark SkPoint center; 65088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (arcCenter(¢er)) { 6519d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary r.set(center.fX - fRadius, center.fY - fRadius, center.fX + fRadius, 65288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark center.fY + fRadius); 65388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 65488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 65504e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_fill(canvas, r, width); 65604e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else { 65704e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 65804e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 65904e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 66004e4d08556750ff6be4576a4cd4925964c63376fcaryclark 66188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fEnabled) { 66288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 66388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 66488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 66588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(fTextSize); 66688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.getTextPath(fText.c_str(), fText.size(), 0, fTextSize, &path); 66788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForText(); 66804e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width * fWidthScale / fTextSize, fTextSize, true); 66988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 67088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 67188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fAnimate) { 67288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth += fDWidth; 67388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fDWidth > 0 && fWidth > kWidthMax) { 67488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = -fDWidth; 67588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else if (fDWidth < 0 && fWidth < kWidthMin) { 67688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = -fDWidth; 67788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 67888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 67988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setAsNeeded(); 68004e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fEnabled) { 68104e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_control(canvas, fWeightControl, fWeight, 0, 5, "weight"); 68204e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 68388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fEnabled) { 68488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_control(canvas, fRadiusControl, fRadius, 0, 500, "radius"); 68588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 686a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 68788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_control(canvas, fErrorControl, gDebugStrokerError, kStrokerErrorMin, kStrokerErrorMax, 68888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark "error"); 68988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 69088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_control(canvas, fWidthControl, fWidth * fWidthScale, kWidthMin * fWidthScale, 69188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark kWidthMax * fWidthScale, "width"); 69288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fQuadButton); 69388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fCubicButton); 69404e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_button(canvas, fConicButton); 69588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark draw_button(canvas, fArcButton); 69688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fRRectButton); 69704e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_button(canvas, fCircleButton); 69888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fTextButton); 69988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 70088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 70188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark class MyClick : public Click { 70288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark public: 70388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int fIndex; 70488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark MyClick(SkView* target, int index) : Click(target), fIndex(index) {} 70588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 70688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 70788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, 70836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein unsigned modi) override { 70988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) { 71088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (hittest(fPts[i], x, y)) { 71188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return new MyClick(this, (int)i); 71288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 71388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 71488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkRect& rectPt = SkRect::MakeXYWH(x, y, 1, 1); 71504e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fWeightControl.contains(rectPt)) { 71604e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 1); 71704e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 71888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fRadiusControl.contains(rectPt)) { 71988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 2); 72088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 721a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 72288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fErrorControl.contains(rectPt)) { 72388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 3); 72488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 72588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 72688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fWidthControl.contains(rectPt)) { 72788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 4); 72888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 72988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fCubicButton.fBounds.contains(rectPt)) { 73088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fEnabled ^= true; 73188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 5); 73288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 73304e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fBounds.contains(rectPt)) { 73404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fEnabled ^= true; 73588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 6); 73604e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 73788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fQuadButton.fBounds.contains(rectPt)) { 73888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fEnabled ^= true; 73988651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 7); 74088651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } 74188651aeb551fb02003a7600679e8e7df8a589e7fcaryclark if (fArcButton.fBounds.contains(rectPt)) { 74288651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fArcButton.fEnabled ^= true; 74388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 8); 74488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 74588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fRRectButton.fBounds.contains(rectPt)) { 74688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fEnabled ^= true; 74788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 9); 74804e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 74904e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fBounds.contains(rectPt)) { 75004e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool wasEnabled = fCircleButton.fEnabled; 75104e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fEnabled = !fCircleButton.fFill; 75204e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fFill = wasEnabled && !fCircleButton.fFill; 75388651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 10); 75488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 75588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fBounds.contains(rectPt)) { 75688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextButton.fEnabled ^= true; 75788651aeb551fb02003a7600679e8e7df8a589e7fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 11); 75888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 75988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return this->INHERITED::onFindClickHandler(x, y, modi); 76088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 76188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 76288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark static SkScalar MapScreenYtoValue(int y, const SkRect& control, SkScalar min, 76388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar max) { 76488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return (SkIntToScalar(y) - control.fTop) / control.height() * (max - min) + min; 76588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 76688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 76736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onClick(Click* click) override { 76888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int index = ((MyClick*)click)->fIndex; 76988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (index < (int) SK_ARRAY_COUNT(fPts)) { 77088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[index].offset(SkIntToScalar(click->fICurr.fX - click->fIPrev.fX), 77188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkIntToScalar(click->fICurr.fY - click->fIPrev.fY)); 77204e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else if (index == (int) SK_ARRAY_COUNT(fPts) + 1) { 77304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeight = MapScreenYtoValue(click->fICurr.fY, fWeightControl, 0, 5); 77488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark } else if (index == (int) SK_ARRAY_COUNT(fPts) + 2) { 77588651aeb551fb02003a7600679e8e7df8a589e7fcaryclark fRadius = MapScreenYtoValue(click->fICurr.fY, fRadiusControl, 0, 500); 77688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 777a76b7a3b04bc0e937921a1eb38d713c619e60e4ecaryclark#ifdef SK_DEBUG 77888651aeb551fb02003a7600679e8e7df8a589e7fcaryclark else if (index == (int) SK_ARRAY_COUNT(fPts) + 3) { 77988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark gDebugStrokerError = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY, 78088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fErrorControl, kStrokerErrorMin, kStrokerErrorMax)); 78188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark gDebugStrokerErrorSet = true; 78288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 78388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 78488651aeb551fb02003a7600679e8e7df8a589e7fcaryclark else if (index == (int) SK_ARRAY_COUNT(fPts) + 4) { 78588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY, fWidthControl, 78688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark kWidthMin, kWidthMax)); 78788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fAnimate = fWidth <= kWidthMin; 78888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 78988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 79088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 79188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 79288c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkprivate: 79388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark typedef SkView INHERITED; 79488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark}; 79588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 79688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark/////////////////////////////////////////////////////////////////////////////// 79788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 79888c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic SkView* F2() { return new QuadStrokerView; } 79988c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic SkViewRegister gR2(F2); 800