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" 10 #include "SkPath.h" 11 #include "SkTArray.h" 12 13 class ConicPathsGM : public skiagm::GM { 14 protected: 15 onShortName()16 SkString onShortName() override { 17 return SkString("conicpaths"); 18 } 19 onISize()20 SkISize onISize() override { 21 return SkISize::Make(920, 960); 22 } 23 onOnceBeforeDraw()24 void onOnceBeforeDraw() override { 25 { 26 const SkScalar w = SkScalarSqrt(2)/2; 27 SkPath* conicCirlce = &fPaths.push_back(); 28 conicCirlce->moveTo(0, 0); 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); 33 34 } 35 { 36 SkPath* hyperbola = &fPaths.push_back(); 37 hyperbola->moveTo(0, 0); 38 hyperbola->conicTo(0, 100, 100, 100, 2); 39 } 40 { 41 SkPath* thinHyperbola = &fPaths.push_back(); 42 thinHyperbola->moveTo(0, 0); 43 thinHyperbola->conicTo(100, 100, 5, 0, 2); 44 } 45 { 46 SkPath* veryThinHyperbola = &fPaths.push_back(); 47 veryThinHyperbola->moveTo(0, 0); 48 veryThinHyperbola->conicTo(100, 100, 1, 0, 2); 49 } 50 { 51 SkPath* closedHyperbola = &fPaths.push_back(); 52 closedHyperbola->moveTo(0, 0); 53 closedHyperbola->conicTo(100, 100, 0, 0, 2); 54 } 55 { 56 // using 1 as weight defaults to using quadTo 57 SkPath* nearParabola = &fPaths.push_back(); 58 nearParabola->moveTo(0, 0); 59 nearParabola->conicTo(0, 100, 100, 100, 0.999f); 60 } 61 { 62 SkPath* thinEllipse = &fPaths.push_back(); 63 thinEllipse->moveTo(0, 0); 64 thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf); 65 } 66 { 67 SkPath* veryThinEllipse = &fPaths.push_back(); 68 veryThinEllipse->moveTo(0, 0); 69 veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf); 70 } 71 { 72 SkPath* closedEllipse = &fPaths.push_back(); 73 closedEllipse->moveTo(0, 0); 74 closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf); 75 } 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 drawGiantCircle(SkCanvas * canvas)87 void drawGiantCircle(SkCanvas* canvas) { 88 SkPaint paint; 89 canvas->drawPath(fGiantCircle, paint); 90 } 91 onDraw(SkCanvas * canvas)92 void onDraw(SkCanvas* canvas) override { 93 const SkAlpha kAlphaValue[] = { 0xFF, 0x40 }; 94 95 const SkScalar margin = 15; 96 canvas->translate(margin, margin); 97 98 SkPaint paint; 99 for (int p = 0; p < fPaths.count(); ++p) { 100 canvas->save(); 101 for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) { 102 paint.setARGB(kAlphaValue[a], 0, 0, 0); 103 for (int aa = 0; aa < 2; ++aa) { 104 paint.setAntiAlias(SkToBool(aa)); 105 for (int fh = 0; fh < 2; ++fh) { 106 paint.setStyle(fh ? SkPaint::kStroke_Style : SkPaint::kFill_Style); 107 108 const SkRect& bounds = fPaths[p].getBounds(); 109 canvas->save(); 110 canvas->translate(-bounds.fLeft, -bounds.fTop); 111 canvas->drawPath(fPaths[p], paint); 112 canvas->restore(); 113 114 canvas->translate(110, 0); 115 } 116 } 117 } 118 canvas->restore(); 119 canvas->translate(0, 110); 120 } 121 canvas->restore(); 122 123 this->drawGiantCircle(canvas); 124 } 125 126 private: 127 SkTArray<SkPath> fPaths; 128 SkPath fGiantCircle; 129 typedef skiagm::GM INHERITED; 130 }; 131 DEF_GM(return new ConicPathsGM;) 132 133 ////////////////////////////////////////////////////////////////////////////// 134 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, 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 } 150 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, radius, paint); 160 } 161 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 } 176