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