1def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com/*
2def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com * Copyright 2013 Google Inc.
3def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com *
4def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com * Use of this source code is governed by a BSD-style license that can be
5def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com * found in the LICENSE file.
6def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com */
7def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
8def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com#include "gm.h"
9def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com#include "SkCanvas.h"
10d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkPath.h"
11def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com#include "SkTArray.h"
12def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
13d1bd1d75a3b5902193b430a611f2eb46edf38435reedclass ConicPathsGM : public skiagm::GM {
14def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.comprotected:
15def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
1636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
17def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        return SkString("conicpaths");
18def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com    }
19def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
2036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override {
2140c85e41b8be96f47f03a34bb2938696037afad4reed        return SkISize::Make(920, 960);
22def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com    }
23def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
2436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onOnceBeforeDraw() override {
25def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
26d1bd1d75a3b5902193b430a611f2eb46edf38435reed            const SkScalar w = SkScalarSqrt(2)/2;
27def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* conicCirlce = &fPaths.push_back();
2840c85e41b8be96f47f03a34bb2938696037afad4reed            conicCirlce->moveTo(0, 0);
29d1bd1d75a3b5902193b430a611f2eb46edf38435reed            conicCirlce->conicTo(0, 50, 50, 50, w);
30d1bd1d75a3b5902193b430a611f2eb46edf38435reed            conicCirlce->rConicTo(50, 0, 50, -50, w);
31d1bd1d75a3b5902193b430a611f2eb46edf38435reed            conicCirlce->rConicTo(0, -50, -50, -50, w);
32d1bd1d75a3b5902193b430a611f2eb46edf38435reed            conicCirlce->rConicTo(-50, 0, -50, 50, w);
33def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
34def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
35def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
36def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* hyperbola = &fPaths.push_back();
3740c85e41b8be96f47f03a34bb2938696037afad4reed            hyperbola->moveTo(0, 0);
38d1bd1d75a3b5902193b430a611f2eb46edf38435reed            hyperbola->conicTo(0, 100, 100, 100, 2);
39def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
40def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
41def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* thinHyperbola = &fPaths.push_back();
4240c85e41b8be96f47f03a34bb2938696037afad4reed            thinHyperbola->moveTo(0, 0);
43d1bd1d75a3b5902193b430a611f2eb46edf38435reed            thinHyperbola->conicTo(100, 100, 5, 0, 2);
44def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
45def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
46def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* veryThinHyperbola = &fPaths.push_back();
4740c85e41b8be96f47f03a34bb2938696037afad4reed            veryThinHyperbola->moveTo(0, 0);
48d1bd1d75a3b5902193b430a611f2eb46edf38435reed            veryThinHyperbola->conicTo(100, 100, 1, 0, 2);
49def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
50def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
51def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* closedHyperbola = &fPaths.push_back();
5240c85e41b8be96f47f03a34bb2938696037afad4reed            closedHyperbola->moveTo(0, 0);
53d1bd1d75a3b5902193b430a611f2eb46edf38435reed            closedHyperbola->conicTo(100, 100, 0, 0, 2);
54def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
55def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
56def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            // using 1 as weight defaults to using quadTo
57def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* nearParabola = &fPaths.push_back();
5840c85e41b8be96f47f03a34bb2938696037afad4reed            nearParabola->moveTo(0, 0);
59d1bd1d75a3b5902193b430a611f2eb46edf38435reed            nearParabola->conicTo(0, 100, 100, 100, 0.999f);
60def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
61def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
62def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* thinEllipse = &fPaths.push_back();
6340c85e41b8be96f47f03a34bb2938696037afad4reed            thinEllipse->moveTo(0, 0);
64d1bd1d75a3b5902193b430a611f2eb46edf38435reed            thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf);
65def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
66def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
67def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* veryThinEllipse = &fPaths.push_back();
6840c85e41b8be96f47f03a34bb2938696037afad4reed            veryThinEllipse->moveTo(0, 0);
69d1bd1d75a3b5902193b430a611f2eb46edf38435reed            veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf);
70def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
71def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        {
72def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            SkPath* closedEllipse = &fPaths.push_back();
7340c85e41b8be96f47f03a34bb2938696037afad4reed            closedEllipse->moveTo(0,  0);
74d1bd1d75a3b5902193b430a611f2eb46edf38435reed            closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf);
75def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
765a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel        {
775a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel            const SkScalar w = SkScalarSqrt(2)/2;
785a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel            fGiantCircle.moveTo(2.1e+11f, -1.05e+11f);
795a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel            fGiantCircle.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w);
805a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel            fGiantCircle.conicTo(0, 0, 0, -1.05e+11f, w);
815a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel            fGiantCircle.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w);
825a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel            fGiantCircle.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w);
835a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel
845a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel        }
855a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel    }
865a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel
875a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel    void drawGiantCircle(SkCanvas* canvas) {
885a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel        SkPaint paint;
895a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel        canvas->drawPath(fGiantCircle, paint);
90def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com    }
91def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
9236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
93d1bd1d75a3b5902193b430a611f2eb46edf38435reed        const SkAlpha kAlphaValue[] = { 0xFF, 0x40 };
94def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
95d1bd1d75a3b5902193b430a611f2eb46edf38435reed        const SkScalar margin = 15;
96d1bd1d75a3b5902193b430a611f2eb46edf38435reed        canvas->translate(margin, margin);
97def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
9840c85e41b8be96f47f03a34bb2938696037afad4reed        SkPaint paint;
99def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        for (int p = 0; p < fPaths.count(); ++p) {
10040c85e41b8be96f47f03a34bb2938696037afad4reed            canvas->save();
101def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) {
10240c85e41b8be96f47f03a34bb2938696037afad4reed                paint.setARGB(kAlphaValue[a], 0, 0, 0);
103def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                for (int aa = 0; aa < 2; ++aa) {
10440c85e41b8be96f47f03a34bb2938696037afad4reed                    paint.setAntiAlias(SkToBool(aa));
105def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                    for (int fh = 0; fh < 2; ++fh) {
10640c85e41b8be96f47f03a34bb2938696037afad4reed                        paint.setStyle(fh ? SkPaint::kStroke_Style : SkPaint::kFill_Style);
107def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
108def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                        const SkRect& bounds = fPaths[p].getBounds();
109def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                        canvas->save();
110def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                        canvas->translate(-bounds.fLeft, -bounds.fTop);
111def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                        canvas->drawPath(fPaths[p], paint);
112def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                        canvas->restore();
113def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
11440c85e41b8be96f47f03a34bb2938696037afad4reed                        canvas->translate(110, 0);
115def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                    }
116def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com                }
117def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com            }
11840c85e41b8be96f47f03a34bb2938696037afad4reed            canvas->restore();
11940c85e41b8be96f47f03a34bb2938696037afad4reed            canvas->translate(0, 110);
120def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        }
121def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com        canvas->restore();
1225a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel
1239d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary        this->drawGiantCircle(canvas);
124def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com    }
125def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
126def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.comprivate:
127def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com    SkTArray<SkPath> fPaths;
1285a23a14b1fbc7503bdeff83e4b45ae7c258c6e96egdaniel    SkPath           fGiantCircle;
129d1bd1d75a3b5902193b430a611f2eb46edf38435reed    typedef skiagm::GM INHERITED;
130def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com};
131385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new ConicPathsGM;)
132def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
133def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com//////////////////////////////////////////////////////////////////////////////
134def9f6e3eb45bf1940b848e44871da73af0d7301egdaniel@google.com
1352b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark/* arc should be on top of circle */
1362b39ffc9d225419b6122e8d31da2ab9c797301c6caryclarkDEF_SIMPLE_GM(arccirclegap, canvas, 250, 250) {
1372b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    canvas->translate(50, 100);
1382b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    SkPoint c = { 1052.5390625f, 506.8760978034711f };
1392b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    SkScalar radius = 1096.702150363923f;
1402b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    SkPaint paint;
1412b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    paint.setAntiAlias(true);
1422b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    paint.setStyle(SkPaint::kStroke_Style);
1432b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    canvas->drawCircle(c.fX, c.fY, radius, paint);
1442b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    SkPath path;
1452b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    path.moveTo(288.88884710654133f, -280.26680862609f);
1462b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    path.arcTo(0, 0, -39.00216443306411f, 400.6058925796476f, radius);
1472b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    paint.setColor(0xff007f00);
1482b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark    canvas->drawPath(path, paint);
1492b39ffc9d225419b6122e8d31da2ab9c797301c6caryclark}
150531191fefebb5bed6177946e2e227ddff292cff2caryclark
1516750e91544b98b839c3148baef996ab2860233a4Jim Van Verth/* circle should be antialiased */
1526750e91544b98b839c3148baef996ab2860233a4Jim Van VerthDEF_SIMPLE_GM(largecircle, canvas, 250, 250) {
1536750e91544b98b839c3148baef996ab2860233a4Jim Van Verth    canvas->translate(50, 100);
1546750e91544b98b839c3148baef996ab2860233a4Jim Van Verth    SkPoint c = { 1052.5390625f, 506.8760978034711f };
1556750e91544b98b839c3148baef996ab2860233a4Jim Van Verth    SkScalar radius = 1096.702150363923f;
1566750e91544b98b839c3148baef996ab2860233a4Jim Van Verth    SkPaint paint;
1576750e91544b98b839c3148baef996ab2860233a4Jim Van Verth    paint.setAntiAlias(true);
1586750e91544b98b839c3148baef996ab2860233a4Jim Van Verth    paint.setStyle(SkPaint::kStroke_Style);
1596750e91544b98b839c3148baef996ab2860233a4Jim Van Verth    canvas->drawCircle(c.fX, c.fY, radius, paint);
1606750e91544b98b839c3148baef996ab2860233a4Jim Van Verth}
1616750e91544b98b839c3148baef996ab2860233a4Jim Van Verth
162531191fefebb5bed6177946e2e227ddff292cff2caryclarkDEF_SIMPLE_GM(crbug_640176, canvas, 250, 250) {
163531191fefebb5bed6177946e2e227ddff292cff2caryclark    SkPath path;
164531191fefebb5bed6177946e2e227ddff292cff2caryclark    path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
165531191fefebb5bed6177946e2e227ddff292cff2caryclark    path.lineTo(SkBits2Float(0x42cfd89a), SkBits2Float(0xc2700000));  // 103.923f, -60
166531191fefebb5bed6177946e2e227ddff292cff2caryclark    path.lineTo(SkBits2Float(0x42cfd899), SkBits2Float(0xc2700006));  // 103.923f, -60
167531191fefebb5bed6177946e2e227ddff292cff2caryclark    path.conicTo(SkBits2Float(0x42f00000), SkBits2Float(0xc2009d9c),
168531191fefebb5bed6177946e2e227ddff292cff2caryclark            SkBits2Float(0x42f00001), SkBits2Float(0x00000000),
169531191fefebb5bed6177946e2e227ddff292cff2caryclark            SkBits2Float(0x3f7746ea));  // 120, -32.1539f, 120, 0, 0.965926f
170531191fefebb5bed6177946e2e227ddff292cff2caryclark
171531191fefebb5bed6177946e2e227ddff292cff2caryclark    SkPaint paint;
172531191fefebb5bed6177946e2e227ddff292cff2caryclark    paint.setAntiAlias(true);
173531191fefebb5bed6177946e2e227ddff292cff2caryclark    canvas->translate(125, 125);
174531191fefebb5bed6177946e2e227ddff292cff2caryclark    canvas->drawPath(path, paint);
175531191fefebb5bed6177946e2e227ddff292cff2caryclark}
176