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 "SkPaint.h" 11#include "SkPath.h" 12#include "SkView.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 18static 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 25class CircleView : public SampleView { 26public: 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 37protected: 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 virtual void onDrawContent(SkCanvas* canvas) { 91 SkPaint paint; 92 paint.setAntiAlias(true); 93 paint.setStyle(SkPaint::kStroke_Style); 94 SkMatrix matrix; 95 matrix.setScale(SkIntToScalar(100), SkIntToScalar(100)); 96 matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200)); 97 canvas->concat(matrix); 98 for (int n = 3; n < 20; n++) { 99 SkPath path; 100 make_poly(&path, n); 101 SkAutoCanvasRestore acr(canvas, true); 102 canvas->rotate(SkIntToScalar(10) * (n - 3)); 103 canvas->translate(-SK_Scalar1, 0); 104 canvas->drawPath(path, paint); 105 } 106 } 107 108private: 109 int fN; 110 typedef SampleView INHERITED; 111}; 112 113const SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67); 114const SkScalar CircleView::ANIM_DY(SK_Scalar1 / 29); 115const SkScalar CircleView::ANIM_RAD(SK_Scalar1 / 19); 116 117////////////////////////////////////////////////////////////////////////////// 118 119static SkView* MyFactory() { return new CircleView; } 120static SkViewRegister reg(MyFactory); 121