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