1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDevice.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// ensure that we don't accidentally screw up the bounds when the oval is
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// fractional, and the impl computes the center and radii, and uses them to
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// reconstruct the edges of the circle.
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// see bug# 1504910
1893c7ee34dc5c8f6bfad65809f4b39f8d00d7f0d4sugoi@google.comstatic void test_circlebounds(SkCanvas*) {
19261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com    SkRect r = { 1.39999998f, 1, 21.3999996f, 21 };
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath p;
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    p.addOval(r);
22d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    SkASSERT(r == p.getBounds());
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
255fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.orgclass CircleView : public SampleView {
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
27f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    static const SkScalar ANIM_DX;
28f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    static const SkScalar ANIM_DY;
29f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    static const SkScalar ANIM_RAD;
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar fDX, fDY, fRAD;
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    CircleView() {
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fDX = fDY = fRAD = 0;
347a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        fN = 3;
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
36ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // overrides from SkEventSink
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual bool onQuery(SkEvent* evt) {
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (SampleCode::TitleQ(*evt)) {
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SampleCode::TitleR(evt, "Circles");
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::onQuery(evt);
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
46ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void circle(SkCanvas* canvas, int width, bool aa) {
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPaint paint;
49ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAntiAlias(aa);
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (width < 0) {
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            paint.setStyle(SkPaint::kFill_Style);
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            paint.setStyle(SkPaint::kStroke_Style);
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            paint.setStrokeWidth(SkIntToScalar(width));
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawCircle(0, 0, SkIntToScalar(9) + fRAD, paint);
5802939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com        if (false) { // avoid bit rot, suppress warning
5902939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com            test_circlebounds(canvas);
6002939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com        }
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
62ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void drawSix(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int width = -1; width <= 1; width++) {
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            canvas->save();
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            circle(canvas, width, false);
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            canvas->translate(0, dy);
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            circle(canvas, width, true);
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            canvas->restore();
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            canvas->translate(dx, 0);
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
73ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
747a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    static void make_poly(SkPath* path, int n) {
757a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        if (n <= 0) {
767a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            return;
777a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        }
787a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        path->incReserve(n + 1);
797a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        path->moveTo(SK_Scalar1, 0);
807a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        SkScalar step = SK_ScalarPI * 2 / n;
817a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        SkScalar angle = 0;
827a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        for (int i = 1; i < n; i++) {
837a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            angle += step;
847a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            SkScalar c, s = SkScalarSinCos(angle, &c);
857a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            path->lineTo(c, s);
867a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        }
877a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        path->close();
887a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    }
89ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
907a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    static void rotate(SkCanvas* canvas, SkScalar angle, SkScalar px, SkScalar py) {
917a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        canvas->translate(-px, -py);
927a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        canvas->rotate(angle);
937a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        canvas->translate(px, py);
947a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    }
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
965fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    virtual void onDrawContent(SkCanvas* canvas) {
977a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        SkPaint paint;
987a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        paint.setAntiAlias(true);
997a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        paint.setStyle(SkPaint::kStroke_Style);
1007a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com//        canvas->drawCircle(250, 250, 220, paint);
1017a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        SkMatrix matrix;
1027a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        matrix.setScale(SkIntToScalar(100), SkIntToScalar(100));
1037a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200));
1047a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        canvas->concat(matrix);
1057a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        for (int n = 3; n < 20; n++) {
1067a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            SkPath path;
1077a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            make_poly(&path, n);
1087a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            SkAutoCanvasRestore acr(canvas, true);
1097a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            canvas->rotate(SkIntToScalar(10) * (n - 3));
1107a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            canvas->translate(-SK_Scalar1, 0);
1117a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com            canvas->drawPath(path, paint);
1127a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        }
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
114ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
1167a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    int fN;
1175fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    typedef SampleView INHERITED;
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
120f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comconst SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67);
121f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comconst SkScalar CircleView::ANIM_DY(SK_Scalar1 / 29);
122f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comconst SkScalar CircleView::ANIM_RAD(SK_Scalar1 / 19);
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new CircleView; }
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory);
128