| /* | |
| * Copyright 2011 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "SampleCode.h" | |
| #include "SkCanvas.h" | |
| #include "SkDevice.h" | |
| #include "SkPaint.h" | |
| #include "SkPath.h" | |
| #include "SkView.h" | |
| // ensure that we don't accidentally screw up the bounds when the oval is | |
| // fractional, and the impl computes the center and radii, and uses them to | |
| // reconstruct the edges of the circle. | |
| // see bug# 1504910 | |
| static void test_circlebounds(SkCanvas*) { | |
| SkRect r = { 1.39999998f, 1, 21.3999996f, 21 }; | |
| SkPath p; | |
| p.addOval(r); | |
| SkASSERT(r == p.getBounds()); | |
| } | |
| class CircleView : public SampleView { | |
| public: | |
| static const SkScalar ANIM_DX; | |
| static const SkScalar ANIM_DY; | |
| static const SkScalar ANIM_RAD; | |
| SkScalar fDX, fDY, fRAD; | |
| CircleView() { | |
| fDX = fDY = fRAD = 0; | |
| fN = 3; | |
| } | |
| protected: | |
| // overrides from SkEventSink | |
| virtual bool onQuery(SkEvent* evt) { | |
| if (SampleCode::TitleQ(*evt)) { | |
| SampleCode::TitleR(evt, "Circles"); | |
| return true; | |
| } | |
| return this->INHERITED::onQuery(evt); | |
| } | |
| void circle(SkCanvas* canvas, int width, bool aa) { | |
| SkPaint paint; | |
| paint.setAntiAlias(aa); | |
| if (width < 0) { | |
| paint.setStyle(SkPaint::kFill_Style); | |
| } else { | |
| paint.setStyle(SkPaint::kStroke_Style); | |
| paint.setStrokeWidth(SkIntToScalar(width)); | |
| } | |
| canvas->drawCircle(0, 0, SkIntToScalar(9) + fRAD, paint); | |
| if (false) { // avoid bit rot, suppress warning | |
| test_circlebounds(canvas); | |
| } | |
| } | |
| void drawSix(SkCanvas* canvas, SkScalar dx, SkScalar dy) { | |
| for (int width = -1; width <= 1; width++) { | |
| canvas->save(); | |
| circle(canvas, width, false); | |
| canvas->translate(0, dy); | |
| circle(canvas, width, true); | |
| canvas->restore(); | |
| canvas->translate(dx, 0); | |
| } | |
| } | |
| static void make_poly(SkPath* path, int n) { | |
| if (n <= 0) { | |
| return; | |
| } | |
| path->incReserve(n + 1); | |
| path->moveTo(SK_Scalar1, 0); | |
| SkScalar step = SK_ScalarPI * 2 / n; | |
| SkScalar angle = 0; | |
| for (int i = 1; i < n; i++) { | |
| angle += step; | |
| SkScalar c, s = SkScalarSinCos(angle, &c); | |
| path->lineTo(c, s); | |
| } | |
| path->close(); | |
| } | |
| static void rotate(SkCanvas* canvas, SkScalar angle, SkScalar px, SkScalar py) { | |
| canvas->translate(-px, -py); | |
| canvas->rotate(angle); | |
| canvas->translate(px, py); | |
| } | |
| virtual void onDrawContent(SkCanvas* canvas) { | |
| SkPaint paint; | |
| paint.setAntiAlias(true); | |
| paint.setStyle(SkPaint::kStroke_Style); | |
| // canvas->drawCircle(250, 250, 220, paint); | |
| SkMatrix matrix; | |
| matrix.setScale(SkIntToScalar(100), SkIntToScalar(100)); | |
| matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200)); | |
| canvas->concat(matrix); | |
| for (int n = 3; n < 20; n++) { | |
| SkPath path; | |
| make_poly(&path, n); | |
| SkAutoCanvasRestore acr(canvas, true); | |
| canvas->rotate(SkIntToScalar(10) * (n - 3)); | |
| canvas->translate(-SK_Scalar1, 0); | |
| canvas->drawPath(path, paint); | |
| } | |
| } | |
| private: | |
| int fN; | |
| typedef SampleView INHERITED; | |
| }; | |
| const SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67); | |
| const SkScalar CircleView::ANIM_DY(SK_Scalar1 / 29); | |
| const SkScalar CircleView::ANIM_RAD(SK_Scalar1 / 19); | |
| ////////////////////////////////////////////////////////////////////////////// | |
| static SkView* MyFactory() { return new CircleView; } | |
| static SkViewRegister reg(MyFactory); |