egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 1 | /* |
| 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" |
bungeman | d3ebb48 | 2015-08-05 13:57:49 -0700 | [diff] [blame] | 10 | #include "SkPath.h" |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 11 | #include "SkTArray.h" |
| 12 | |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 13 | class ConicPathsGM : public skiagm::GM { |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 14 | protected: |
| 15 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 16 | SkString onShortName() override { |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 17 | return SkString("conicpaths"); |
| 18 | } |
| 19 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 20 | SkISize onISize() override { |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 21 | return SkISize::Make(920, 960); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 22 | } |
| 23 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 24 | void onOnceBeforeDraw() override { |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 25 | { |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 26 | const SkScalar w = SkScalarSqrt(2)/2; |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 27 | SkPath* conicCirlce = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 28 | conicCirlce->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 29 | 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.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 33 | |
| 34 | } |
| 35 | { |
| 36 | SkPath* hyperbola = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 37 | hyperbola->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 38 | hyperbola->conicTo(0, 100, 100, 100, 2); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 39 | } |
| 40 | { |
| 41 | SkPath* thinHyperbola = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 42 | thinHyperbola->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 43 | thinHyperbola->conicTo(100, 100, 5, 0, 2); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 44 | } |
| 45 | { |
| 46 | SkPath* veryThinHyperbola = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 47 | veryThinHyperbola->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 48 | veryThinHyperbola->conicTo(100, 100, 1, 0, 2); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 49 | } |
| 50 | { |
| 51 | SkPath* closedHyperbola = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 52 | closedHyperbola->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 53 | closedHyperbola->conicTo(100, 100, 0, 0, 2); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 54 | } |
| 55 | { |
| 56 | // using 1 as weight defaults to using quadTo |
| 57 | SkPath* nearParabola = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 58 | nearParabola->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 59 | nearParabola->conicTo(0, 100, 100, 100, 0.999f); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 60 | } |
| 61 | { |
| 62 | SkPath* thinEllipse = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 63 | thinEllipse->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 64 | thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 65 | } |
| 66 | { |
| 67 | SkPath* veryThinEllipse = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 68 | veryThinEllipse->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 69 | veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 70 | } |
| 71 | { |
| 72 | SkPath* closedEllipse = &fPaths.push_back(); |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 73 | closedEllipse->moveTo(0, 0); |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 74 | closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 75 | } |
egdaniel | 5a23a14 | 2015-02-25 06:41:47 -0800 | [diff] [blame] | 76 | { |
| 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.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 90 | } |
| 91 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 92 | void onDraw(SkCanvas* canvas) override { |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 93 | const SkAlpha kAlphaValue[] = { 0xFF, 0x40 }; |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 94 | |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 95 | const SkScalar margin = 15; |
| 96 | canvas->translate(margin, margin); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 97 | |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 98 | SkPaint paint; |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 99 | for (int p = 0; p < fPaths.count(); ++p) { |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 100 | canvas->save(); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 101 | for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) { |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 102 | paint.setARGB(kAlphaValue[a], 0, 0, 0); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 103 | for (int aa = 0; aa < 2; ++aa) { |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 104 | paint.setAntiAlias(SkToBool(aa)); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 105 | for (int fh = 0; fh < 2; ++fh) { |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 106 | paint.setStyle(fh ? SkPaint::kStroke_Style : SkPaint::kFill_Style); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 107 | |
| 108 | const SkRect& bounds = fPaths[p].getBounds(); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 109 | canvas->save(); |
| 110 | canvas->translate(-bounds.fLeft, -bounds.fTop); |
| 111 | canvas->drawPath(fPaths[p], paint); |
| 112 | canvas->restore(); |
| 113 | |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 114 | canvas->translate(110, 0); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 115 | } |
| 116 | } |
| 117 | } |
reed | 40c85e4 | 2015-01-05 10:01:25 -0800 | [diff] [blame] | 118 | canvas->restore(); |
| 119 | canvas->translate(0, 110); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 120 | } |
| 121 | canvas->restore(); |
egdaniel | 5a23a14 | 2015-02-25 06:41:47 -0800 | [diff] [blame] | 122 | |
halcanary | 9d524f2 | 2016-03-29 09:03:52 -0700 | [diff] [blame] | 123 | this->drawGiantCircle(canvas); |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 124 | } |
| 125 | |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 126 | private: |
| 127 | SkTArray<SkPath> fPaths; |
egdaniel | 5a23a14 | 2015-02-25 06:41:47 -0800 | [diff] [blame] | 128 | SkPath fGiantCircle; |
reed | d1bd1d7 | 2014-12-31 20:07:01 -0800 | [diff] [blame] | 129 | typedef skiagm::GM INHERITED; |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 130 | }; |
halcanary | 385fe4d | 2015-08-26 13:07:48 -0700 | [diff] [blame] | 131 | DEF_GM(return new ConicPathsGM;) |
egdaniel@google.com | def9f6e | 2013-06-20 16:54:31 +0000 | [diff] [blame] | 132 | |
| 133 | ////////////////////////////////////////////////////////////////////////////// |
| 134 | |
caryclark | 2b39ffc | 2016-01-20 07:46:05 -0800 | [diff] [blame] | 135 | /* arc should be on top of circle */ |
| 136 | DEF_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 | } |
caryclark | 531191f | 2016-08-24 11:59:30 -0700 | [diff] [blame] | 150 | |
Jim Van Verth | 6750e91 | 2016-12-19 14:45:19 -0500 | [diff] [blame] | 151 | /* circle should be antialiased */ |
| 152 | DEF_SIMPLE_GM(largecircle, canvas, 250, 250) { |
| 153 | canvas->translate(50, 100); |
| 154 | SkPoint c = { 1052.5390625f, 506.8760978034711f }; |
| 155 | SkScalar radius = 1096.702150363923f; |
| 156 | SkPaint paint; |
| 157 | paint.setAntiAlias(true); |
| 158 | paint.setStyle(SkPaint::kStroke_Style); |
| 159 | canvas->drawCircle(c.fX, c.fY, radius, paint); |
| 160 | } |
| 161 | |
caryclark | 531191f | 2016-08-24 11:59:30 -0700 | [diff] [blame] | 162 | DEF_SIMPLE_GM(crbug_640176, canvas, 250, 250) { |
| 163 | SkPath path; |
| 164 | path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 |
| 165 | path.lineTo(SkBits2Float(0x42cfd89a), SkBits2Float(0xc2700000)); // 103.923f, -60 |
| 166 | path.lineTo(SkBits2Float(0x42cfd899), SkBits2Float(0xc2700006)); // 103.923f, -60 |
| 167 | path.conicTo(SkBits2Float(0x42f00000), SkBits2Float(0xc2009d9c), |
| 168 | SkBits2Float(0x42f00001), SkBits2Float(0x00000000), |
| 169 | SkBits2Float(0x3f7746ea)); // 120, -32.1539f, 120, 0, 0.965926f |
| 170 | |
| 171 | SkPaint paint; |
| 172 | paint.setAntiAlias(true); |
| 173 | canvas->translate(125, 125); |
| 174 | canvas->drawPath(path, paint); |
| 175 | } |