1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SampleCode.h" 9 #include "SkCanvas.h" 10 #include "SkDevice.h" 11 #include "SkPaint.h" 12 #include "SkPath.h" 13 #include "SkView.h" 14 15 // ensure that we don't accidentally screw up the bounds when the oval is 16 // fractional, and the impl computes the center and radii, and uses them to 17 // reconstruct the edges of the circle. 18 // see bug# 1504910 19 static void test_circlebounds(SkCanvas*) { 20 SkRect r = { 1.39999998f, 1, 21.3999996f, 21 }; 21 SkPath p; 22 p.addOval(r); 23 SkASSERT(r == p.getBounds()); 24 } 25 26 class CircleView : public SampleView { 27 public: 28 static const SkScalar ANIM_DX; 29 static const SkScalar ANIM_DY; 30 static const SkScalar ANIM_RAD; 31 SkScalar fDX, fDY, fRAD; 32 33 CircleView() { 34 fDX = fDY = fRAD = 0; 35 fN = 3; 36 } 37 38 protected: 39 // overrides from SkEventSink 40 virtual bool onQuery(SkEvent* evt) { 41 if (SampleCode::TitleQ(*evt)) { 42 SampleCode::TitleR(evt, "Circles"); 43 return true; 44 } 45 return this->INHERITED::onQuery(evt); 46 } 47 48 void circle(SkCanvas* canvas, int width, bool aa) { 49 SkPaint paint; 50 51 paint.setAntiAlias(aa); 52 if (width < 0) { 53 paint.setStyle(SkPaint::kFill_Style); 54 } else { 55 paint.setStyle(SkPaint::kStroke_Style); 56 paint.setStrokeWidth(SkIntToScalar(width)); 57 } 58 canvas->drawCircle(0, 0, SkIntToScalar(9) + fRAD, paint); 59 if (false) { // avoid bit rot, suppress warning 60 test_circlebounds(canvas); 61 } 62 } 63 64 void drawSix(SkCanvas* canvas, SkScalar dx, SkScalar dy) { 65 for (int width = -1; width <= 1; width++) { 66 canvas->save(); 67 circle(canvas, width, false); 68 canvas->translate(0, dy); 69 circle(canvas, width, true); 70 canvas->restore(); 71 canvas->translate(dx, 0); 72 } 73 } 74 75 static void make_poly(SkPath* path, int n) { 76 if (n <= 0) { 77 return; 78 } 79 path->incReserve(n + 1); 80 path->moveTo(SK_Scalar1, 0); 81 SkScalar step = SK_ScalarPI * 2 / n; 82 SkScalar angle = 0; 83 for (int i = 1; i < n; i++) { 84 angle += step; 85 SkScalar c, s = SkScalarSinCos(angle, &c); 86 path->lineTo(c, s); 87 } 88 path->close(); 89 } 90 91 static void rotate(SkCanvas* canvas, SkScalar angle, SkScalar px, SkScalar py) { 92 canvas->translate(-px, -py); 93 canvas->rotate(angle); 94 canvas->translate(px, py); 95 } 96 97 virtual void onDrawContent(SkCanvas* canvas) { 98 SkPaint paint; 99 paint.setAntiAlias(true); 100 paint.setStyle(SkPaint::kStroke_Style); 101 // canvas->drawCircle(250, 250, 220, paint); 102 SkMatrix matrix; 103 matrix.setScale(SkIntToScalar(100), SkIntToScalar(100)); 104 matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200)); 105 canvas->concat(matrix); 106 for (int n = 3; n < 20; n++) { 107 SkPath path; 108 make_poly(&path, n); 109 SkAutoCanvasRestore acr(canvas, true); 110 canvas->rotate(SkIntToScalar(10) * (n - 3)); 111 canvas->translate(-SK_Scalar1, 0); 112 canvas->drawPath(path, paint); 113 } 114 } 115 116 private: 117 int fN; 118 typedef SampleView INHERITED; 119 }; 120 121 const SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67); 122 const SkScalar CircleView::ANIM_DY(SK_Scalar1 / 29); 123 const SkScalar CircleView::ANIM_RAD(SK_Scalar1 / 19); 124 125 ////////////////////////////////////////////////////////////////////////////// 126 127 static SkView* MyFactory() { return new CircleView; } 128 static SkViewRegister reg(MyFactory); 129