1ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon/* 2ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon * Copyright 2017 Google Inc. 3ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon * 4ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon * Use of this source code is governed by a BSD-style license that can be 5ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon * found in the LICENSE file. 6ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon */ 7ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon#include "Test.h" 8ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon#include "SkInsetConvexPolygon.h" 9ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 10ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonstatic bool is_convex(const SkTDArray<SkPoint>& poly) { 11ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (poly.count() < 3) { 12ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon return false; 13ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 14ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 15ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkVector v0 = poly[0] - poly[poly.count() - 1]; 16ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkVector v1 = poly[1] - poly[poly.count() - 1]; 17ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkScalar winding = v0.cross(v1); 18ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 19ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (int i = 0; i < poly.count()-1; ++i) { 20ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon int j = i + 1; 21ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon int k = (i + 2) % poly.count(); 22ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 23ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkVector v0 = poly[j] - poly[i]; 24ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkVector v1 = poly[k] - poly[i]; 25ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkScalar perpDot = v0.cross(v1); 26291932e8e42e0556bfef9118231b4ac364ecf5dfJim Van Verth if (winding*perpDot < 0) { 27ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon return false; 28ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 29ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 30ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 31ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon return true; 32ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon} 33ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 34ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian SalomonDEF_TEST(InsetConvexPoly, reporter) { 35ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkTDArray<SkPoint> rrectPoly; 36ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 37ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // round rect 38ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100, 55); 39ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100, 55); 40ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100 + 2.5f, 50 + 4.330127f); 41ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100 + 3.535534f, 50 + 3.535534f); 42ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100 + 4.330127f, 50 + 2.5f); 43ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(105, 50); 44ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(105, -50); 45ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100 + 4.330127f, -50 - 2.5f); 46ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100 + 3.535534f, -50 - 3.535534f); 47ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100 + 2.5f, -50 - 4.330127f); 48ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(100, -55); 49ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100, -55); 50ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100 - 2.5f, -50 - 4.330127f); 51ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100 - 3.535534f, -50 - 3.535534f); 52ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100 - 4.330127f, -50 - 2.5f); 53ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-105, -50); 54ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-105, 50); 55ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100 - 4.330127f, 50 + 2.5f); 56ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100 - 3.535534f, 50 + 3.535534f); 57ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *rrectPoly.push() = SkPoint::Make(-100 - 2.5f, 50 + 4.330127f); 58ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, is_convex(rrectPoly)); 59ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 60ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // inset a little 61ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkTDArray<SkPoint> insetPoly; 62ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon bool result = SkInsetConvexPolygon(&rrectPoly[0], rrectPoly.count(), 3, &insetPoly); 63ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, result); 64ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, is_convex(insetPoly)); 65ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 66ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // inset to rect 67ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon result = SkInsetConvexPolygon(&rrectPoly[0], rrectPoly.count(), 10, &insetPoly); 68ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, result); 69ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, is_convex(insetPoly)); 70ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, insetPoly.count() == 4); 71ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (insetPoly.count() == 4) { 72ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, insetPoly[0].equals(-95, 45)); 73ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, insetPoly[1].equals(95, 45)); 74ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, insetPoly[2].equals(95, -45)); 75ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, insetPoly[3].equals(-95, -45)); 76ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 77ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 78ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // just to full inset 79da96550d3941cb794a799c73506a1c5b695c70a1Jim Van Verth // fails, but outputs a line segment 80ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon result = SkInsetConvexPolygon(&rrectPoly[0], rrectPoly.count(), 55, &insetPoly); 81da96550d3941cb794a799c73506a1c5b695c70a1Jim Van Verth REPORTER_ASSERT(reporter, !result); 82da96550d3941cb794a799c73506a1c5b695c70a1Jim Van Verth REPORTER_ASSERT(reporter, !is_convex(insetPoly)); 83da96550d3941cb794a799c73506a1c5b695c70a1Jim Van Verth REPORTER_ASSERT(reporter, insetPoly.count() == 2); 84da96550d3941cb794a799c73506a1c5b695c70a1Jim Van Verth if (insetPoly.count() == 2) { 85ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, insetPoly[0].equals(-50, 0)); 86ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, insetPoly[1].equals(50, 0)); 87ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 88ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 89ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // past full inset 90ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon result = SkInsetConvexPolygon(&rrectPoly[0], rrectPoly.count(), 75, &insetPoly); 91ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, !result); 92da96550d3941cb794a799c73506a1c5b695c70a1Jim Van Verth REPORTER_ASSERT(reporter, insetPoly.count() == 0); 93ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 94ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // troublesome case 95ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkTDArray<SkPoint> clippedRRectPoly; 96ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(335.928101f, 428.219055f); 97ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(330.414459f, 423.034912f); 98ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(325.749084f, 417.395508f); 99ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(321.931946f, 411.300842f); 100ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(318.963074f, 404.750977f); 101ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(316.842468f, 397.745850f); 102ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(315.570068f, 390.285522f); 103ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(315.145966f, 382.369965f); 104ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(315.570068f, 374.454346f); 105ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(316.842468f, 366.994019f); 106ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(318.963074f, 359.988892f); 107ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(321.931946f, 353.439056f); 108ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(325.749084f, 347.344421f); 109ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(330.414459f, 341.705017f); 110ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(335.928101f, 336.520813f); 111ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(342.289948f, 331.791901f); 112ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(377.312134f, 331.791901f); 113ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(381.195313f, 332.532593f); 114ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(384.464935f, 334.754700f); 115ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(386.687042f, 338.024292f); 116ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(387.427765f, 341.907532f); 117ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(387.427765f, 422.832367f); 118ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(386.687042f, 426.715576f); 119ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(384.464935f, 429.985168f); 120ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(381.195313f, 432.207275f); 121ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(377.312134f, 432.947998f); 122ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *clippedRRectPoly.push() = SkPoint::Make(342.289948f, 432.947998f); 123ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, is_convex(clippedRRectPoly)); 124ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 125ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon result = SkInsetConvexPolygon(&clippedRRectPoly[0], clippedRRectPoly.count(), 32.3699417f, 126ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon &insetPoly); 127ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, result); 128ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon REPORTER_ASSERT(reporter, is_convex(insetPoly)); 129ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon} 130