PathMeasureTest.cpp revision 8f6884aab8aecd7657cf3f9cdbc682f0deca29c5
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 11static 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 28static 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 44static 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 76DEF_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