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