1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathBuilder.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathEffect.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkDashPathEffect.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "tools/timer/TimeUtils.h" 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Worker int dash1[] = { 1, 1 }; 25*c8dee2aaSAndroid Build Coastguard Worker int dash2[] = { 1, 3 }; 26*c8dee2aaSAndroid Build Coastguard Worker int dash3[] = { 1, 1, 3, 3 }; 27*c8dee2aaSAndroid Build Coastguard Worker int dash4[] = { 1, 3, 2, 4 }; 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker struct DashExample { 30*c8dee2aaSAndroid Build Coastguard Worker int* pattern; 31*c8dee2aaSAndroid Build Coastguard Worker int length; 32*c8dee2aaSAndroid Build Coastguard Worker } dashExamples[] = { 33*c8dee2aaSAndroid Build Coastguard Worker { dash1, std::size(dash1) }, 34*c8dee2aaSAndroid Build Coastguard Worker { dash2, std::size(dash2) }, 35*c8dee2aaSAndroid Build Coastguard Worker { dash3, std::size(dash3) }, 36*c8dee2aaSAndroid Build Coastguard Worker { dash4, std::size(dash4) } 37*c8dee2aaSAndroid Build Coastguard Worker }; 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker class DashCircleGM : public skiagm::GM { 41*c8dee2aaSAndroid Build Coastguard Worker public: DashCircleGM()42*c8dee2aaSAndroid Build Coastguard Worker DashCircleGM() : fRotation(0) { } 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker protected: getName() const45*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("dashcircle"); } 46*c8dee2aaSAndroid Build Coastguard Worker getISize()47*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(900, 1200); } 48*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)49*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 50*c8dee2aaSAndroid Build Coastguard Worker SkPaint refPaint; 51*c8dee2aaSAndroid Build Coastguard Worker refPaint.setAntiAlias(true); 52*c8dee2aaSAndroid Build Coastguard Worker refPaint.setColor(0xFFbf3f7f); 53*c8dee2aaSAndroid Build Coastguard Worker refPaint.setStroke(true); 54*c8dee2aaSAndroid Build Coastguard Worker refPaint.setStrokeWidth(1); 55*c8dee2aaSAndroid Build Coastguard Worker const SkScalar radius = 125; 56*c8dee2aaSAndroid Build Coastguard Worker SkRect oval = SkRect::MakeLTRB(-radius - 20, -radius - 20, radius + 20, radius + 20); 57*c8dee2aaSAndroid Build Coastguard Worker SkPath circle = SkPath::Circle(0, 0, radius); 58*c8dee2aaSAndroid Build Coastguard Worker SkScalar circumference = radius * SK_ScalarPI * 2; 59*c8dee2aaSAndroid Build Coastguard Worker int wedges[] = { 6, 12, 36 }; 60*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(radius+20, radius+20); 61*c8dee2aaSAndroid Build Coastguard Worker for (int wedge : wedges) { 62*c8dee2aaSAndroid Build Coastguard Worker SkScalar arcLength = 360.f / wedge; 63*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 64*c8dee2aaSAndroid Build Coastguard Worker for (const DashExample& dashExample : dashExamples) { 65*c8dee2aaSAndroid Build Coastguard Worker SkPathBuilder refPath; 66*c8dee2aaSAndroid Build Coastguard Worker int dashUnits = 0; 67*c8dee2aaSAndroid Build Coastguard Worker for (int index = 0; index < dashExample.length; ++index) { 68*c8dee2aaSAndroid Build Coastguard Worker dashUnits += dashExample.pattern[index]; 69*c8dee2aaSAndroid Build Coastguard Worker } 70*c8dee2aaSAndroid Build Coastguard Worker SkScalar unitLength = arcLength / dashUnits; 71*c8dee2aaSAndroid Build Coastguard Worker SkScalar angle = 0; 72*c8dee2aaSAndroid Build Coastguard Worker for (int index = 0; index < wedge; ++index) { 73*c8dee2aaSAndroid Build Coastguard Worker for (int i2 = 0; i2 < dashExample.length; i2 += 2) { 74*c8dee2aaSAndroid Build Coastguard Worker SkScalar span = dashExample.pattern[i2] * unitLength; 75*c8dee2aaSAndroid Build Coastguard Worker refPath.moveTo(0, 0); 76*c8dee2aaSAndroid Build Coastguard Worker refPath.arcTo(oval, angle, span, false); 77*c8dee2aaSAndroid Build Coastguard Worker refPath.close(); 78*c8dee2aaSAndroid Build Coastguard Worker angle += span + (dashExample.pattern[i2 + 1]) * unitLength; 79*c8dee2aaSAndroid Build Coastguard Worker } 80*c8dee2aaSAndroid Build Coastguard Worker } 81*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 82*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(fRotation); 83*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(refPath.detach(), refPaint); 84*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 85*c8dee2aaSAndroid Build Coastguard Worker SkPaint p; 86*c8dee2aaSAndroid Build Coastguard Worker p.setAntiAlias(true); 87*c8dee2aaSAndroid Build Coastguard Worker p.setStroke(true); 88*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeWidth(10); 89*c8dee2aaSAndroid Build Coastguard Worker SkScalar intervals[4]; 90*c8dee2aaSAndroid Build Coastguard Worker int intervalCount = dashExample.length; 91*c8dee2aaSAndroid Build Coastguard Worker SkScalar dashLength = circumference / wedge / dashUnits; 92*c8dee2aaSAndroid Build Coastguard Worker for (int index = 0; index < dashExample.length; ++index) { 93*c8dee2aaSAndroid Build Coastguard Worker intervals[index] = dashExample.pattern[index] * dashLength; 94*c8dee2aaSAndroid Build Coastguard Worker } 95*c8dee2aaSAndroid Build Coastguard Worker p.setPathEffect(SkDashPathEffect::Make(intervals, intervalCount, 0)); 96*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 97*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(fRotation); 98*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(circle, p); 99*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 100*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, radius * 2 + 50); 101*c8dee2aaSAndroid Build Coastguard Worker } 102*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 103*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(radius * 2 + 50, 0); 104*c8dee2aaSAndroid Build Coastguard Worker } 105*c8dee2aaSAndroid Build Coastguard Worker } 106*c8dee2aaSAndroid Build Coastguard Worker onAnimate(double nanos)107*c8dee2aaSAndroid Build Coastguard Worker bool onAnimate(double nanos) override { 108*c8dee2aaSAndroid Build Coastguard Worker constexpr SkScalar kDesiredDurationSecs = 100.0f; 109*c8dee2aaSAndroid Build Coastguard Worker 110*c8dee2aaSAndroid Build Coastguard Worker fRotation = TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f); 111*c8dee2aaSAndroid Build Coastguard Worker return true; 112*c8dee2aaSAndroid Build Coastguard Worker } 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker private: 115*c8dee2aaSAndroid Build Coastguard Worker SkScalar fRotation; 116*c8dee2aaSAndroid Build Coastguard Worker 117*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GM; 118*c8dee2aaSAndroid Build Coastguard Worker }; 119*c8dee2aaSAndroid Build Coastguard Worker 120*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new DashCircleGM; ) 121*c8dee2aaSAndroid Build Coastguard Worker 122*c8dee2aaSAndroid Build Coastguard Worker class DashCircle2GM : public skiagm::GM { 123*c8dee2aaSAndroid Build Coastguard Worker public: DashCircle2GM()124*c8dee2aaSAndroid Build Coastguard Worker DashCircle2GM() {} 125*c8dee2aaSAndroid Build Coastguard Worker 126*c8dee2aaSAndroid Build Coastguard Worker protected: getName() const127*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("dashcircle2"); } 128*c8dee2aaSAndroid Build Coastguard Worker getISize()129*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(635, 900); } 130*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)131*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 132*c8dee2aaSAndroid Build Coastguard Worker // These intervals are defined relative to tau. 133*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kIntervals[][2]{ 134*c8dee2aaSAndroid Build Coastguard Worker {0.333f, 0.333f}, 135*c8dee2aaSAndroid Build Coastguard Worker {0.015f, 0.015f}, 136*c8dee2aaSAndroid Build Coastguard Worker {0.01f , 0.09f }, 137*c8dee2aaSAndroid Build Coastguard Worker {0.097f, 0.003f}, 138*c8dee2aaSAndroid Build Coastguard Worker {0.02f , 0.04f }, 139*c8dee2aaSAndroid Build Coastguard Worker {0.1f , 0.2f }, 140*c8dee2aaSAndroid Build Coastguard Worker {0.25f , 0.25f }, 141*c8dee2aaSAndroid Build Coastguard Worker {0.6f , 0.7f }, // adds to > 1 142*c8dee2aaSAndroid Build Coastguard Worker {1.2f , 0.8f }, // on is > 1 143*c8dee2aaSAndroid Build Coastguard Worker {0.1f , 1.1f }, // off is > 1*/ 144*c8dee2aaSAndroid Build Coastguard Worker }; 145*c8dee2aaSAndroid Build Coastguard Worker 146*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kN = std::size(kIntervals); 147*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kRadius = 20.f; 148*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kStrokeWidth = 15.f; 149*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kPad = 5.f; 150*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkRect kCircle = {-kRadius, -kRadius, kRadius, kRadius}; 151*c8dee2aaSAndroid Build Coastguard Worker 152*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kThinRadius = kRadius * 1.5; 153*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkRect kThinCircle = {-kThinRadius, -kThinRadius, 154*c8dee2aaSAndroid Build Coastguard Worker kThinRadius, kThinRadius}; 155*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kThinStrokeWidth = 0.4f; 156*c8dee2aaSAndroid Build Coastguard Worker 157*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> deffects[std::size(kIntervals)]; 158*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> thinDEffects[std::size(kIntervals)]; 159*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kN; ++i) { 160*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kTau = 2 * SK_ScalarPI; 161*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kCircumference = kRadius * kTau; 162*c8dee2aaSAndroid Build Coastguard Worker SkScalar scaledIntervals[2] = {kCircumference * kIntervals[i][0], 163*c8dee2aaSAndroid Build Coastguard Worker kCircumference * kIntervals[i][1]}; 164*c8dee2aaSAndroid Build Coastguard Worker deffects[i] = SkDashPathEffect::Make( 165*c8dee2aaSAndroid Build Coastguard Worker scaledIntervals, 2, kCircumference * fPhaseDegrees * kTau / 360.f); 166*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kThinCircumference = kThinRadius * kTau; 167*c8dee2aaSAndroid Build Coastguard Worker scaledIntervals[0] = kThinCircumference * kIntervals[i][0]; 168*c8dee2aaSAndroid Build Coastguard Worker scaledIntervals[1] = kThinCircumference * kIntervals[i][1]; 169*c8dee2aaSAndroid Build Coastguard Worker thinDEffects[i] = SkDashPathEffect::Make( 170*c8dee2aaSAndroid Build Coastguard Worker scaledIntervals, 2, kThinCircumference * fPhaseDegrees * kTau / 360.f); 171*c8dee2aaSAndroid Build Coastguard Worker } 172*c8dee2aaSAndroid Build Coastguard Worker 173*c8dee2aaSAndroid Build Coastguard Worker SkMatrix rotate; 174*c8dee2aaSAndroid Build Coastguard Worker rotate.setRotate(25.f); 175*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix kMatrices[]{ 176*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::I(), 177*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::Scale(1.2f, 1.2f), 178*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::MakeAll(1, 0, 0, 0, -1, 0, 0, 0, 1), // y flipper 179*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::MakeAll(-1, 0, 0, 0, 1, 0, 0, 0, 1), // x flipper 180*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::Scale(0.7f, 0.7f), 181*c8dee2aaSAndroid Build Coastguard Worker rotate, 182*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::Concat( 183*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::Concat(SkMatrix::MakeAll(-1, 0, 0, 0, 1, 0, 0, 0, 1), rotate), 184*c8dee2aaSAndroid Build Coastguard Worker rotate) 185*c8dee2aaSAndroid Build Coastguard Worker }; 186*c8dee2aaSAndroid Build Coastguard Worker 187*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 188*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 189*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(kStrokeWidth); 190*c8dee2aaSAndroid Build Coastguard Worker paint.setStroke(true); 191*c8dee2aaSAndroid Build Coastguard Worker 192*c8dee2aaSAndroid Build Coastguard Worker // Compute the union of bounds of all of our test cases. 193*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = SkRect::MakeEmpty(); 194*c8dee2aaSAndroid Build Coastguard Worker const SkRect kBounds = kThinCircle.makeOutset(kThinStrokeWidth / 2.f, 195*c8dee2aaSAndroid Build Coastguard Worker kThinStrokeWidth / 2.f); 196*c8dee2aaSAndroid Build Coastguard Worker for (const auto& m : kMatrices) { 197*c8dee2aaSAndroid Build Coastguard Worker SkRect devBounds; 198*c8dee2aaSAndroid Build Coastguard Worker m.mapRect(&devBounds, kBounds); 199*c8dee2aaSAndroid Build Coastguard Worker bounds.join(devBounds); 200*c8dee2aaSAndroid Build Coastguard Worker } 201*c8dee2aaSAndroid Build Coastguard Worker 202*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 203*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(-bounds.fLeft + kPad, -bounds.fTop + kPad); 204*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(deffects); ++i) { 205*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 206*c8dee2aaSAndroid Build Coastguard Worker for (const auto& m : kMatrices) { 207*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 208*c8dee2aaSAndroid Build Coastguard Worker canvas->concat(m); 209*c8dee2aaSAndroid Build Coastguard Worker 210*c8dee2aaSAndroid Build Coastguard Worker paint.setPathEffect(deffects[i]); 211*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(kStrokeWidth); 212*c8dee2aaSAndroid Build Coastguard Worker canvas->drawOval(kCircle, paint); 213*c8dee2aaSAndroid Build Coastguard Worker 214*c8dee2aaSAndroid Build Coastguard Worker paint.setPathEffect(thinDEffects[i]); 215*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(kThinStrokeWidth); 216*c8dee2aaSAndroid Build Coastguard Worker canvas->drawOval(kThinCircle, paint); 217*c8dee2aaSAndroid Build Coastguard Worker 218*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 219*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(bounds.width() + kPad, 0); 220*c8dee2aaSAndroid Build Coastguard Worker } 221*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 222*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, bounds.height() + kPad); 223*c8dee2aaSAndroid Build Coastguard Worker } 224*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 225*c8dee2aaSAndroid Build Coastguard Worker } 226*c8dee2aaSAndroid Build Coastguard Worker 227*c8dee2aaSAndroid Build Coastguard Worker protected: onAnimate(double nanos)228*c8dee2aaSAndroid Build Coastguard Worker bool onAnimate(double nanos) override { 229*c8dee2aaSAndroid Build Coastguard Worker fPhaseDegrees = 1e-9 * nanos; 230*c8dee2aaSAndroid Build Coastguard Worker return true; 231*c8dee2aaSAndroid Build Coastguard Worker } 232*c8dee2aaSAndroid Build Coastguard Worker 233*c8dee2aaSAndroid Build Coastguard Worker // Init with a non-zero phase for when run as a non-animating GM. 234*c8dee2aaSAndroid Build Coastguard Worker SkScalar fPhaseDegrees = 12.f; 235*c8dee2aaSAndroid Build Coastguard Worker }; 236*c8dee2aaSAndroid Build Coastguard Worker 237*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new DashCircle2GM;) 238*c8dee2aaSAndroid Build Coastguard Worker 239*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(maddash, canvas, 1600, 1600) { 240*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect({0, 0, 1600, 1600}, SkPaint()); 241*c8dee2aaSAndroid Build Coastguard Worker SkPaint p; 242*c8dee2aaSAndroid Build Coastguard Worker p.setColor(SK_ColorRED); 243*c8dee2aaSAndroid Build Coastguard Worker p.setAntiAlias(true); 244*c8dee2aaSAndroid Build Coastguard Worker p.setStroke(true); 245*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeWidth(380); 246*c8dee2aaSAndroid Build Coastguard Worker 247*c8dee2aaSAndroid Build Coastguard Worker SkScalar intvls[] = { 2.5, 10 /* 1200 */ }; 248*c8dee2aaSAndroid Build Coastguard Worker p.setPathEffect(SkDashPathEffect::Make(intvls, 2, 0)); 249*c8dee2aaSAndroid Build Coastguard Worker 250*c8dee2aaSAndroid Build Coastguard Worker canvas->drawCircle(400, 400, 200, p); 251*c8dee2aaSAndroid Build Coastguard Worker 252*c8dee2aaSAndroid Build Coastguard Worker SkPathBuilder path; 253*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(800, 400); 254*c8dee2aaSAndroid Build Coastguard Worker path.quadTo(1000, 400, 1000, 600); 255*c8dee2aaSAndroid Build Coastguard Worker path.quadTo(1000, 800, 800, 800); 256*c8dee2aaSAndroid Build Coastguard Worker path.quadTo(600, 800, 600, 600); 257*c8dee2aaSAndroid Build Coastguard Worker path.quadTo(600, 400, 800, 400); 258*c8dee2aaSAndroid Build Coastguard Worker path.close(); 259*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(350, 150); 260*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeWidth(320); 261*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path.detach(), p); 262*c8dee2aaSAndroid Build Coastguard Worker 263*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(800, 400); 264*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(900, 400, 1000, 500, 1000, 600); 265*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(1000, 700, 900, 800, 800, 800); 266*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(700, 800, 600, 700, 600, 600); 267*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(600, 500, 700, 400, 800, 400); 268*c8dee2aaSAndroid Build Coastguard Worker path.close(); 269*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(-550, 500); 270*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeWidth(300); 271*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path.detach(), p); 272*c8dee2aaSAndroid Build Coastguard Worker } 273