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" 1288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkPathMeasure.h" 1388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkRandom.h" 1488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkRRect.h" 1588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkColorPriv.h" 1688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkStrokerPriv.h" 1788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#include "SkSurface.h" 1888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 1988c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic bool hittest(const SkPoint& target, SkScalar x, SkScalar y) { 2088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkScalar TOL = 7; 2188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL; 2288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 2388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 2488c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic int getOnCurvePoints(const SkPath& path, SkPoint storage[]) { 2588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::RawIter iter(path); 2688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pts[4]; 2788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::Verb verb; 2888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 2988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = 0; 3088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 3188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (verb) { 3288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kMove_Verb: 3388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kLine_Verb: 3488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kQuad_Verb: 3588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kConic_Verb: 3688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kCubic_Verb: 3788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark storage[count++] = pts[0]; 3888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 3988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 4088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 4188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 4288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 4388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return count; 4488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 4588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 4688c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic void getContourCounts(const SkPath& path, SkTArray<int>* contourCounts) { 4788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::RawIter iter(path); 4888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pts[4]; 4988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath::Verb verb; 5088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 5188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = 0; 5288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 5388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (verb) { 5488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kMove_Verb: 5588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kLine_Verb: 5688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 1; 5788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 5888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kQuad_Verb: 5988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kConic_Verb: 6088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 2; 6188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kCubic_Verb: 6388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count += 3; 6488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case SkPath::kClose_Verb: 6688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark contourCounts->push_back(count); 6788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark count = 0; 6888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 6988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 7088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 7188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (count > 0) { 7488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark contourCounts->push_back(count); 7588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 7688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 7788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 7888c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic void erase(SkSurface* surface) { 7988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark surface->getCanvas()->clear(SK_ColorTRANSPARENT); 8088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark} 8188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 8288c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstruct StrokeTypeButton { 8388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fBounds; 8488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark char fLabel; 8588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fEnabled; 8688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark}; 8788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 8804e4d08556750ff6be4576a4cd4925964c63376fcaryclarkstruct CircleTypeButton : public StrokeTypeButton { 8904e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool fFill; 9004e4d08556750ff6be4576a4cd4925964c63376fcaryclark}; 9104e4d08556750ff6be4576a4cd4925964c63376fcaryclark 9288c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkclass QuadStrokerView : public SampleView { 9388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark enum { 9488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SKELETON_COLOR = 0xFF0000FF, 9588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark WIREFRAME_COLOR = 0x80FF0000 9688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 9788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 9888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark enum { 9904e4d08556750ff6be4576a4cd4925964c63376fcaryclark kCount = 15 10088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 10188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint fPts[kCount]; 10204e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect fWeightControl; 10388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fErrorControl; 10488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fWidthControl; 10588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect fBounds; 10688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkMatrix fMatrix, fInverse; 10788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoTUnref<SkShader> fShader; 10888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoTUnref<SkSurface> fMinSurface; 10988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoTUnref<SkSurface> fMaxSurface; 11088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fCubicButton; 11104e4d08556750ff6be4576a4cd4925964c63376fcaryclark StrokeTypeButton fConicButton; 11288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fQuadButton; 11388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fRRectButton; 11404e4d08556750ff6be4576a4cd4925964c63376fcaryclark CircleTypeButton fCircleButton; 11588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark StrokeTypeButton fTextButton; 11688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkString fText; 11788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fTextSize; 11804e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalar fWeight; 11988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fWidth, fDWidth; 12088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar fWidthScale; 12188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int fW, fH, fZoom; 12288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fAnimate; 12388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fDrawRibs; 12488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool fDrawTangents; 1251297ecfd1d1efaeee41153e491b160228ba4345acaryclark#if !defined SK_LEGACY_STROKE_CURVES && defined(SK_DEBUG) 12688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kStrokerErrorMin 0.001f 12788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kStrokerErrorMax 5 12888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 12988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kWidthMin 1 13088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark #define kWidthMax 100 13188c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkpublic: 13288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark QuadStrokerView() { 13388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->setBGColor(SK_ColorLTGRAY); 13488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 13504e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[0].set(50, 200); // cubic 13688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[1].set(50, 100); 13788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[2].set(150, 50); 13888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[3].set(300, 50); 13988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 14004e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[4].set(350, 200); // conic 14188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[5].set(350, 100); 14288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[6].set(450, 50); 14388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 14404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[7].set(150, 300); // quad 14504e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[8].set(150, 200); 14604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[9].set(250, 150); 14704e4d08556750ff6be4576a4cd4925964c63376fcaryclark 14804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[10].set(200, 200); // rrect 14904e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[11].set(400, 400); 15004e4d08556750ff6be4576a4cd4925964c63376fcaryclark 15104e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[12].set(250, 250); // oval 15204e4d08556750ff6be4576a4cd4925964c63376fcaryclark fPts[13].set(450, 450); 15388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 15488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText = "a"; 15588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize = 12; 15688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth = 50; 15788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = 0.25f; 15804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeight = 1; 15988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 16088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fLabel = 'C'; 16188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fEnabled = false; 16204e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fLabel = 'K'; 16304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fEnabled = true; 16488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fLabel = 'Q'; 16588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fEnabled = false; 16688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fLabel = 'R'; 16788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fEnabled = false; 16804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fLabel = 'O'; 16904e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fEnabled = false; 17004e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fFill = false; 17188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextButton.fLabel = 'T'; 17204e4d08556750ff6be4576a4cd4925964c63376fcaryclark fTextButton.fEnabled = false; 17388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fAnimate = true; 17488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setAsNeeded(); 17588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 17688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 17788c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkprotected: 17836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onQuery(SkEvent* evt) override { 17988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (SampleCode::TitleQ(*evt)) { 18088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SampleCode::TitleR(evt, "QuadStroker"); 18188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 18288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 18388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkUnichar uni; 18488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fEnabled && SampleCode::CharQ(*evt, &uni)) { 18588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark switch (uni) { 18688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case ' ': 18788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText = ""; 18888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 18988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '-': 19088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize = SkTMax(1.0f, fTextSize - 1); 19188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 19288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '+': 19388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark case '=': 19488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextSize += 1; 19588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark break; 19688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark default: 19788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fText.appendUnichar(uni); 19888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 19988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->inval(NULL); 20088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 20188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 20288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return this->INHERITED::onQuery(evt); 20388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 20488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 20536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onSizeChange() override { 20604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeightControl.setXYWH(this->width() - 150, 30, 30, 400); 20788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fErrorControl.setXYWH(this->width() - 100, 30, 30, 400); 20888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthControl.setXYWH(this->width() - 50, 30, 30, 400); 20904e4d08556750ff6be4576a4cd4925964c63376fcaryclark int buttonOffset = 450; 21004e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCubicButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 21104e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 21204e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 21304e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 21404e4d08556750ff6be4576a4cd4925964c63376fcaryclark fQuadButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 21504e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 21604e4d08556750ff6be4576a4cd4925964c63376fcaryclark fRRectButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 21704e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 21804e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 21904e4d08556750ff6be4576a4cd4925964c63376fcaryclark buttonOffset += 50; 22004e4d08556750ff6be4576a4cd4925964c63376fcaryclark fTextButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30); 22188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->INHERITED::onSizeChange(); 22288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 22388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 22488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void copyMinToMax() { 22588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark erase(fMaxSurface); 22688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkCanvas* canvas = fMaxSurface->getCanvas(); 22788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->save(); 22888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->concat(fMatrix); 22988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fMinSurface->draw(canvas, 0, 0, NULL); 23088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->restore(); 23188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 23288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 23388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setXfermodeMode(SkXfermode::kClear_Mode); 23488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (int iy = 1; iy < fH; ++iy) { 23588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar y = SkIntToScalar(iy * fZoom); 23688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint); 23788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 23888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (int ix = 1; ix < fW; ++ix) { 23988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar x = SkIntToScalar(ix * fZoom); 24088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint); 24188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 24288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 24388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 24488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setWHZ(int width, int height, int zoom) { 24588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fZoom = zoom; 24688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom)); 24788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom)); 24888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom); 24988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fShader.reset(sk_tool_utils::create_checkerboard_shader( 25088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 0xFFCCCCCC, 0xFFFFFFFF, zoom)); 25188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 25288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 25388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fMinSurface.reset(SkSurface::NewRaster(info)); 25488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark info = info.makeWH(width * zoom, height * zoom); 25588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fMaxSurface.reset(SkSurface::NewRaster(info)); 25688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 25788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 25888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_points(SkCanvas* canvas, const SkPath& path, SkColor color, 25988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark bool show_lines) { 26088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 26188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(color); 26288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAlpha(0x80); 26388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 26488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int n = path.countPoints(); 26588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkAutoSTArray<32, SkPoint> pts(n); 26688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (show_lines && fDrawTangents) { 26788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkTArray<int> contourCounts; 26888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark getContourCounts(path, &contourCounts); 26988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint* ptPtr = pts.get(); 27088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (int i = 0; i < contourCounts.count(); ++i) { 27188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int count = contourCounts[i]; 27288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.getPoints(ptPtr, count); 27388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, ptPtr, paint); 27488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark ptPtr += count; 27588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 27688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 27788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark n = getOnCurvePoints(path, pts.get()); 27888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 27988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStrokeWidth(5); 28088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts.get(), paint); 28188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 28288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 28388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width, 28488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkColor color) { 28588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkScalar radius = width / 2; 28688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 28788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPathMeasure meas(path, false); 28888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar total = meas.getLength(); 28988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 29088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar delta = 8; 29188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 29288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(color); 29388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 29488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPoint pos, tan; 29588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (SkScalar dist = 0; dist <= total; dist += delta) { 29688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (meas.getPosTan(dist, &pos, &tan)) { 29788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark tan.scale(radius); 29888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark tan.rotateCCW(); 29988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), 30088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark pos.x() - tan.x(), pos.y() - tan.y(), paint); 30188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 30288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 30388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 30488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 30504e4d08556750ff6be4576a4cd4925964c63376fcaryclark void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width, SkScalar scale, 30604e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool drawText) { 30788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect bounds = path.getBounds(); 30888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (bounds.isEmpty()) { 30988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return; 31088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 31104e4d08556750ff6be4576a4cd4925964c63376fcaryclark this->setWHZ(SkScalarCeilToInt(bounds.right()), drawText 31204e4d08556750ff6be4576a4cd4925964c63376fcaryclark ? SkScalarRoundToInt(scale * 3 / 2) : SkScalarRoundToInt(scale), 31304e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalarRoundToInt(950.0f / scale)); 31488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark erase(fMinSurface); 31588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 31688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x1f1f0f0f); 31788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 31804e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStrokeWidth(width * scale * scale); 31988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x3f0f1f3f); 32004e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (drawText) { 32104e4d08556750ff6be4576a4cd4925964c63376fcaryclark fMinSurface->getCanvas()->drawPath(path, paint); 32204e4d08556750ff6be4576a4cd4925964c63376fcaryclark this->copyMinToMax(); 32304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fMaxSurface->draw(canvas, 0, 0, NULL); 32404e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 32588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 32688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 32788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStrokeWidth(1); 32888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 32988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(SKELETON_COLOR); 33088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath scaled; 33188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkMatrix matrix; 33288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark matrix.reset(); 33304e4d08556750ff6be4576a4cd4925964c63376fcaryclark matrix.setScale(950 / scale, 950 / scale); 33488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (drawText) { 33588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.transform(matrix, &scaled); 33688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 33788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark scaled = path; 33888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 33988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(scaled, paint); 34088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_points(canvas, scaled, SKELETON_COLOR, true); 34188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 34288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fDrawRibs) { 34388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_ribs(canvas, scaled, width, 0xFF00FF00); 34488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 34588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 34688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath fill; 34788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 34888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint p; 34988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark p.setStyle(SkPaint::kStroke_Style); 35004e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (drawText) { 35104e4d08556750ff6be4576a4cd4925964c63376fcaryclark p.setStrokeWidth(width * scale * scale); 35204e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else { 35304e4d08556750ff6be4576a4cd4925964c63376fcaryclark p.setStrokeWidth(width); 35404e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 35588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark p.getFillPath(path, &fill); 35688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath scaledFill; 35788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (drawText) { 35888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fill.transform(matrix, &scaledFill); 35988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 36088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark scaledFill = fill; 36188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 36288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(WIREFRAME_COLOR); 36388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(scaledFill, paint); 36488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_points(canvas, scaledFill, WIREFRAME_COLOR, false); 36588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 36688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 36704e4d08556750ff6be4576a4cd4925964c63376fcaryclark void draw_fill(SkCanvas* canvas, const SkRect& rect, SkScalar width) { 36804e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (rect.isEmpty()) { 36904e4d08556750ff6be4576a4cd4925964c63376fcaryclark return; 37004e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 37104e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPaint paint; 37204e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setColor(0x1f1f0f0f); 37304e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStyle(SkPaint::kStroke_Style); 37404e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStrokeWidth(width); 37504e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPath path; 37604e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkScalar maxSide = SkTMax(rect.width(), rect.height()) / 2; 37704e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkPoint center = { rect.fLeft + maxSide, rect.fTop + maxSide }; 37804e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide); 37904e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 38004e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setStyle(SkPaint::kFill_Style); 38104e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 38204e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide - width / 2); 38304e4d08556750ff6be4576a4cd4925964c63376fcaryclark paint.setColor(0x3f0f1f3f); 38404e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 38504e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 38604e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.setFillType(SkPath::kEvenOdd_FillType); 38704e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addCircle(center.fX, center.fY, maxSide + width / 2); 38804e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect outside = SkRect::MakeXYWH(center.fX - maxSide - width, center.fY - maxSide - width, 38904e4d08556750ff6be4576a4cd4925964c63376fcaryclark (maxSide + width) * 2, (maxSide + width) * 2); 39004e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addRect(outside); 39104e4d08556750ff6be4576a4cd4925964c63376fcaryclark canvas->drawPath(path, paint); 39204e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 39304e4d08556750ff6be4576a4cd4925964c63376fcaryclark 39488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_button(SkCanvas* canvas, const StrokeTypeButton& button) { 39588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 39688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 39788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 39888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); 39988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawRect(button.fBounds, paint); 40088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(25.0f); 40188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); 40288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextAlign(SkPaint::kCenter_Align); 40388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kFill_Style); 40488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawText(&button.fLabel, 1, button.fBounds.centerX(), button.fBounds.fBottom - 5, 40588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint); 40688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 40788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 40888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void draw_control(SkCanvas* canvas, const SkRect& bounds, SkScalar value, 40988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar min, SkScalar max, const char* name) { 41088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 41188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 41288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kStroke_Style); 41388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawRect(bounds, paint); 41488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar scale = max - min; 41588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar yPos = bounds.fTop + (value - min) * bounds.height() / scale; 41688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0xFFFF0000); 41788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawLine(bounds.fLeft - 5, yPos, bounds.fRight + 5, yPos, paint); 41888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkString label; 41988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark label.printf("%0.3g", value); 42088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0xFF000000); 42188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(11.0f); 42288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setStyle(SkPaint::kFill_Style); 42388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawText(label.c_str(), label.size(), bounds.fLeft + 5, yPos - 5, paint); 42488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(13.0f); 42588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawText(name, strlen(name), bounds.fLeft, bounds.bottom() + 11, paint); 42688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 42788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 42888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setForGeometry() { 42988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDrawRibs = true; 43088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDrawTangents = true; 43188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthScale = 1; 43288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 43388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 43488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setForText() { 43588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDrawRibs = fDrawTangents = false; 43688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidthScale = 0.002f; 43788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 43888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 43988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark void setAsNeeded() { 44004e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabled 44104e4d08556750ff6be4576a4cd4925964c63376fcaryclark || fRRectButton.fEnabled || fCircleButton.fEnabled) { 44288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 44388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else { 44488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForText(); 44588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 44688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 44788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 44836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDrawContent(SkCanvas* canvas) override { 44988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPath path; 45088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar width = fWidth; 45188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 45288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fCubicButton.fEnabled) { 45388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.moveTo(fPts[0]); 45488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.cubicTo(fPts[1], fPts[2], fPts[3]); 45588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 45604e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 45704e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 45804e4d08556750ff6be4576a4cd4925964c63376fcaryclark 45904e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fEnabled) { 46004e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.moveTo(fPts[4]); 46104e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.conicTo(fPts[5], fPts[6], fWeight); 46204e4d08556750ff6be4576a4cd4925964c63376fcaryclark setForGeometry(); 46304e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 46488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 46588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 46688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fQuadButton.fEnabled) { 46788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 46804e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.moveTo(fPts[7]); 46904e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.quadTo(fPts[8], fPts[9]); 47088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 47104e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 47288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 47388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 47488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fRRectButton.fEnabled) { 47588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar rad = 32; 47688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRect r; 47704e4d08556750ff6be4576a4cd4925964c63376fcaryclark r.set(&fPts[10], 2); 47888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 47988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRRect rr; 48088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.setRectXY(r, rad, rad); 48188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr); 48288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForGeometry(); 48304e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 48488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 48588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 48688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkRRect rr2; 48788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.inset(width/2, width/2, &rr2); 48888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr2, SkPath::kCCW_Direction); 48988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark rr.inset(-width/2, -width/2, &rr2); 49088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.addRRect(rr2, SkPath::kCW_Direction); 49188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 49288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 49388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setColor(0x40FF8844); 49488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark canvas->drawPath(path, paint); 49588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 49688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 49704e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fEnabled) { 49804e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.reset(); 49904e4d08556750ff6be4576a4cd4925964c63376fcaryclark SkRect r; 50004e4d08556750ff6be4576a4cd4925964c63376fcaryclark r.set(&fPts[12], 2); 50104e4d08556750ff6be4576a4cd4925964c63376fcaryclark path.addOval(r); 50204e4d08556750ff6be4576a4cd4925964c63376fcaryclark setForGeometry(); 50304e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fFill) { 50404e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_fill(canvas, r, width); 50504e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else { 50604e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width, 950, false); 50704e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 50804e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 50904e4d08556750ff6be4576a4cd4925964c63376fcaryclark 51088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fEnabled) { 51188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark path.reset(); 51288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkPaint paint; 51388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setAntiAlias(true); 51488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.setTextSize(fTextSize); 51588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark paint.getTextPath(fText.c_str(), fText.size(), 0, fTextSize, &path); 51688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setForText(); 51704e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_stroke(canvas, path, width * fWidthScale / fTextSize, fTextSize, true); 51888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 51988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 52088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fAnimate) { 52188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth += fDWidth; 52288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fDWidth > 0 && fWidth > kWidthMax) { 52388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = -fDWidth; 52488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } else if (fDWidth < 0 && fWidth < kWidthMin) { 52588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fDWidth = -fDWidth; 52688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 52788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 52888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark setAsNeeded(); 52904e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fEnabled) { 53004e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_control(canvas, fWeightControl, fWeight, 0, 5, "weight"); 53104e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 5321297ecfd1d1efaeee41153e491b160228ba4345acaryclark#if !defined SK_LEGACY_STROKE_CURVES && defined(SK_DEBUG) 53388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_control(canvas, fErrorControl, gDebugStrokerError, kStrokerErrorMin, kStrokerErrorMax, 53488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark "error"); 53588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 53688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_control(canvas, fWidthControl, fWidth * fWidthScale, kWidthMin * fWidthScale, 53788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark kWidthMax * fWidthScale, "width"); 53888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fQuadButton); 53988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fCubicButton); 54004e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_button(canvas, fConicButton); 54188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fRRectButton); 54204e4d08556750ff6be4576a4cd4925964c63376fcaryclark draw_button(canvas, fCircleButton); 54388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark draw_button(canvas, fTextButton); 54488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->inval(NULL); 54588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 54688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 54788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark class MyClick : public Click { 54888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark public: 54988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int fIndex; 55088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark MyClick(SkView* target, int index) : Click(target), fIndex(index) {} 55188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark }; 55288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 55388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, 55436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein unsigned modi) override { 55588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) { 55688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (hittest(fPts[i], x, y)) { 55788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return new MyClick(this, (int)i); 55888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 55988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 56088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark const SkRect& rectPt = SkRect::MakeXYWH(x, y, 1, 1); 56104e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fWeightControl.contains(rectPt)) { 56204e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 1); 56304e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 5641297ecfd1d1efaeee41153e491b160228ba4345acaryclark#if !defined SK_LEGACY_STROKE_CURVES && defined(SK_DEBUG) 56588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fErrorControl.contains(rectPt)) { 56604e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 2); 56788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 56888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 56988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fWidthControl.contains(rectPt)) { 57088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 3); 57188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 57288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fCubicButton.fBounds.contains(rectPt)) { 57388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fCubicButton.fEnabled ^= true; 57488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 4); 57588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 57604e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fConicButton.fBounds.contains(rectPt)) { 57704e4d08556750ff6be4576a4cd4925964c63376fcaryclark fConicButton.fEnabled ^= true; 57804e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 5); 57904e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 58088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fQuadButton.fBounds.contains(rectPt)) { 58188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fQuadButton.fEnabled ^= true; 58204e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 6); 58388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 58488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fRRectButton.fBounds.contains(rectPt)) { 58588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fRRectButton.fEnabled ^= true; 58604e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 7); 58704e4d08556750ff6be4576a4cd4925964c63376fcaryclark } 58804e4d08556750ff6be4576a4cd4925964c63376fcaryclark if (fCircleButton.fBounds.contains(rectPt)) { 58904e4d08556750ff6be4576a4cd4925964c63376fcaryclark bool wasEnabled = fCircleButton.fEnabled; 59004e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fEnabled = !fCircleButton.fFill; 59104e4d08556750ff6be4576a4cd4925964c63376fcaryclark fCircleButton.fFill = wasEnabled && !fCircleButton.fFill; 59204e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 8); 59388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 59488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (fTextButton.fBounds.contains(rectPt)) { 59588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fTextButton.fEnabled ^= true; 59604e4d08556750ff6be4576a4cd4925964c63376fcaryclark return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 9); 59788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 59888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return this->INHERITED::onFindClickHandler(x, y, modi); 59988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 60088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 60188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark static SkScalar MapScreenYtoValue(int y, const SkRect& control, SkScalar min, 60288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkScalar max) { 60388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return (SkIntToScalar(y) - control.fTop) / control.height() * (max - min) + min; 60488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 60588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 60636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onClick(Click* click) override { 60788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark int index = ((MyClick*)click)->fIndex; 60888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark if (index < (int) SK_ARRAY_COUNT(fPts)) { 60988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fPts[index].offset(SkIntToScalar(click->fICurr.fX - click->fIPrev.fX), 61088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark SkIntToScalar(click->fICurr.fY - click->fIPrev.fY)); 61188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark this->inval(NULL); 61204e4d08556750ff6be4576a4cd4925964c63376fcaryclark } else if (index == (int) SK_ARRAY_COUNT(fPts) + 1) { 61304e4d08556750ff6be4576a4cd4925964c63376fcaryclark fWeight = MapScreenYtoValue(click->fICurr.fY, fWeightControl, 0, 5); 61488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 6151297ecfd1d1efaeee41153e491b160228ba4345acaryclark#if !defined SK_LEGACY_STROKE_CURVES && defined(SK_DEBUG) 61604e4d08556750ff6be4576a4cd4925964c63376fcaryclark else if (index == (int) SK_ARRAY_COUNT(fPts) + 2) { 61788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark gDebugStrokerError = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY, 61888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fErrorControl, kStrokerErrorMin, kStrokerErrorMax)); 61988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark gDebugStrokerErrorSet = true; 62088c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 62188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark#endif 62288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark else if (index == (int) SK_ARRAY_COUNT(fPts) + 3) { 62388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fWidth = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY, fWidthControl, 62488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark kWidthMin, kWidthMax)); 62588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark fAnimate = fWidth <= kWidthMin; 62688c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 62788c748aeea1cedfc8280d7f3da3d949ed01be177caryclark return true; 62888c748aeea1cedfc8280d7f3da3d949ed01be177caryclark } 62988c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 63088c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkprivate: 63188c748aeea1cedfc8280d7f3da3d949ed01be177caryclark typedef SkView INHERITED; 63288c748aeea1cedfc8280d7f3da3d949ed01be177caryclark}; 63388c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 63488c748aeea1cedfc8280d7f3da3d949ed01be177caryclark/////////////////////////////////////////////////////////////////////////////// 63588c748aeea1cedfc8280d7f3da3d949ed01be177caryclark 63688c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic SkView* F2() { return new QuadStrokerView; } 63788c748aeea1cedfc8280d7f3da3d949ed01be177caryclarkstatic SkViewRegister gR2(F2); 638