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