180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gm.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRandom.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTArray.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkOnce : SkNoncopyable {
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOnce() { fDidOnce = false; }
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool needToDo() const { return !fDidOnce; }
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool alreadyDone() const { return fDidOnce; }
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void accomplished() {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(!fDidOnce);
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fDidOnce = true;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool fDidOnce;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace skiagm {
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass ConvexPathsGM : public GM {
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOnce fOnce;
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ConvexPathsGM() {
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->setBGColor(0xFF000000);
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkString onShortName() {
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkString("convexpaths");
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkISize onISize() {
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return make_isize(1200, 1100);
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void makePaths() {
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fOnce.alreadyDone()) {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return;
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fOnce.accomplished();
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // CW
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 0);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             0, 100 * SK_Scalar1);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(0, 0);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // CCW
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 0);
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(0, 100 * SK_Scalar1);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             0, 0);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // CW
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 50 * SK_Scalar1);
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(50 * SK_Scalar1, 0,
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             100 * SK_Scalar1, 50 * SK_Scalar1);
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             0, 50 * SK_Scalar1);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // CCW
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 50 * SK_Scalar1);
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             100 * SK_Scalar1, 50 * SK_Scalar1);
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(50 * SK_Scalar1, 0,
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             0, 50 * SK_Scalar1);
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addRect(0, 0,
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   100 * SK_Scalar1, 100 * SK_Scalar1,
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPath::kCW_Direction);
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addRect(0, 0,
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   100 * SK_Scalar1, 100 * SK_Scalar1,
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPath::kCCW_Direction);
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addCircle(50  * SK_Scalar1, 50  * SK_Scalar1,
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                     50  * SK_Scalar1, SkPath::kCW_Direction);
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addCircle(50  * SK_Scalar1, 50  * SK_Scalar1,
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                     40  * SK_Scalar1, SkPath::kCCW_Direction);
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    50 * SK_Scalar1,
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    100 * SK_Scalar1),
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPath::kCW_Direction);
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    100 * SK_Scalar1,
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    50 * SK_Scalar1),
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPath::kCCW_Direction);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    100 * SK_Scalar1,
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    5 * SK_Scalar1),
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPath::kCCW_Direction);
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    SK_Scalar1,
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    100 * SK_Scalar1),
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkPath::kCCW_Direction);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addRoundRect(SkRect::MakeXYWH(0, 0,
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                         SK_Scalar1 * 100,
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                         SK_Scalar1 * 100),
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        40 * SK_Scalar1, 20 * SK_Scalar1,
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        SkPath::kCW_Direction);
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addRoundRect(SkRect::MakeXYWH(0, 0,
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                         SK_Scalar1 * 100,
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                         SK_Scalar1 * 100),
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        20 * SK_Scalar1, 40 * SK_Scalar1,
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        SkPath::kCCW_Direction);
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // large number of points
1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        enum {
1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            kLength = 100,
1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            kPtsPerSide = (1 << 12),
1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        };
1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPaths.push_back().moveTo(0, 0);
1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int i = 1; i < kPtsPerSide; ++i) { // skip the first point due to moveTo.
1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPaths.back().lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, 0);
1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int i = 0; i < kPtsPerSide; ++i) {
1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPaths.back().lineTo(kLength, kLength * SkIntToScalar(i) / kPtsPerSide);
1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int i = kPtsPerSide; i > 0; --i) {
1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPaths.back().lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, kLength);
1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int i = kPtsPerSide; i > 0; --i) {
1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPaths.back().lineTo(0, kLength * SkIntToScalar(i) / kPtsPerSide);
1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // shallow diagonals
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().lineTo(100 * SK_Scalar1, SK_Scalar1);
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(98 * SK_Scalar1, 100 * SK_Scalar1);
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(3 * SK_Scalar1, 96 * SK_Scalar1);
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //It turns out arcTos are not automatically marked as convex and they
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //may in fact be ever so slightly concave.
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //fPaths.push_back().arcTo(SkRect::MakeXYWH(0, 0,
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //                                          50 * SK_Scalar1,
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //                                          100 * SK_Scalar1),
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //                         25 * SK_Scalar1,  130 * SK_Scalar1, false);
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // cubics
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().cubicTo( 1 * SK_Scalar1,  1 * SK_Scalar1,
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   10 * SK_Scalar1,  90 * SK_Scalar1,
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    0 * SK_Scalar1, 100 * SK_Scalar1);
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().cubicTo(100 * SK_Scalar1,  50 * SK_Scalar1,
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    20 * SK_Scalar1, 100 * SK_Scalar1,
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                     0 * SK_Scalar1,   0 * SK_Scalar1);
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // path that has a cubic with a repeated first control point and
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // a repeated last control point.
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(SK_Scalar1 * 10, SK_Scalar1 * 10);
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(10 * SK_Scalar1, 10 * SK_Scalar1,
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              10 * SK_Scalar1, 0,
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              20 * SK_Scalar1, 0);
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(40 * SK_Scalar1, 0);
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(40 * SK_Scalar1, 0,
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              50 * SK_Scalar1, 0,
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              50 * SK_Scalar1, 10 * SK_Scalar1);
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // path that has two cubics with repeated middle control points.
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(SK_Scalar1 * 10, SK_Scalar1 * 10);
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(10 * SK_Scalar1, 0,
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              10 * SK_Scalar1, 0,
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              20 * SK_Scalar1, 0);
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(40 * SK_Scalar1, 0);
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(50 * SK_Scalar1, 0,
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              50 * SK_Scalar1, 0,
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              50 * SK_Scalar1, 10 * SK_Scalar1);
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // cubic where last three points are almost a line
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 228 * SK_Scalar1 / 8);
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(628 * SK_Scalar1 / 8, 82 * SK_Scalar1 / 8,
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              1255 * SK_Scalar1 / 8, 141 * SK_Scalar1 / 8,
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              1883 * SK_Scalar1 / 8, 202 * SK_Scalar1 / 8);
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // flat cubic where the at end point tangents both point outward.
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(10 * SK_Scalar1, 0);
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(0, SK_Scalar1,
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              30 * SK_Scalar1, SK_Scalar1,
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              20 * SK_Scalar1, 0);
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // flat cubic where initial tangent is in, end tangent out
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 0 * SK_Scalar1);
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(10 * SK_Scalar1, SK_Scalar1,
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              30 * SK_Scalar1, SK_Scalar1,
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              20 * SK_Scalar1, 0);
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // flat cubic where initial tangent is out, end tangent in
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(10 * SK_Scalar1, 0);
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(0, SK_Scalar1,
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              20 * SK_Scalar1, SK_Scalar1,
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              30 * SK_Scalar1, 0);
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // triangle where one edge is a degenerate quad
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(SkFloatToScalar(8.59375f), 45 * SK_Scalar1);
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(SkFloatToScalar(16.9921875f),   45 * SK_Scalar1,
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             SkFloatToScalar(31.25f),        45 * SK_Scalar1);
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(100 * SK_Scalar1,              100 * SK_Scalar1);
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(SkFloatToScalar(8.59375f),      45 * SK_Scalar1);
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // point degenerate
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().lineTo(50 * SK_Scalar1, 50 * SK_Scalar1);
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().quadTo(50 * SK_Scalar1, 50 * SK_Scalar1,
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             50 * SK_Scalar1, 50 * SK_Scalar1);
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().cubicTo(50 * SK_Scalar1, 50 * SK_Scalar1,
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              50 * SK_Scalar1, 50 * SK_Scalar1,
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              50 * SK_Scalar1, 50 * SK_Scalar1);
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // moveTo only paths
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 0);
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().moveTo(0, 0);
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().moveTo(SK_Scalar1, SK_Scalar1);
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().moveTo(SK_Scalar1, SK_Scalar1);
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().moveTo(10 * SK_Scalar1, 10 * SK_Scalar1);
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().moveTo(0, 0);
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.back().moveTo(0, 0);
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // line degenerate
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().lineTo(100 * SK_Scalar1, 100 * SK_Scalar1);
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().quadTo(100 * SK_Scalar1, 100 * SK_Scalar1, 0, 0);
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().quadTo(100 * SK_Scalar1, 100 * SK_Scalar1,
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                  50 * SK_Scalar1, 50 * SK_Scalar1);
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().quadTo(50 * SK_Scalar1, 50 * SK_Scalar1,
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                  100 * SK_Scalar1, 100 * SK_Scalar1);
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().cubicTo(0, 0,
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   0, 0,
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   100 * SK_Scalar1, 100 * SK_Scalar1);
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // small circle. This is listed last so that it has device coords far
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // from the origin (small area relative to x,y values).
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaths.push_back().addCircle(0, 0, SkFloatToScalar(0.8f));
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void onDraw(SkCanvas* canvas) {
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->makePaths();
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRandom rand;
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < fPaths.count(); ++i) {
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->save();
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // position the path, and make it at off-integer coords.
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->translate(SK_Scalar1 * 200 * (i % 5) + SK_Scalar1 / 4,
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                          SK_Scalar1 * 200 * (i / 5) + 3 * SK_Scalar1 / 4);
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkColor color = rand.nextU();
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        color |= 0xff000000;
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        paint.setColor(color);
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fPaths[i].isConvex());
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->drawPath(fPaths[i], paint);
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->restore();
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GM INHERITED;
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTArray<SkPath> fPaths;
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory(void*) { return new ConvexPathsGM; }
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg(MyFactory);
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
284