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