1d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco/*
2d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco * Copyright 2015 Google Inc.
3d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco *
4d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco * Use of this source code is governed by a BSD-style license that can be
5d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco * found in the LICENSE file.
6d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco */
7d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
8d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco#include "gm.h"
9d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco#include "SkCanvas.h"
10d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
11d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco#define WIDTH 400
12d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco#define HEIGHT 600
13d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
14d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanconamespace {
15d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Concave test
16d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_concave(SkCanvas* canvas, const SkPaint& paint) {
17d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
18d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(0, 0);
19d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
20d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
21d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(30), SkIntToScalar(30));
22d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
23d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
24d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
25d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
26d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Reverse concave test
27d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_reverse_concave(SkCanvas* canvas, const SkPaint& paint) {
28d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
29d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
30d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(100, 0);
31d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
32d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
33d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(30), SkIntToScalar(30));
34d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
35d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
36d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
37d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
38d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
39d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Bowtie (intersection)
40d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_bowtie(SkCanvas* canvas, const SkPaint& paint) {
41d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
42d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
43d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(200, 0);
44d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
45d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
46d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
47d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
48d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
49d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
50d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
51d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
52d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// "fake" bowtie (concave, but no intersection)
53d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_fake_bowtie(SkCanvas* canvas, const SkPaint& paint) {
54d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
55d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
56d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(300, 0);
57d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
58d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(40));
59d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
60d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
61d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(60));
62d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
63d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
64d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
65d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
66d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
67d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Fish test (intersection/concave)
68d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_fish(SkCanvas* canvas, const SkPaint& paint) {
69d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
70d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
71d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(0, 100);
72d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
73d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
74d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(70), SkIntToScalar(50));
75d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
76d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
77d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(0), SkIntToScalar(50));
78d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
79d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
80d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
81d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
82d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Collinear edges
83d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_collinear_edges(SkCanvas* canvas, const SkPaint& paint) {
84d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
85d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
86d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(100, 100);
87d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
88d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(20));
89d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
90d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(80));
91d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
92d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
93d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
94d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
95d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Square polygon with a square hole.
96d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_hole(SkCanvas* canvas, const SkPaint& paint) {
97d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
98d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
99d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(200, 100);
100d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
101d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
102d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
103d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
104d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(30), SkIntToScalar(30));
105d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(30), SkIntToScalar(70));
106d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(70), SkIntToScalar(70));
107d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(70), SkIntToScalar(30));
108d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
109d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
110d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
111d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
112d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Star test (self-intersecting)
113d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_star(SkCanvas* canvas, const SkPaint& paint) {
114d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
115d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
116d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(300, 100);
117d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(30, 20);
118d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(50, 80);
119d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(70, 20);
120d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(20, 57);
121d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(80, 57);
122d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.close();
123d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
124d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
125d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
126d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
127d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Stairstep with repeated vert (intersection)
128d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_stairstep(SkCanvas* canvas, const SkPaint& paint) {
129d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
130d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
131d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(0, 200);
132d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(50), SkIntToScalar(50));
133d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(20));
134d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
135d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(50));
136d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(50));
137d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
138d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
139d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
140d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
141d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
142d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_stairstep2(SkCanvas* canvas, const SkPaint& paint) {
143d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
144d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
145d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(100, 200);
146d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(20, 60);
147d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(35, 80);
148d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(50, 60);
149d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(65, 80);
150d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(80, 60);
151d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
152d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
153d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
154d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
155d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Overlapping segments
156d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_overlapping(SkCanvas* canvas, const SkPaint& paint) {
157d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
158d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
159d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(200, 200);
160d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(80));
161d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
162d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
163d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(30));
164d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
165d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
166d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
167d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
168d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Monotone test 1 (point in the middle)
169d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_monotone_1(SkCanvas* canvas, const SkPaint& paint) {
170d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
171d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
172d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(0, 300);
173d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
174d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.quadTo(SkIntToScalar(20), SkIntToScalar(50),
175d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco                SkIntToScalar(80), SkIntToScalar(50));
176d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.quadTo(SkIntToScalar(20), SkIntToScalar(50),
177d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco                SkIntToScalar(20), SkIntToScalar(80));
178d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
179d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
180d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
181d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
182d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Monotone test 2 (point at the top)
183d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_monotone_2(SkCanvas* canvas, const SkPaint& paint) {
184d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
185d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
186d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(100, 300);
187d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
188d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(30));
189d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.quadTo(SkIntToScalar(20), SkIntToScalar(20),
190d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco                SkIntToScalar(20), SkIntToScalar(80));
191d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
192d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
193d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
194d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
195d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Monotone test 3 (point at the bottom)
196d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_monotone_3(SkCanvas* canvas, const SkPaint& paint) {
197d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
198d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
199d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(200, 300);
200d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(80));
201d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(70));
202d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.quadTo(SkIntToScalar(20), SkIntToScalar(80),
203d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco                SkIntToScalar(20), SkIntToScalar(20));
204d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
205d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
206d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
207d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
208d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Monotone test 4 (merging of two monotones)
209d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_monotone_4(SkCanvas* canvas, const SkPaint& paint) {
210d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
211d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
212d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(300, 300);
213d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(80, 25);
214d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(50, 39);
215d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(20, 25);
216d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(40, 45);
217d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(70, 50);
218d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(80, 80);
219d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
220d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
221d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
222d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
223d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Monotone test 5 (aborted merging of two monotones)
224d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_monotone_5(SkCanvas* canvas, const SkPaint& paint) {
225d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
226d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
227d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(0, 400);
228d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(50, 20);
229d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(80, 80);
230d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(50, 50);
231d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(20, 80);
232d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
233d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
234d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
235d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Degenerate intersection test
236d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_degenerate(SkCanvas* canvas, const SkPaint& paint) {
237d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
238d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
239d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(100, 400);
240d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(50, 20);
241d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(70, 30);
242d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(20, 50);
243d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(50, 20);
244d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(80, 80);
245d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(50, 80);
246d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
247d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
248d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
249d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Two triangles with a coincident edge.
250d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_coincident_edge(SkCanvas* canvas, const SkPaint& paint) {
251d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
252d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
253d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(200, 400);
254d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
255d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(80, 20);
256d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(80, 80);
257d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(20, 80);
258d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
259d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(20, 20);
260d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(80, 80);
261d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(20, 80);
262d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
263d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
264d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
265d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
266d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Bowtie with a coincident triangle (one triangle vertex coincident with the
267d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// bowtie's intersection).
268d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_bowtie_coincident_triangle(SkCanvas* canvas, const SkPaint& paint) {
269d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
270d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
271d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(300, 400);
272d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
273d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
274d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
275d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
276d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(50), SkIntToScalar(50));
277d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
278d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
279d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
280d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
281d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
282d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
283d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Coincident edges (big ones first, coincident vert on top).
284d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_coincident_edges_1(SkCanvas* canvas, const SkPaint& paint) {
285d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
286d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
287d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(0, 500);
288d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
289d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
290d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
291d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
292d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(50));
293d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(50));
294d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
295d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
296d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
297d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Coincident edges (small ones first, coincident vert on top).
298d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_coincident_edges_2(SkCanvas* canvas, const SkPaint& paint) {
299d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
300d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
301d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(100, 500);
302d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
303d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(50));
304d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(50));
305d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
306d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
307d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
308d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
309d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
310d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
311d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Coincident edges (small ones first, coincident vert on bottom).
312d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_coincident_edges_3(SkCanvas* canvas, const SkPaint& paint) {
313d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
314d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
315d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(200, 500);
316d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(80));
317d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(50));
318d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(50));
319d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(80));
320d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(20));
321d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
322d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
323d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
324d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
325d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco// Coincident edges (big ones first, coincident vert on bottom).
326d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancovoid test_coincident_edges_4(SkCanvas* canvas, const SkPaint& paint) {
327d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    SkPath path;
328d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->save();
329d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->translate(300, 500);
330d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(80));
331d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(20));
332d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
333d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.moveTo(SkIntToScalar(20), SkIntToScalar(80));
334d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(20), SkIntToScalar(50));
335d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    path.lineTo(SkIntToScalar(50), SkIntToScalar(50));
336d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->drawPath(path, paint);
337d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    canvas->restore();
338d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco}
339d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
340d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco};
341d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
342d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancoclass ConcavePathsGM : public skiagm::GM {
343d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancopublic:
344d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    ConcavePathsGM() {}
345d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
346d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancoprotected:
34736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
348d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        return SkString("concavepaths");
349d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    }
350d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
35136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override {
352d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        return SkISize::Make(WIDTH, HEIGHT);
353d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    }
354d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
35536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
356d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        SkPaint paint;
357d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
358d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        paint.setAntiAlias(true);
359d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        paint.setStyle(SkPaint::kFill_Style);
360d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
361d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_concave(canvas, paint);
362d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_reverse_concave(canvas, paint);
363d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_bowtie(canvas, paint);
364d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_fake_bowtie(canvas, paint);
365d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_fish(canvas, paint);
366d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_collinear_edges(canvas, paint);
367d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_hole(canvas, paint);
368d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_star(canvas, paint);
369d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_stairstep(canvas, paint);
370d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_stairstep2(canvas, paint);
371d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_overlapping(canvas, paint);
372d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_monotone_1(canvas, paint);
373d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_monotone_2(canvas, paint);
374d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_monotone_3(canvas, paint);
375d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_monotone_4(canvas, paint);
376d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_monotone_5(canvas, paint);
377d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_degenerate(canvas, paint);
378d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_coincident_edge(canvas, paint);
379d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_bowtie_coincident_triangle(canvas, paint);
380d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_coincident_edges_1(canvas, paint);
381d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_coincident_edges_2(canvas, paint);
382d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_coincident_edges_3(canvas, paint);
383d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco        test_coincident_edges_4(canvas, paint);
384d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    }
385d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
386d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancoprivate:
387d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco    typedef skiagm::GM INHERITED;
388d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco};
389d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblanco
390d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancostatic skiagm::GM* F0(void*) { return new ConcavePathsGM; }
391d6ed19cc751463285491a538bc7bf154cc7e6d8csenorblancostatic skiagm::GMRegistry R0(F0);
392