Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2011 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 
      8 #include "SkPathMeasure.h"
      9 #include "Test.h"
     10 
     11 static void test_small_segment3() {
     12     SkPath path;
     13     const SkPoint pts[] = {
     14         { 0, 0 },
     15         { 100000000000.0f, 100000000000.0f }, { 0, 0 }, { 10, 10 },
     16         { 10, 10 }, { 0, 0 }, { 10, 10 }
     17     };
     18 
     19     path.moveTo(pts[0]);
     20     for (size_t i = 1; i < SK_ARRAY_COUNT(pts); i += 3) {
     21         path.cubicTo(pts[i], pts[i + 1], pts[i + 2]);
     22     }
     23 
     24     SkPathMeasure meas(path, false);
     25     meas.getLength();
     26 }
     27 
     28 static void test_small_segment2() {
     29     SkPath path;
     30     const SkPoint pts[] = {
     31         { 0, 0 },
     32         { 100000000000.0f, 100000000000.0f }, { 0, 0 },
     33         { 10, 10 }, { 0, 0 },
     34     };
     35 
     36     path.moveTo(pts[0]);
     37     for (size_t i = 1; i < SK_ARRAY_COUNT(pts); i += 2) {
     38         path.quadTo(pts[i], pts[i + 1]);
     39     }
     40     SkPathMeasure meas(path, false);
     41     meas.getLength();
     42 }
     43 
     44 static void test_small_segment() {
     45     SkPath path;
     46     const SkPoint pts[] = {
     47         { 100000, 100000},
     48         // big jump between these points, makes a big segment
     49         { 1.0005f, 0.9999f },
     50         // tiny (non-zero) jump between these points
     51         { SK_Scalar1, SK_Scalar1 },
     52     };
     53 
     54     path.moveTo(pts[0]);
     55     for (size_t i = 1; i < SK_ARRAY_COUNT(pts); ++i) {
     56         path.lineTo(pts[i]);
     57     }
     58     SkPathMeasure meas(path, false);
     59 
     60     /*  this would assert (before a fix) because we added a segment with
     61         the same length as the prev segment, due to the follow (bad) pattern
     62 
     63         d = distance(pts[0], pts[1]);
     64         distance += d;
     65         seg->fDistance = distance;
     66 
     67         SkASSERT(d > 0);    // TRUE
     68         SkASSERT(seg->fDistance > prevSeg->fDistance);  // FALSE
     69 
     70         This 2nd assert failes because (distance += d) didn't affect distance
     71         because distance >>> d.
     72      */
     73     meas.getLength();
     74 }
     75 
     76 DEF_TEST(PathMeasure, reporter) {
     77     SkPath  path;
     78 
     79     path.moveTo(0, 0);
     80     path.lineTo(SK_Scalar1, 0);
     81     path.lineTo(SK_Scalar1, SK_Scalar1);
     82     path.lineTo(0, SK_Scalar1);
     83 
     84     SkPathMeasure   meas(path, true);
     85     SkScalar        length = meas.getLength();
     86     SkASSERT(length == SK_Scalar1*4);
     87 
     88     path.reset();
     89     path.moveTo(0, 0);
     90     path.lineTo(SK_Scalar1*3, SK_Scalar1*4);
     91     meas.setPath(&path, false);
     92     length = meas.getLength();
     93     REPORTER_ASSERT(reporter, length == SK_Scalar1*5);
     94 
     95     path.reset();
     96     path.addCircle(0, 0, SK_Scalar1);
     97     meas.setPath(&path, true);
     98     length = meas.getLength();
     99 //    SkDebugf("circle arc-length = %g\n", length);
    100 
    101     // Test the behavior following a close not followed by a move.
    102     path.reset();
    103     path.lineTo(SK_Scalar1, 0);
    104     path.lineTo(SK_Scalar1, SK_Scalar1);
    105     path.lineTo(0, SK_Scalar1);
    106     path.close();
    107     path.lineTo(-SK_Scalar1, 0);
    108     meas.setPath(&path, false);
    109     length = meas.getLength();
    110     REPORTER_ASSERT(reporter, length == SK_Scalar1 * 4);
    111     meas.nextContour();
    112     length = meas.getLength();
    113     REPORTER_ASSERT(reporter, length == SK_Scalar1);
    114     SkPoint position;
    115     SkVector tangent;
    116     REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
    117     REPORTER_ASSERT(reporter,
    118         SkScalarNearlyEqual(position.fX,
    119                             -SK_ScalarHalf,
    120                             0.0001f));
    121     REPORTER_ASSERT(reporter, position.fY == 0);
    122     REPORTER_ASSERT(reporter, tangent.fX == -SK_Scalar1);
    123     REPORTER_ASSERT(reporter, tangent.fY == 0);
    124 
    125     // Test degenerate paths
    126     path.reset();
    127     path.moveTo(0, 0);
    128     path.lineTo(0, 0);
    129     path.lineTo(SK_Scalar1, 0);
    130     path.quadTo(SK_Scalar1, 0, SK_Scalar1, 0);
    131     path.quadTo(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1 * 2);
    132     path.cubicTo(SK_Scalar1, SK_Scalar1 * 2,
    133                  SK_Scalar1, SK_Scalar1 * 2,
    134                  SK_Scalar1, SK_Scalar1 * 2);
    135     path.cubicTo(SK_Scalar1*2, SK_Scalar1 * 2,
    136                  SK_Scalar1*3, SK_Scalar1 * 2,
    137                  SK_Scalar1*4, SK_Scalar1 * 2);
    138     meas.setPath(&path, false);
    139     length = meas.getLength();
    140     REPORTER_ASSERT(reporter, length == SK_Scalar1 * 6);
    141     REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
    142     REPORTER_ASSERT(reporter,
    143         SkScalarNearlyEqual(position.fX,
    144                             SK_ScalarHalf,
    145                             0.0001f));
    146     REPORTER_ASSERT(reporter, position.fY == 0);
    147     REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
    148     REPORTER_ASSERT(reporter, tangent.fY == 0);
    149     REPORTER_ASSERT(reporter, meas.getPosTan(2.5f, &position, &tangent));
    150     REPORTER_ASSERT(reporter,
    151         SkScalarNearlyEqual(position.fX, SK_Scalar1, 0.0001f));
    152     REPORTER_ASSERT(reporter,
    153         SkScalarNearlyEqual(position.fY, 1.5f));
    154     REPORTER_ASSERT(reporter, tangent.fX == 0);
    155     REPORTER_ASSERT(reporter, tangent.fY == SK_Scalar1);
    156     REPORTER_ASSERT(reporter, meas.getPosTan(4.5f, &position, &tangent));
    157     REPORTER_ASSERT(reporter,
    158         SkScalarNearlyEqual(position.fX,
    159                             2.5f,
    160                             0.0001f));
    161     REPORTER_ASSERT(reporter,
    162         SkScalarNearlyEqual(position.fY,
    163                             2.0f,
    164                             0.0001f));
    165     REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
    166     REPORTER_ASSERT(reporter, tangent.fY == 0);
    167 
    168     path.reset();
    169     path.moveTo(0, 0);
    170     path.lineTo(SK_Scalar1, 0);
    171     path.moveTo(SK_Scalar1, SK_Scalar1);
    172     path.moveTo(SK_Scalar1 * 2, SK_Scalar1 * 2);
    173     path.lineTo(SK_Scalar1, SK_Scalar1 * 2);
    174     meas.setPath(&path, false);
    175     length = meas.getLength();
    176     REPORTER_ASSERT(reporter, length == SK_Scalar1);
    177     REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
    178     REPORTER_ASSERT(reporter,
    179         SkScalarNearlyEqual(position.fX,
    180                             SK_ScalarHalf,
    181                             0.0001f));
    182     REPORTER_ASSERT(reporter, position.fY == 0);
    183     REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
    184     REPORTER_ASSERT(reporter, tangent.fY == 0);
    185     meas.nextContour();
    186     length = meas.getLength();
    187     REPORTER_ASSERT(reporter, length == SK_Scalar1);
    188     REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
    189     REPORTER_ASSERT(reporter,
    190         SkScalarNearlyEqual(position.fX,
    191                             1.5f,
    192                             0.0001f));
    193     REPORTER_ASSERT(reporter,
    194         SkScalarNearlyEqual(position.fY,
    195                             2.0f,
    196                             0.0001f));
    197     REPORTER_ASSERT(reporter, tangent.fX == -SK_Scalar1);
    198     REPORTER_ASSERT(reporter, tangent.fY == 0);
    199 
    200     test_small_segment();
    201     test_small_segment2();
    202     test_small_segment3();
    203 }
    204 
    205 DEF_TEST(PathMeasureConic, reporter) {
    206     SkPoint stdP, hiP, pts[] = {{0,0}, {100,0}, {100,0}};
    207     SkPath p;
    208     p.moveTo(0, 0);
    209     p.conicTo(pts[1], pts[2], 1);
    210     SkPathMeasure stdm(p, false);
    211     REPORTER_ASSERT(reporter, stdm.getPosTan(20, &stdP, nullptr));
    212     p.reset();
    213     p.moveTo(0, 0);
    214     p.conicTo(pts[1], pts[2], 10);
    215     stdm.setPath(&p, false);
    216     REPORTER_ASSERT(reporter, stdm.getPosTan(20, &hiP, nullptr));
    217     REPORTER_ASSERT(reporter, 19.5f < stdP.fX && stdP.fX < 20.5f);
    218     REPORTER_ASSERT(reporter, 19.5f < hiP.fX && hiP.fX < 20.5f);
    219 }
    220