blob: 6d1fc00f22c1e2c3ebe9a60fd2b2fa9da1d8dab1 [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
8#include "gm.h"
9#include "SkCanvas.h"
bungemand3ebb482015-08-05 13:57:49 -070010#include "SkPath.h"
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000011#include "SkTArray.h"
12
reedd1bd1d72014-12-31 20:07:01 -080013class ConicPathsGM : public skiagm::GM {
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000014protected:
15
mtklein36352bf2015-03-25 18:17:31 -070016 SkString onShortName() override {
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000017 return SkString("conicpaths");
18 }
19
mtklein36352bf2015-03-25 18:17:31 -070020 SkISize onISize() override {
reed40c85e42015-01-05 10:01:25 -080021 return SkISize::Make(920, 960);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000022 }
23
mtklein36352bf2015-03-25 18:17:31 -070024 void onOnceBeforeDraw() override {
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000025 {
reedd1bd1d72014-12-31 20:07:01 -080026 const SkScalar w = SkScalarSqrt(2)/2;
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000027 SkPath* conicCirlce = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080028 conicCirlce->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080029 conicCirlce->conicTo(0, 50, 50, 50, w);
30 conicCirlce->rConicTo(50, 0, 50, -50, w);
31 conicCirlce->rConicTo(0, -50, -50, -50, w);
32 conicCirlce->rConicTo(-50, 0, -50, 50, w);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000033
34 }
35 {
36 SkPath* hyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080037 hyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080038 hyperbola->conicTo(0, 100, 100, 100, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000039 }
40 {
41 SkPath* thinHyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080042 thinHyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080043 thinHyperbola->conicTo(100, 100, 5, 0, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000044 }
45 {
46 SkPath* veryThinHyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080047 veryThinHyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080048 veryThinHyperbola->conicTo(100, 100, 1, 0, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000049 }
50 {
51 SkPath* closedHyperbola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080052 closedHyperbola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080053 closedHyperbola->conicTo(100, 100, 0, 0, 2);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000054 }
55 {
56 // using 1 as weight defaults to using quadTo
57 SkPath* nearParabola = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080058 nearParabola->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080059 nearParabola->conicTo(0, 100, 100, 100, 0.999f);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000060 }
61 {
62 SkPath* thinEllipse = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080063 thinEllipse->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080064 thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000065 }
66 {
67 SkPath* veryThinEllipse = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080068 veryThinEllipse->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080069 veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000070 }
71 {
72 SkPath* closedEllipse = &fPaths.push_back();
reed40c85e42015-01-05 10:01:25 -080073 closedEllipse->moveTo(0, 0);
reedd1bd1d72014-12-31 20:07:01 -080074 closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000075 }
egdaniel5a23a142015-02-25 06:41:47 -080076 {
77 const SkScalar w = SkScalarSqrt(2)/2;
78 fGiantCircle.moveTo(2.1e+11f, -1.05e+11f);
79 fGiantCircle.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w);
80 fGiantCircle.conicTo(0, 0, 0, -1.05e+11f, w);
81 fGiantCircle.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w);
82 fGiantCircle.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w);
83
84 }
85 }
86
87 void drawGiantCircle(SkCanvas* canvas) {
88 SkPaint paint;
89 canvas->drawPath(fGiantCircle, paint);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000090 }
91
mtklein36352bf2015-03-25 18:17:31 -070092 void onDraw(SkCanvas* canvas) override {
reedd1bd1d72014-12-31 20:07:01 -080093 const SkAlpha kAlphaValue[] = { 0xFF, 0x40 };
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000094
reedd1bd1d72014-12-31 20:07:01 -080095 const SkScalar margin = 15;
96 canvas->translate(margin, margin);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000097
reed40c85e42015-01-05 10:01:25 -080098 SkPaint paint;
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +000099 for (int p = 0; p < fPaths.count(); ++p) {
reed40c85e42015-01-05 10:01:25 -0800100 canvas->save();
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000101 for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) {
reed40c85e42015-01-05 10:01:25 -0800102 paint.setARGB(kAlphaValue[a], 0, 0, 0);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000103 for (int aa = 0; aa < 2; ++aa) {
reed40c85e42015-01-05 10:01:25 -0800104 paint.setAntiAlias(SkToBool(aa));
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000105 for (int fh = 0; fh < 2; ++fh) {
reed40c85e42015-01-05 10:01:25 -0800106 paint.setStyle(fh ? SkPaint::kStroke_Style : SkPaint::kFill_Style);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000107
108 const SkRect& bounds = fPaths[p].getBounds();
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000109 canvas->save();
110 canvas->translate(-bounds.fLeft, -bounds.fTop);
111 canvas->drawPath(fPaths[p], paint);
112 canvas->restore();
113
reed40c85e42015-01-05 10:01:25 -0800114 canvas->translate(110, 0);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000115 }
116 }
117 }
reed40c85e42015-01-05 10:01:25 -0800118 canvas->restore();
119 canvas->translate(0, 110);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000120 }
121 canvas->restore();
egdaniel5a23a142015-02-25 06:41:47 -0800122
halcanary9d524f22016-03-29 09:03:52 -0700123 this->drawGiantCircle(canvas);
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000124 }
125
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000126private:
127 SkTArray<SkPath> fPaths;
egdaniel5a23a142015-02-25 06:41:47 -0800128 SkPath fGiantCircle;
reedd1bd1d72014-12-31 20:07:01 -0800129 typedef skiagm::GM INHERITED;
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000130};
halcanary385fe4d2015-08-26 13:07:48 -0700131DEF_GM(return new ConicPathsGM;)
egdaniel@google.comdef9f6e2013-06-20 16:54:31 +0000132
133//////////////////////////////////////////////////////////////////////////////
134
caryclark2b39ffc2016-01-20 07:46:05 -0800135/* arc should be on top of circle */
136DEF_SIMPLE_GM(arccirclegap, canvas, 250, 250) {
137 canvas->translate(50, 100);
138 SkPoint c = { 1052.5390625f, 506.8760978034711f };
139 SkScalar radius = 1096.702150363923f;
140 SkPaint paint;
141 paint.setAntiAlias(true);
142 paint.setStyle(SkPaint::kStroke_Style);
143 canvas->drawCircle(c.fX, c.fY, radius, paint);
144 SkPath path;
145 path.moveTo(288.88884710654133f, -280.26680862609f);
146 path.arcTo(0, 0, -39.00216443306411f, 400.6058925796476f, radius);
147 paint.setColor(0xff007f00);
148 canvas->drawPath(path, paint);
149}
caryclark531191f2016-08-24 11:59:30 -0700150
151DEF_SIMPLE_GM(crbug_640176, canvas, 250, 250) {
152 SkPath path;
153 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
154 path.lineTo(SkBits2Float(0x42cfd89a), SkBits2Float(0xc2700000)); // 103.923f, -60
155 path.lineTo(SkBits2Float(0x42cfd899), SkBits2Float(0xc2700006)); // 103.923f, -60
156 path.conicTo(SkBits2Float(0x42f00000), SkBits2Float(0xc2009d9c),
157 SkBits2Float(0x42f00001), SkBits2Float(0x00000000),
158 SkBits2Float(0x3f7746ea)); // 120, -32.1539f, 120, 0, 0.965926f
159
160 SkPaint paint;
161 paint.setAntiAlias(true);
162 canvas->translate(125, 125);
163 canvas->drawPath(path, paint);
164}