blob: 1375726c367db85b667d10e18dc2fb663d25af36 [file] [log] [blame]
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkColor.h"
11#include "include/core/SkPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkPath.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040013#include "include/core/SkPoint.h"
14#include "include/core/SkRect.h"
15#include "include/core/SkScalar.h"
16#include "include/core/SkSize.h"
17#include "include/core/SkString.h"
18#include "include/core/SkTypes.h"
19#include "include/private/SkFloatBits.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "include/private/SkTArray.h"
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000021
reedd1bd1d72014-12-31 20:07:01 -080022class ConicPathsGM : public skiagm::GM {
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000023protected:
24
mtklein36352bf2015-03-25 18:17:31 -070025 SkString onShortName() override {
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000026 return SkString("conicpaths");
27 }
28
mtklein36352bf2015-03-25 18:17:31 -070029 SkISize onISize() override {
reed40c85e42015-01-05 10:01:25 -080030 return SkISize::Make(920, 960);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000031 }
32
mtklein36352bf2015-03-25 18:17:31 -070033 void onOnceBeforeDraw() override {
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000034 {
reedd1bd1d72014-12-31 20:07:01 -080035 const SkScalar w = SkScalarSqrt(2)/2;
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000036 SkPath* conicCirlce = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080037 conicCirlce->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080038 conicCirlce->conicTo(0, 50, 50, 50, w);
39 conicCirlce->rConicTo(50, 0, 50, -50, w);
40 conicCirlce->rConicTo(0, -50, -50, -50, w);
41 conicCirlce->rConicTo(-50, 0, -50, 50, w);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000042
43 }
44 {
45 SkPath* hyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080046 hyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080047 hyperbola->conicTo(0, 100, 100, 100, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000048 }
49 {
50 SkPath* thinHyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080051 thinHyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080052 thinHyperbola->conicTo(100, 100, 5, 0, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000053 }
54 {
55 SkPath* veryThinHyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080056 veryThinHyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080057 veryThinHyperbola->conicTo(100, 100, 1, 0, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000058 }
59 {
60 SkPath* closedHyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080061 closedHyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080062 closedHyperbola->conicTo(100, 100, 0, 0, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000063 }
64 {
65 // using 1 as weight defaults to using quadTo
66 SkPath* nearParabola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080067 nearParabola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080068 nearParabola->conicTo(0, 100, 100, 100, 0.999f);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000069 }
70 {
71 SkPath* thinEllipse = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080072 thinEllipse->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080073 thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000074 }
75 {
76 SkPath* veryThinEllipse = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080077 veryThinEllipse->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080078 veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000079 }
80 {
81 SkPath* closedEllipse = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080082 closedEllipse->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080083 closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000084 }
egdaniel5a23a142015-02-25 06:41:47 -080085 {
86 const SkScalar w = SkScalarSqrt(2)/2;
87 fGiantCircle.moveTo(2.1e+11f, -1.05e+11f);
88 fGiantCircle.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w);
89 fGiantCircle.conicTo(0, 0, 0, -1.05e+11f, w);
90 fGiantCircle.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w);
91 fGiantCircle.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w);
92
93 }
94 }
95
96 void drawGiantCircle(SkCanvas* canvas) {
97 SkPaint paint;
98 canvas->drawPath(fGiantCircle, paint);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000099 }
100
mtklein36352bf2015-03-25 18:17:31 -0700101 void onDraw(SkCanvas* canvas) override {
reedd1bd1d72014-12-31 20:07:01 -0800102 const SkAlpha kAlphaValue[] = { 0xFF, 0x40 };
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000103
reedd1bd1d72014-12-31 20:07:01 -0800104 const SkScalar margin = 15;
105 canvas->translate(margin, margin);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000106
reed40c85e42015-01-05 10:01:25 -0800107 SkPaint paint;
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000108 for (int p = 0; p < fPaths.count(); ++p) {
reed40c85e42015-01-05 10:01:25 -0800109 canvas->save();
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000110 for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) {
reed40c85e42015-01-05 10:01:25 -0800111 paint.setARGB(kAlphaValue[a], 0, 0, 0);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000112 for (int aa = 0; aa < 2; ++aa) {
reed40c85e42015-01-05 10:01:25 -0800113 paint.setAntiAlias(SkToBool(aa));
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000114 for (int fh = 0; fh < 2; ++fh) {
Mike Reed19630092020-05-18 21:25:44 -0400115 paint.setStroke(fh != 0);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000116
117 const SkRect& bounds = fPaths[p].getBounds();
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000118 canvas->save();
119 canvas->translate(-bounds.fLeft, -bounds.fTop);
120 canvas->drawPath(fPaths[p], paint);
121 canvas->restore();
122
reed40c85e42015-01-05 10:01:25 -0800123 canvas->translate(110, 0);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000124 }
125 }
126 }
reed40c85e42015-01-05 10:01:25 -0800127 canvas->restore();
128 canvas->translate(0, 110);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000129 }
130 canvas->restore();
egdaniel5a23a142015-02-25 06:41:47 -0800131
halcanary9d524f22016-03-29 09:03:52 -0700132 this->drawGiantCircle(canvas);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000133 }
134
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000135private:
136 SkTArray<SkPath> fPaths;
egdaniel5a23a142015-02-25 06:41:47 -0800137 SkPath fGiantCircle;
reedd1bd1d72014-12-31 20:07:01 -0800138 typedef skiagm::GM INHERITED;
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000139};
halcanary385fe4d2015-08-26 13:07:48 -0700140DEF_GM(return new ConicPathsGM;)
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000141
142//////////////////////////////////////////////////////////////////////////////
143
caryclark2b39ffc2016-01-20 07:46:05 -0800144/* arc should be on top of circle */
145DEF_SIMPLE_GM(arccirclegap, canvas, 250, 250) {
146 canvas->translate(50, 100);
147 SkPoint c = { 1052.5390625f, 506.8760978034711f };
148 SkScalar radius = 1096.702150363923f;
149 SkPaint paint;
150 paint.setAntiAlias(true);
Mike Reed19630092020-05-18 21:25:44 -0400151 paint.setStroke(true);
Hal Canary23e474c2017-05-15 13:35:35 -0400152 canvas->drawCircle(c, radius, paint);
caryclark2b39ffc2016-01-20 07:46:05 -0800153 SkPath path;
154 path.moveTo(288.88884710654133f, -280.26680862609f);
155 path.arcTo(0, 0, -39.00216443306411f, 400.6058925796476f, radius);
156 paint.setColor(0xff007f00);
157 canvas->drawPath(path, paint);
158}
caryclark531191f2016-08-24 11:59:30 -0700159
Jim Van Verth6750e912016-12-19 14:45:19 -0500160/* circle should be antialiased */
161DEF_SIMPLE_GM(largecircle, canvas, 250, 250) {
162 canvas->translate(50, 100);
163 SkPoint c = { 1052.5390625f, 506.8760978034711f };
164 SkScalar radius = 1096.702150363923f;
165 SkPaint paint;
166 paint.setAntiAlias(true);
Mike Reed19630092020-05-18 21:25:44 -0400167 paint.setStroke(true);
Hal Canary23e474c2017-05-15 13:35:35 -0400168 canvas->drawCircle(c, radius, paint);
Jim Van Verth6750e912016-12-19 14:45:19 -0500169}
170
Jim Van Verth20ae25c2019-03-29 08:50:41 -0400171/* ovals should not be blurry */
172DEF_SIMPLE_GM(largeovals, canvas, 250, 250) {
173 // Test EllipseOp
174 SkRect r = SkRect::MakeXYWH(-520, -520, 5000, 4000);
175 SkPaint paint;
176 paint.setAntiAlias(true);
Mike Reed19630092020-05-18 21:25:44 -0400177 paint.setStroke(true);
Jim Van Verth20ae25c2019-03-29 08:50:41 -0400178 paint.setStrokeWidth(100);
179 canvas->drawOval(r, paint);
180 r.offset(-15, -15);
181 paint.setColor(SK_ColorDKGRAY);
182 // we use stroke and fill to avoid falling into the SimpleFill path
183 paint.setStyle(SkPaint::kStrokeAndFill_Style);
184 paint.setStrokeWidth(1);
185 canvas->drawOval(r, paint);
186
187 // Test DIEllipseOp
188 canvas->rotate(1.0f);
189 r.offset(55, 55);
190 paint.setColor(SK_ColorGRAY);
Mike Reed19630092020-05-18 21:25:44 -0400191 paint.setStroke(true);
Jim Van Verth20ae25c2019-03-29 08:50:41 -0400192 paint.setStrokeWidth(100);
193 canvas->drawOval(r, paint);
194 r.offset(-15, -15);
195 paint.setColor(SK_ColorLTGRAY);
196 paint.setStyle(SkPaint::kStrokeAndFill_Style);
197 paint.setStrokeWidth(1);
198 canvas->drawOval(r, paint);
199}
200
caryclark531191f2016-08-24 11:59:30 -0700201DEF_SIMPLE_GM(crbug_640176, canvas, 250, 250) {
202 SkPath path;
203 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
204 path.lineTo(SkBits2Float(0x42cfd89a), SkBits2Float(0xc2700000)); // 103.923f, -60
205 path.lineTo(SkBits2Float(0x42cfd899), SkBits2Float(0xc2700006)); // 103.923f, -60
206 path.conicTo(SkBits2Float(0x42f00000), SkBits2Float(0xc2009d9c),
207 SkBits2Float(0x42f00001), SkBits2Float(0x00000000),
208 SkBits2Float(0x3f7746ea)); // 120, -32.1539f, 120, 0, 0.965926f
209
210 SkPaint paint;
211 paint.setAntiAlias(true);
212 canvas->translate(125, 125);
213 canvas->drawPath(path, paint);
214}