addarc.cpp revision 8ed666d230231c7280069236f265a61edb8a9a20
119d8f9f17373bcf7d352b77e72a6a46568ee8a8breed/* 219d8f9f17373bcf7d352b77e72a6a46568ee8a8breed * Copyright 2015 Google Inc. 319d8f9f17373bcf7d352b77e72a6a46568ee8a8breed * 419d8f9f17373bcf7d352b77e72a6a46568ee8a8breed * Use of this source code is governed by a BSD-style license that can be 519d8f9f17373bcf7d352b77e72a6a46568ee8a8breed * found in the LICENSE file. 619d8f9f17373bcf7d352b77e72a6a46568ee8a8breed */ 719d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 819d8f9f17373bcf7d352b77e72a6a46568ee8a8breed#include "gm.h" 976113a9b7716748c70ea0ecf7aacbabe4cce5009reed#include "SkAnimTimer.h" 1019d8f9f17373bcf7d352b77e72a6a46568ee8a8breed#include "SkCanvas.h" 1161adb1b6491db3d3552d09a1c69ba5a37beb38d5reed#include "SkPathMeasure.h" 1219d8f9f17373bcf7d352b77e72a6a46568ee8a8breed#include "SkRandom.h" 1319d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 1419d8f9f17373bcf7d352b77e72a6a46568ee8a8breedclass AddArcGM : public skiagm::GM { 15d9adfe6a223955bc69c8c7661ab8e0a078afbc32reedpublic: 16d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed AddArcGM() : fRotate(0) {} 17d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed 1819d8f9f17373bcf7d352b77e72a6a46568ee8a8breedprotected: 1919d8f9f17373bcf7d352b77e72a6a46568ee8a8breed SkString onShortName() SK_OVERRIDE { return SkString("addarc"); } 2019d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 2119d8f9f17373bcf7d352b77e72a6a46568ee8a8breed SkISize onISize() SK_OVERRIDE { return SkISize::Make(1040, 1040); } 2219d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 2319d8f9f17373bcf7d352b77e72a6a46568ee8a8breed void onDraw(SkCanvas* canvas) SK_OVERRIDE { 2419d8f9f17373bcf7d352b77e72a6a46568ee8a8breed canvas->translate(20, 20); 2519d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 2619d8f9f17373bcf7d352b77e72a6a46568ee8a8breed SkRect r = SkRect::MakeWH(1000, 1000); 2719d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 2819d8f9f17373bcf7d352b77e72a6a46568ee8a8breed SkPaint paint; 2919d8f9f17373bcf7d352b77e72a6a46568ee8a8breed paint.setAntiAlias(true); 3019d8f9f17373bcf7d352b77e72a6a46568ee8a8breed paint.setStyle(SkPaint::kStroke_Style); 3119d8f9f17373bcf7d352b77e72a6a46568ee8a8breed paint.setStrokeWidth(15); 3219d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 3319d8f9f17373bcf7d352b77e72a6a46568ee8a8breed const SkScalar inset = paint.getStrokeWidth() + 4; 3419d8f9f17373bcf7d352b77e72a6a46568ee8a8breed const SkScalar sweepAngle = 345; 3519d8f9f17373bcf7d352b77e72a6a46568ee8a8breed SkRandom rand; 3619d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 37d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed SkScalar sign = 1; 3819d8f9f17373bcf7d352b77e72a6a46568ee8a8breed while (r.width() > paint.getStrokeWidth() * 3) { 3919d8f9f17373bcf7d352b77e72a6a46568ee8a8breed paint.setColor(rand.nextU() | (0xFF << 24)); 4019d8f9f17373bcf7d352b77e72a6a46568ee8a8breed SkScalar startAngle = rand.nextUScalar1() * 360; 4119d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 42d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed SkScalar speed = SkScalarSqrt(16 / r.width()) * 0.5f; 43d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed startAngle += fRotate * 360 * speed * sign; 44d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed 4519d8f9f17373bcf7d352b77e72a6a46568ee8a8breed SkPath path; 4619d8f9f17373bcf7d352b77e72a6a46568ee8a8breed path.addArc(r, startAngle, sweepAngle); 4719d8f9f17373bcf7d352b77e72a6a46568ee8a8breed canvas->drawPath(path, paint); 4819d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 4919d8f9f17373bcf7d352b77e72a6a46568ee8a8breed r.inset(inset, inset); 50d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed sign = -sign; 5119d8f9f17373bcf7d352b77e72a6a46568ee8a8breed } 5219d8f9f17373bcf7d352b77e72a6a46568ee8a8breed } 5319d8f9f17373bcf7d352b77e72a6a46568ee8a8breed 5476113a9b7716748c70ea0ecf7aacbabe4cce5009reed bool onAnimate(const SkAnimTimer& timer) SK_OVERRIDE { 5576113a9b7716748c70ea0ecf7aacbabe4cce5009reed fRotate = timer.scaled(1, 360); 56d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed return true; 57d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed } 58d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed 5919d8f9f17373bcf7d352b77e72a6a46568ee8a8breedprivate: 60d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed SkScalar fRotate; 6119d8f9f17373bcf7d352b77e72a6a46568ee8a8breed typedef skiagm::GM INHERITED; 6219d8f9f17373bcf7d352b77e72a6a46568ee8a8breed}; 6319d8f9f17373bcf7d352b77e72a6a46568ee8a8breedDEF_GM( return new AddArcGM; ) 6461adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 6561adb1b6491db3d3552d09a1c69ba5a37beb38d5reed/////////////////////////////////////////////////// 6661adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 6761adb1b6491db3d3552d09a1c69ba5a37beb38d5reed#define R 400 6861adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 6961adb1b6491db3d3552d09a1c69ba5a37beb38d5reedclass AddArcMeasGM : public skiagm::GM { 7061adb1b6491db3d3552d09a1c69ba5a37beb38d5reedpublic: 7161adb1b6491db3d3552d09a1c69ba5a37beb38d5reed AddArcMeasGM() {} 7261adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 7361adb1b6491db3d3552d09a1c69ba5a37beb38d5reedprotected: 7461adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkString onShortName() SK_OVERRIDE { return SkString("addarc_meas"); } 7561adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 7661adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkISize onISize() SK_OVERRIDE { return SkISize::Make(2*R + 40, 2*R + 40); } 7761adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 7861adb1b6491db3d3552d09a1c69ba5a37beb38d5reed void onDraw(SkCanvas* canvas) SK_OVERRIDE { 7961adb1b6491db3d3552d09a1c69ba5a37beb38d5reed canvas->translate(R + 20, R + 20); 8061adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 8161adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkPaint paint; 8261adb1b6491db3d3552d09a1c69ba5a37beb38d5reed paint.setAntiAlias(true); 8361adb1b6491db3d3552d09a1c69ba5a37beb38d5reed paint.setStyle(SkPaint::kStroke_Style); 8461adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 8561adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkPaint measPaint; 8661adb1b6491db3d3552d09a1c69ba5a37beb38d5reed measPaint.setAntiAlias(true); 8761adb1b6491db3d3552d09a1c69ba5a37beb38d5reed measPaint.setColor(SK_ColorRED); 8861adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 8961adb1b6491db3d3552d09a1c69ba5a37beb38d5reed const SkRect oval = SkRect::MakeLTRB(-R, -R, R, R); 9061adb1b6491db3d3552d09a1c69ba5a37beb38d5reed canvas->drawOval(oval, paint); 9161adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 9261adb1b6491db3d3552d09a1c69ba5a37beb38d5reed for (SkScalar deg = 0; deg < 360; deg += 10) { 9361adb1b6491db3d3552d09a1c69ba5a37beb38d5reed const SkScalar rad = SkDegreesToRadians(deg); 9461adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkScalar rx = SkScalarCos(rad) * R; 9561adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkScalar ry = SkScalarSin(rad) * R; 9661adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 9761adb1b6491db3d3552d09a1c69ba5a37beb38d5reed canvas->drawLine(0, 0, rx, ry, paint); 9861adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 9961adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkPath path; 10061adb1b6491db3d3552d09a1c69ba5a37beb38d5reed path.addArc(oval, 0, deg); 10161adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkPathMeasure meas(path, false); 10261adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkScalar arcLen = rad * R; 10361adb1b6491db3d3552d09a1c69ba5a37beb38d5reed SkPoint pos; 10461adb1b6491db3d3552d09a1c69ba5a37beb38d5reed if (meas.getPosTan(arcLen, &pos, NULL)) { 10561adb1b6491db3d3552d09a1c69ba5a37beb38d5reed canvas->drawLine(0, 0, pos.x(), pos.y(), measPaint); 10661adb1b6491db3d3552d09a1c69ba5a37beb38d5reed } 10761adb1b6491db3d3552d09a1c69ba5a37beb38d5reed } 10861adb1b6491db3d3552d09a1c69ba5a37beb38d5reed } 10961adb1b6491db3d3552d09a1c69ba5a37beb38d5reed 11061adb1b6491db3d3552d09a1c69ba5a37beb38d5reedprivate: 11161adb1b6491db3d3552d09a1c69ba5a37beb38d5reed typedef skiagm::GM INHERITED; 11261adb1b6491db3d3552d09a1c69ba5a37beb38d5reed}; 11361adb1b6491db3d3552d09a1c69ba5a37beb38d5reedDEF_GM( return new AddArcMeasGM; ) 1148ed666d230231c7280069236f265a61edb8a9a20reed 1158ed666d230231c7280069236f265a61edb8a9a20reed/////////////////////////////////////////////////// 1168ed666d230231c7280069236f265a61edb8a9a20reed 1178ed666d230231c7280069236f265a61edb8a9a20reed// Emphasize drawing a stroked oval (containing conics) and then scaling the results up, 1188ed666d230231c7280069236f265a61edb8a9a20reed// to ensure that we compute the stroke taking the CTM into account 1198ed666d230231c7280069236f265a61edb8a9a20reed// 1208ed666d230231c7280069236f265a61edb8a9a20reedclass StrokeCircleGM : public skiagm::GM { 1218ed666d230231c7280069236f265a61edb8a9a20reedpublic: 1228ed666d230231c7280069236f265a61edb8a9a20reed StrokeCircleGM() : fRotate(0) {} 1238ed666d230231c7280069236f265a61edb8a9a20reed 1248ed666d230231c7280069236f265a61edb8a9a20reedprotected: 1258ed666d230231c7280069236f265a61edb8a9a20reed SkString onShortName() SK_OVERRIDE { return SkString("strokecircle"); } 1268ed666d230231c7280069236f265a61edb8a9a20reed 1278ed666d230231c7280069236f265a61edb8a9a20reed SkISize onISize() SK_OVERRIDE { return SkISize::Make(520, 520); } 1288ed666d230231c7280069236f265a61edb8a9a20reed 1298ed666d230231c7280069236f265a61edb8a9a20reed void onDraw(SkCanvas* canvas) SK_OVERRIDE { 1308ed666d230231c7280069236f265a61edb8a9a20reed canvas->scale(20, 20); 1318ed666d230231c7280069236f265a61edb8a9a20reed canvas->translate(13, 13); 1328ed666d230231c7280069236f265a61edb8a9a20reed 1338ed666d230231c7280069236f265a61edb8a9a20reed SkPaint paint; 1348ed666d230231c7280069236f265a61edb8a9a20reed paint.setAntiAlias(true); 1358ed666d230231c7280069236f265a61edb8a9a20reed paint.setStyle(SkPaint::kStroke_Style); 1368ed666d230231c7280069236f265a61edb8a9a20reed paint.setStrokeWidth(SK_Scalar1 / 2); 1378ed666d230231c7280069236f265a61edb8a9a20reed 1388ed666d230231c7280069236f265a61edb8a9a20reed const SkScalar delta = paint.getStrokeWidth() * 3 / 2; 1398ed666d230231c7280069236f265a61edb8a9a20reed SkRect r = SkRect::MakeXYWH(-12, -12, 24, 24); 1408ed666d230231c7280069236f265a61edb8a9a20reed SkRandom rand; 1418ed666d230231c7280069236f265a61edb8a9a20reed 1428ed666d230231c7280069236f265a61edb8a9a20reed SkScalar sign = 1; 1438ed666d230231c7280069236f265a61edb8a9a20reed while (r.width() > paint.getStrokeWidth() * 2) { 1448ed666d230231c7280069236f265a61edb8a9a20reed SkAutoCanvasRestore acr(canvas, true); 1458ed666d230231c7280069236f265a61edb8a9a20reed canvas->rotate(fRotate * sign); 1468ed666d230231c7280069236f265a61edb8a9a20reed 1478ed666d230231c7280069236f265a61edb8a9a20reed paint.setColor(rand.nextU() | (0xFF << 24)); 1488ed666d230231c7280069236f265a61edb8a9a20reed canvas->drawOval(r, paint); 1498ed666d230231c7280069236f265a61edb8a9a20reed r.inset(delta, delta); 1508ed666d230231c7280069236f265a61edb8a9a20reed sign = -sign; 1518ed666d230231c7280069236f265a61edb8a9a20reed } 1528ed666d230231c7280069236f265a61edb8a9a20reed } 1538ed666d230231c7280069236f265a61edb8a9a20reed 1548ed666d230231c7280069236f265a61edb8a9a20reed bool onAnimate(const SkAnimTimer& timer) SK_OVERRIDE { 1558ed666d230231c7280069236f265a61edb8a9a20reed fRotate = timer.scaled(60, 360); 1568ed666d230231c7280069236f265a61edb8a9a20reed return true; 1578ed666d230231c7280069236f265a61edb8a9a20reed } 1588ed666d230231c7280069236f265a61edb8a9a20reed 1598ed666d230231c7280069236f265a61edb8a9a20reedprivate: 1608ed666d230231c7280069236f265a61edb8a9a20reed SkScalar fRotate; 1618ed666d230231c7280069236f265a61edb8a9a20reed 1628ed666d230231c7280069236f265a61edb8a9a20reed typedef skiagm::GM INHERITED; 1638ed666d230231c7280069236f265a61edb8a9a20reed}; 1648ed666d230231c7280069236f265a61edb8a9a20reedDEF_GM( return new StrokeCircleGM; ) 165