11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
80b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SampleCode.h"
90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkView.h"
100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCanvas.h"
110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkDevice.h"
120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPaint.h"
130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// ensure that we don't accidentally screw up the bounds when the oval is
150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// fractional, and the impl computes the center and radii, and uses them to
160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// reconstruct the edges of the circle.
170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// see bug# 1504910
180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void test_circlebounds(SkCanvas* canvas) {
190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#ifdef SK_SCALAR_IS_FLOAT
200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkRect r = { 1.39999998f, 1, 21.3999996f, 21 };
210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkPath p;
220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    p.addOval(r);
230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkASSERT(r == p.getBounds());
240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#endif
250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass CircleView : public SampleView {
280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic:
290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    static const SkScalar ANIM_DX;
300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    static const SkScalar ANIM_DY;
310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    static const SkScalar ANIM_RAD;
320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkScalar fDX, fDY, fRAD;
330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    CircleView() {
350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fDX = fDY = fRAD = 0;
360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fN = 3;
370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprotected:
400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // overrides from SkEventSink
410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool onQuery(SkEvent* evt) {
420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (SampleCode::TitleQ(*evt)) {
430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SampleCode::TitleR(evt, "Circles");
440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            return true;
450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        return this->INHERITED::onQuery(evt);
470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    void circle(SkCanvas* canvas, int width, bool aa) {
500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkPaint paint;
510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        paint.setAntiAlias(aa);
530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (width < 0) {
540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            paint.setStyle(SkPaint::kFill_Style);
550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        } else {
560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            paint.setStyle(SkPaint::kStroke_Style);
570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            paint.setStrokeWidth(SkIntToScalar(width));
580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->drawCircle(0, 0, SkIntToScalar(9) + fRAD, paint);
600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    void drawSix(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        for (int width = -1; width <= 1; width++) {
640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->save();
650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            circle(canvas, width, false);
660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->translate(0, dy);
670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            circle(canvas, width, true);
680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->restore();
690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->translate(dx, 0);
700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    static void blowup(SkCanvas* canvas, const SkIRect& src, const SkRect& dst) {
740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkDevice* device = canvas->getDevice();
750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        const SkBitmap& bm = device->accessBitmap(false);
760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->drawBitmapRect(bm, &src, dst, NULL);
770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    static void make_poly(SkPath* path, int n) {
800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (n <= 0) {
810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            return;
820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        path->incReserve(n + 1);
840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        path->moveTo(SK_Scalar1, 0);
850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkScalar step = SK_ScalarPI * 2 / n;
860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkScalar angle = 0;
870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        for (int i = 1; i < n; i++) {
880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            angle += step;
890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkScalar c, s = SkScalarSinCos(angle, &c);
900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            path->lineTo(c, s);
910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        path->close();
930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    static void rotate(SkCanvas* canvas, SkScalar angle, SkScalar px, SkScalar py) {
960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->translate(-px, -py);
970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->rotate(angle);
980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->translate(px, py);
990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void onDrawContent(SkCanvas* canvas) {
1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkPaint paint;
1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        paint.setAntiAlias(true);
1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        paint.setStyle(SkPaint::kStroke_Style);
1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//        canvas->drawCircle(250, 250, 220, paint);
1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkMatrix matrix;
1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        matrix.setScale(SkIntToScalar(100), SkIntToScalar(100));
1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200));
1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->concat(matrix);
1100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        for (int n = 3; n < 20; n++) {
1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkPath path;
1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            make_poly(&path, n);
1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkAutoCanvasRestore acr(canvas, true);
1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->rotate(SkIntToScalar(10) * (n - 3));
1150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->translate(-SK_Scalar1, 0);
1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->drawPath(path, paint);
1170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
1180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate:
1210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    int fN;
1220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    typedef SampleView INHERITED;
1230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger};
1240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerconst SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67);
1260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerconst SkScalar CircleView::ANIM_DY(SK_Scalar1 / 29);
1270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerconst SkScalar CircleView::ANIM_RAD(SK_Scalar1 / 19);
1280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//////////////////////////////////////////////////////////////////////////////
1300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkView* MyFactory() { return new CircleView; }
1320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkViewRegister reg(MyFactory);
1330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
134