1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPath.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRandom.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace skiagm {
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass DegenerateSegmentsGM : public GM {
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DegenerateSegmentsGM() {}
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct PathAndName {
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPath      fPath;
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* fName1;
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* fName2;
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() {
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("degeneratesegments");
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() { return SkISize::Make(896, 930); }
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkPoint (*AddSegmentFunc)(SkPath&, SkPoint&);
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // We need to use explicit commands here, instead of addPath, because we
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // do not want the moveTo that is added at the beginning of a path to
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // appear in the appended path.
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMove(SkPath& path, SkPoint& startPt) {
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveClose(SkPath& path, SkPoint& startPt) {
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddDegenLine(SkPath& path, SkPoint& startPt) {
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.lineTo(startPt);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return startPt;
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveDegenLine(SkPath& path, SkPoint& startPt) {
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.lineTo(moveToPt);
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveDegenLineClose(SkPath& path, SkPoint& startPt) {
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.lineTo(moveToPt);
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddDegenQuad(SkPath& path, SkPoint& startPt) {
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.quadTo(startPt, startPt);
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return startPt;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveDegenQuad(SkPath& path, SkPoint& startPt) {
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.quadTo(moveToPt, moveToPt);
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveDegenQuadClose(SkPath& path, SkPoint& startPt) {
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.quadTo(moveToPt, moveToPt);
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddDegenCubic(SkPath& path, SkPoint& startPt) {
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.cubicTo(startPt, startPt, startPt);
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return startPt;
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveDegenCubic(SkPath& path, SkPoint& startPt) {
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.cubicTo(moveToPt, moveToPt, moveToPt);
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveDegenCubicClose(SkPath& path, SkPoint& startPt) {
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.cubicTo(moveToPt, moveToPt, moveToPt);
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return moveToPt;
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddClose(SkPath& path, SkPoint& startPt) {
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return startPt;
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddLine(SkPath& path, SkPoint& startPt) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.lineTo(endPt);
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveLine(SkPath& path, SkPoint& startPt) {
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.lineTo(endPt);
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveLineClose(SkPath& path, SkPoint& startPt) {
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.lineTo(endPt);
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddQuad(SkPath& path, SkPoint& startPt) {
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint midPt = startPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.quadTo(midPt, endPt);
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveQuad(SkPath& path, SkPoint& startPt) {
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.quadTo(midPt, endPt);
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveQuadClose(SkPath& path, SkPoint& startPt) {
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.quadTo(midPt, endPt);
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddCubic(SkPath& path, SkPoint& startPt) {
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint t1Pt = startPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint t2Pt = startPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.cubicTo(t1Pt, t2Pt, endPt);
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveCubic(SkPath& path, SkPoint& startPt) {
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.cubicTo(t1Pt, t2Pt, endPt);
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPoint AddMoveCubicClose(SkPath& path, SkPoint& startPt) {
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(moveToPt);
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.cubicTo(t1Pt, t2Pt, endPt);
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.close();
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return endPt;
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void drawPath(SkPath& path, SkCanvas* canvas, SkColor color,
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  const SkRect& clip, SkPaint::Cap cap, SkPaint::Join join,
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  SkPaint::Style style, SkPath::FillType fill,
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  SkScalar strokeWidth) {
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.setFillType(fill);
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setStrokeCap(cap);
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setStrokeWidth(strokeWidth);
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setStrokeJoin(join);
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(color);
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setStyle(style);
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->save();
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->clipRect(clip);
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawPath(path, paint);
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->restore();
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void onDraw(SkCanvas* canvas) {
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr AddSegmentFunc gSegmentFunctions[] = {
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMove,
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveClose,
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddDegenLine,
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveDegenLine,
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveDegenLineClose,
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddDegenQuad,
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveDegenQuad,
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveDegenQuadClose,
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddDegenCubic,
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveDegenCubic,
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveDegenCubicClose,
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddClose,
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddLine,
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveLine,
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveLineClose,
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddQuad,
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveQuad,
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveQuadClose,
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddCubic,
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveCubic,
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        AddMoveCubicClose
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* gSegmentNames[] = {
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "Move",
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveClose",
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "DegenLine",
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveDegenLine",
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveDegenLineClose",
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "DegenQuad",
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveDegenQuad",
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveDegenQuadClose",
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "DegenCubic",
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveDegenCubic",
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveDegenCubicClose",
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "Close",
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "Line",
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveLine",
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveLineClose",
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "Quad",
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveQuad",
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveQuadClose",
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "Cubic",
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveCubic",
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        "MoveCubicClose"
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        struct FillAndName {
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPath::FillType fFill;
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char*      fName;
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr FillAndName gFills[] = {
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPath::kWinding_FillType, "Winding"},
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPath::kEvenOdd_FillType, "Even / Odd"},
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPath::kInverseWinding_FillType, "Inverse Winding"},
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        struct StyleAndName {
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPaint::Style fStyle;
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char*    fName;
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr StyleAndName gStyles[] = {
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPaint::kFill_Style, "Fill"},
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPaint::kStroke_Style, "Stroke 10"},
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPaint::kStrokeAndFill_Style, "Stroke 10 And Fill"}
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        struct CapAndName {
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPaint::Cap  fCap;
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPaint::Join fJoin;
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char*   fName;
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr CapAndName gCaps[] = {
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint titlePaint;
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        titlePaint.setColor(SK_ColorBLACK);
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        titlePaint.setAntiAlias(true);
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_tool_utils::set_portable_typeface(&titlePaint);
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        titlePaint.setTextSize(15 * SK_Scalar1);
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char title[] = "Random Paths Drawn Into Rectangle Clips With "
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             "Indicated Style, Fill and Linecaps, "
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             "with Stroke width 6";
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawString(title,
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                           20 * SK_Scalar1,
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                           20 * SK_Scalar1,
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                           titlePaint);
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRandom rand;
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect rect = SkRect::MakeWH(220*SK_Scalar1, 50*SK_Scalar1);
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->save();
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(2*SK_Scalar1, 30 * SK_Scalar1); // The title
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->save();
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unsigned numSegments = SK_ARRAY_COUNT(gSegmentFunctions);
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unsigned numCaps = SK_ARRAY_COUNT(gCaps);
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unsigned numStyles = SK_ARRAY_COUNT(gStyles);
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unsigned numFills = SK_ARRAY_COUNT(gFills);
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (size_t row = 0; row < 6; ++row) {
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (0 < row) {
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->translate(0, rect.height() + 100*SK_Scalar1);
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->save();
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (size_t column = 0; column < 4; ++column) {
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (0 < column) {
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->translate(rect.width() + 4*SK_Scalar1, 0);
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkColor color = sk_tool_utils::color_to_565(0xff007000);
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                StyleAndName style = gStyles[(rand.nextU() >> 16) % numStyles];
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                CapAndName cap = gCaps[(rand.nextU() >> 16) % numCaps];
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                FillAndName fill = gFills[(rand.nextU() >> 16) % numFills];
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkPath path;
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                unsigned s1 = (rand.nextU() >> 16) % numSegments;
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                unsigned s2 = (rand.nextU() >> 16) % numSegments;
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                unsigned s3 = (rand.nextU() >> 16) % numSegments;
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                unsigned s4 = (rand.nextU() >> 16) % numSegments;
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                unsigned s5 = (rand.nextU() >> 16) % numSegments;
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkPoint pt = SkPoint::Make(10*SK_Scalar1, 0);
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                pt = gSegmentFunctions[s1](path, pt);
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                pt = gSegmentFunctions[s2](path, pt);
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                pt = gSegmentFunctions[s3](path, pt);
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                pt = gSegmentFunctions[s4](path, pt);
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                pt = gSegmentFunctions[s5](path, pt);
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->drawPath(path, canvas, color, rect,
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                               cap.fCap, cap.fJoin, style.fStyle,
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                               fill.fFill, SK_Scalar1*6);
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkPaint rectPaint;
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                rectPaint.setColor(SK_ColorBLACK);
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                rectPaint.setStyle(SkPaint::kStroke_Style);
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                rectPaint.setStrokeWidth(-1);
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                rectPaint.setAntiAlias(true);
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawRect(rect, rectPaint);
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkPaint labelPaint;
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                labelPaint.setColor(color);
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                labelPaint.setAntiAlias(true);
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                sk_tool_utils::set_portable_typeface(&labelPaint);
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                labelPaint.setTextSize(10 * SK_Scalar1);
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(style.fName,
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 12 * SK_Scalar1,
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(fill.fName,
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 24 * SK_Scalar1,
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(cap.fName,
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 36 * SK_Scalar1,
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(gSegmentNames[s1],
364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 48 * SK_Scalar1,
365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(gSegmentNames[s2],
367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 60 * SK_Scalar1,
368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(gSegmentNames[s3],
370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 72 * SK_Scalar1,
371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(gSegmentNames[s4],
373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 84 * SK_Scalar1,
374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawString(gSegmentNames[s5],
376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   0, rect.height() + 96 * SK_Scalar1,
377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   labelPaint);
378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->restore();
380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->restore();
382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->restore();
383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//////////////////////////////////////////////////////////////////////////////
390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic GM* MyFactory(void*) { return new DegenerateSegmentsGM; }
392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic GMRegistry reg(MyFactory);
393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
395