concavepaths.cpp revision 36352bf5e38f45a70ee4f4fc132a38048d38206d
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