Flutter Engine
The Flutter Engine
PathOpsAngleTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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 */
14#include "src/base/SkRandom.h"
24#include "tests/Test.h"
25
26#include <array>
27#include <cfloat>
28#include <cmath>
29
30static bool gDisableAngleTests = true;
31
32static float next(float f)
33{
34 int fBits = SkFloatAs2sCompliment(f);
35 ++fBits;
36 float fNext = Sk2sComplimentAsFloat(fBits);
37 return fNext;
38}
39
40static float prev(float f)
41{
42 int fBits = SkFloatAs2sCompliment(f);
43 --fBits;
44 float fNext = Sk2sComplimentAsFloat(fBits);
45 return fNext;
46}
47
48DEF_TEST(PathOpsAngleFindCrossEpsilon, reporter) {
50 return;
51 }
52 SkRandom ran;
53 int maxEpsilon = 0;
54 for (int index = 0; index < 10000000; ++index) {
55 SkDLine line = {{{0, 0}, {ran.nextRangeF(0.0001f, 1000), ran.nextRangeF(0.0001f, 1000)}}};
56 for (int inner = 0; inner < 10; ++inner) {
57 float t = ran.nextRangeF(0.0001f, 1);
58 SkDPoint dPt = line.ptAtT(t);
59 SkPoint pt = dPt.asSkPoint();
60 float xs[3] = { prev(pt.fX), pt.fX, next(pt.fX) };
61 float ys[3] = { prev(pt.fY), pt.fY, next(pt.fY) };
62 for (int xIdx = 0; xIdx < 3; ++xIdx) {
63 for (int yIdx = 0; yIdx < 3; ++yIdx) {
64 SkPoint test = { xs[xIdx], ys[yIdx] };
65 float p1 = SkDoubleToScalar(line[1].fX * test.fY);
66 float p2 = SkDoubleToScalar(line[1].fY * test.fX);
67 int p1Bits = SkFloatAs2sCompliment(p1);
68 int p2Bits = SkFloatAs2sCompliment(p2);
69 int epsilon = SkTAbs(p1Bits - p2Bits);
70 if (maxEpsilon < epsilon) {
71 SkDebugf("line={{0, 0}, {%1.7g, %1.7g}} t=%1.7g pt={%1.7g, %1.7g}"
72 " epsilon=%d\n",
73 line[1].fX, line[1].fY, t, test.fX, test.fY, epsilon);
74 maxEpsilon = epsilon;
75 }
76 }
77 }
78 }
79 }
80}
81
82DEF_TEST(PathOpsAngleFindQuadEpsilon, reporter) {
84 return;
85 }
86 SkRandom ran;
87 int maxEpsilon = 0;
88 double maxAngle = 0;
89 for (int index = 0; index < 100000; ++index) {
90 SkDLine line = {{{0, 0}, {ran.nextRangeF(0.0001f, 1000), ran.nextRangeF(0.0001f, 1000)}}};
91 float t = ran.nextRangeF(0.0001f, 1);
92 SkDPoint dPt = line.ptAtT(t);
93 float t2 = ran.nextRangeF(0.0001f, 1);
94 SkDPoint qPt = line.ptAtT(t2);
95 float t3 = ran.nextRangeF(0.0001f, 1);
96 SkDPoint qPt2 = line.ptAtT(t3);
97 qPt.fX += qPt2.fY;
98 qPt.fY -= qPt2.fX;
99 QuadPts q = {{line[0], dPt, qPt}};
100 SkDQuad quad;
101 quad.debugSet(q.fPts);
102 // binary search for maximum movement of quad[1] towards test that still has 1 intersection
103 double moveT = 0.5f;
104 double deltaT = moveT / 2;
105 SkDPoint last;
106 do {
107 last = quad[1];
108 quad[1].fX = dPt.fX - line[1].fY * moveT;
109 quad[1].fY = dPt.fY + line[1].fX * moveT;
111 i.intersect(quad, line);
112 REPORTER_ASSERT(reporter, i.used() > 0);
113 if (i.used() == 1) {
114 moveT += deltaT;
115 } else {
116 moveT -= deltaT;
117 }
118 deltaT /= 2;
119 } while (last.asSkPoint() != quad[1].asSkPoint());
120 float p1 = SkDoubleToScalar(line[1].fX * last.fY);
121 float p2 = SkDoubleToScalar(line[1].fY * last.fX);
122 int p1Bits = SkFloatAs2sCompliment(p1);
123 int p2Bits = SkFloatAs2sCompliment(p2);
124 int epsilon = SkTAbs(p1Bits - p2Bits);
125 if (maxEpsilon < epsilon) {
126 SkDebugf("line={{0, 0}, {%1.7g, %1.7g}} t=%1.7g/%1.7g/%1.7g moveT=%1.7g"
127 " pt={%1.7g, %1.7g} epsilon=%d\n",
128 line[1].fX, line[1].fY, t, t2, t3, moveT, last.fX, last.fY, epsilon);
129 maxEpsilon = epsilon;
130 }
131 double a1 = atan2(line[1].fY, line[1].fX);
132 double a2 = atan2(last.fY, last.fX);
133 double angle = fabs(a1 - a2);
134 if (maxAngle < angle) {
135 SkDebugf("line={{0, 0}, {%1.7g, %1.7g}} t=%1.7g/%1.7g/%1.7g moveT=%1.7g"
136 " pt={%1.7g, %1.7g} angle=%1.7g\n",
137 line[1].fX, line[1].fY, t, t2, t3, moveT, last.fX, last.fY, angle);
138 maxAngle = angle;
139 }
140 }
141}
142
143static int find_slop(double x, double y, double rx, double ry) {
144 int slopBits = 0;
145 bool less1, less2;
146 double absX = fabs(x);
147 double absY = fabs(y);
148 double length = absX < absY ? absX / 2 + absY : absX + absY / 2;
149 int exponent;
150 (void) frexp(length, &exponent);
151 double epsilon = ldexp(FLT_EPSILON, exponent);
152 do {
153 // get the length as the larger plus half the smaller (both same signs)
154 // find the ulps of the length
155 // compute the offsets from there
156 double xSlop = epsilon * slopBits;
157 double ySlop = x * y < 0 ? -xSlop : xSlop; // OPTIMIZATION: use copysign / _copysign ?
158 double x1 = x - xSlop;
159 double y1 = y + ySlop;
160 double x_ry1 = x1 * ry;
161 double rx_y1 = rx * y1;
162 less1 = x_ry1 < rx_y1;
163 double x2 = x + xSlop;
164 double y2 = y - ySlop;
165 double x_ry2 = x2 * ry;
166 double rx_y2 = rx * y2;
167 less2 = x_ry2 < rx_y2;
168 } while (less1 == less2 && ++slopBits);
169 return slopBits;
170}
171
172// from http://stackoverflow.com/questions/1427422/cheap-algorithm-to-find-measure-of-angle-between-vectors
173static double diamond_angle(double y, double x)
174{
175 if (y >= 0)
176 return (x >= 0 ? y/(x+y) : 1-x/(-x+y));
177 else
178 return (x < 0 ? 2-y/(-x-y) : 3+x/(x-y));
179}
180
181static const double slopTests[][4] = {
182 // x y rx ry
183 {-0.058554756452593892, -0.18804585843827226, -0.018568569646021160, -0.059615294434479438},
184 {-0.0013717412948608398, 0.0041152238845825195, -0.00045837944195925573, 0.0013753175735478074},
185 {-2.1033774145221198, -1.4046019261273715e-008, -0.70062688352066704, -1.2706324683777995e-008},
186};
187
188DEF_TEST(PathOpsAngleFindSlop, reporter) {
189 if (gDisableAngleTests) {
190 return;
191 }
192 for (int index = 0; index < (int) std::size(slopTests); ++index) {
193 const double* slopTest = slopTests[index];
194 double x = slopTest[0];
195 double y = slopTest[1];
196 double rx = slopTest[2];
197 double ry = slopTest[3];
198 SkDebugf("%s xy %d=%d\n", __FUNCTION__, index, find_slop(x, y, rx, ry));
199 SkDebugf("%s rxy %d=%d\n", __FUNCTION__, index, find_slop(rx, ry, x, y));
200 double angle = diamond_angle(y, x);
201 double rAngle = diamond_angle(ry, rx);
202 double diff = fabs(angle - rAngle);
203 SkDebugf("%s diamond xy=%1.9g rxy=%1.9g diff=%1.9g factor=%d\n", __FUNCTION__,
204 angle, rAngle, diff, (int) (diff / FLT_EPSILON));
205 }
206}
207
208class PathOpsAngleTester {
209public:
210 static int After(SkOpAngle& lh, SkOpAngle& rh) {
211 return lh.after(&rh);
212 }
213
214 static int AllOnOneSide(SkOpAngle& lh, SkOpAngle& rh) {
215 return lh.lineOnOneSide(&rh, false);
216 }
217
219 return lh.convexHullOverlaps(&rh);
220 }
221
222 static int Orderable(SkOpAngle& lh, SkOpAngle& rh) {
223 return lh.orderable(&rh);
224 }
225
226 static int EndsIntersect(SkOpAngle& lh, SkOpAngle& rh) {
227 return lh.endsIntersect(&rh);
228 }
229
230 static void SetNext(SkOpAngle& lh, SkOpAngle& rh) {
231 lh.fNext = &rh;
232 }
233};
234
236public:
237 static void DebugReset(SkOpSegment* segment) {
238 segment->debugReset();
239 }
240};
241
244 const int fPtCount;
246};
247
249 { {{{313.0155029296875, 207.90290832519531}, {320.05078125, 227.58743286132812}}}, 2, {} },
250 { {{{313.0155029296875, 207.90290832519531}, {313.98246891063195, 219.33615203830394},
251 {320.05078125, 227.58743286132812}}}, 3, {} },
252};
253
255
256DEF_TEST(PathOpsAngleCircle, reporter) {
257 SkSTArenaAlloc<4096> allocator;
259 SkOpGlobalState state(&contour, &allocator SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
260 contour.init(&state, false, false);
261 for (int index = 0; index < circleDataSetSize; ++index) {
262 CircleData& data = circleDataSet[index];
263 for (int idx2 = 0; idx2 < data.fPtCount; ++idx2) {
264 data.fShortPts[idx2] = data.fPts.fPts[idx2].asSkPoint();
265 }
266 switch (data.fPtCount) {
267 case 2:
268 contour.addLine(data.fShortPts);
269 break;
270 case 3:
271 contour.addQuad(data.fShortPts);
272 break;
273 case 4:
274 contour.addCubic(data.fShortPts);
275 break;
276 }
277 }
278 SkOpSegment* first = contour.first();
279 first->debugAddAngle(0, 1);
280 SkOpSegment* next = first->next();
281 next->debugAddAngle(0, 1);
282 PathOpsAngleTester::Orderable(*first->debugLastAngle(), *next->debugLastAngle());
283}
284
287 const int fPtCount;
288 double fTStart;
289 double fTEnd;
291};
292
294 { {{{322.935669,231.030273}, {312.832214,220.393295}, {312.832214,203.454178}}}, 3,
295 0.865309956, 0.154740299, {} },
296 { {{{322.12738,233.397751}, {295.718353,159.505829}}}, 2,
297 0.345028807, 0.0786326511, {} },
298 { {{{322.935669,231.030273}, {312.832214,220.393295}, {312.832214,203.454178}}}, 3,
299 0.865309956, 1, {} },
300 { {{{322.12738,233.397751}, {295.718353,159.505829}}}, 2,
301 0.345028807, 1, {} },
302};
303
305 { {{{364.390686,157.898193}, {375.281769,136.674606}, {396.039917,136.674606}}}, 3,
306 0.578520747, 1, {} },
307 { {{{364.390686,157.898193}, {375.281769,136.674606}, {396.039917,136.674606}}}, 3,
308 0.578520747, 0.536512973, {} },
309 { {{{366.608826,151.196014}, {378.803101,136.674606}, {398.164948,136.674606}}}, 3,
310 0.490456543, 1, {} },
311};
312
314 { {{{2.000000,0.000000}, {1.33333333,0.66666667}}}, 2, 1, 0, {} },
315 { {{{1.33333333,0.66666667}, {0.000000,2.000000}}}, 2, 0, 0.25, {} },
316 { {{{2.000000,2.000000}, {1.33333333,0.66666667}}}, 2, 1, 0, {} },
317};
318
320 { {{{1.3333333,0.6666667}, {0.000,2.000}}}, 2, 0.250000006, 0, {} },
321 { {{{1.000,0.000}, {1.000,1.000}}}, 2, 1, 0, {} },
322 { {{{1.000,1.000}, {0.000,0.000}}}, 2, 0, 1, {} },
323};
324
326 { {{{0.000,0.000}, {1.000,0.000}, {1.000,1.000}}}, 3, 1, 0.666666667, {} },
327 { {{{0.000,0.000}, {2.000,1.000}, {0.000,2.000}}}, 3, 0.5, 1, {} },
328 { {{{0.000,0.000}, {2.000,1.000}, {0.000,2.000}}}, 3, 0.5, 0, {} },
329};
330
331static IntersectData intersectDataSet6[] = { // pathops_visualizer.htm:3658
332 { {{{0.000,1.000}, {3.000,4.000}, {1.000,0.000}, {3.000,0.000}}}, 4, 0.0925339054, 0, {} }, // pathops_visualizer.htm:3616
333 { {{{0.000,1.000}, {0.000,3.000}, {1.000,0.000}, {4.000,3.000}}}, 4, 0.453872386, 0, {} }, // pathops_visualizer.htm:3616
334 { {{{0.000,1.000}, {3.000,4.000}, {1.000,0.000}, {3.000,0.000}}}, 4, 0.0925339054, 0.417096368, {} }, // pathops_visualizer.htm:3616
335};
336
337static IntersectData intersectDataSet7[] = { // pathops_visualizer.htm:3748
338 { {{{2.000,1.000}, {0.000,1.000}}}, 2, 0.5, 0, {} }, // pathops_visualizer.htm:3706
339 { {{{2.000,0.000}, {0.000,2.000}}}, 2, 0.5, 1, {} }, // pathops_visualizer.htm:3706
340 { {{{0.000,1.000}, {0.000,2.000}, {2.000,0.000}, {2.000,1.000}}}, 4, 0.5, 1, {} }, // pathops_visualizer.htm:3706
341}; //
342
343static IntersectData intersectDataSet8[] = { // pathops_visualizer.htm:4194
344 { {{{0.000,1.000}, {2.000,3.000}, {5.000,1.000}, {4.000,3.000}}}, 4, 0.311007457, 0.285714286, {} }, // pathops_visualizer.htm:4152
345 { {{{1.000,5.000}, {3.000,4.000}, {1.000,0.000}, {3.000,2.000}}}, 4, 0.589885081, 0.999982974, {} }, // pathops_visualizer.htm:4152
346 { {{{1.000,5.000}, {3.000,4.000}, {1.000,0.000}, {3.000,2.000}}}, 4, 0.589885081, 0.576935809, {} }, // pathops_visualizer.htm:4152
347}; //
348
349static IntersectData intersectDataSet9[] = { // pathops_visualizer.htm:4142
350 { {{{0.000,1.000}, {2.000,3.000}, {5.000,1.000}, {4.000,3.000}}}, 4, 0.476627072, 0.311007457, {} }, // pathops_visualizer.htm:4100
351 { {{{1.000,5.000}, {3.000,4.000}, {1.000,0.000}, {3.000,2.000}}}, 4, 0.999982974, 1, {} }, // pathops_visualizer.htm:4100
352 { {{{0.000,1.000}, {2.000,3.000}, {5.000,1.000}, {4.000,3.000}}}, 4, 0.476627072, 1, {} }, // pathops_visualizer.htm:4100
353}; //
354
355static IntersectData intersectDataSet10[] = { // pathops_visualizer.htm:4186
356 { {{{0.000,1.000}, {1.000,6.000}, {1.000,0.000}, {1.000,0.000}}}, 4, 0.788195121, 0.726275769, {} }, // pathops_visualizer.htm:4144
357 { {{{0.000,1.000}, {0.000,1.000}, {1.000,0.000}, {6.000,1.000}}}, 4, 0.473378977, 1, {} }, // pathops_visualizer.htm:4144
358 { {{{0.000,1.000}, {1.000,6.000}, {1.000,0.000}, {1.000,0.000}}}, 4, 0.788195121, 1, {} }, // pathops_visualizer.htm:4144
359}; //
360
361static IntersectData intersectDataSet11[] = { // pathops_visualizer.htm:4704
362 { {{{979.305,561.000}, {1036.695,291.000}}}, 2, 0.888888874, 0.11111108, {} }, // pathops_visualizer.htm:4662
363 { {{{1006.695,291.000}, {1023.264,291.000}, {1033.840,304.431}, {1030.318,321.000}}}, 4, 1, 0, {} }, // pathops_visualizer.htm:4662
364 { {{{979.305,561.000}, {1036.695,291.000}}}, 2, 0.888888874, 1, {} }, // pathops_visualizer.htm:4662
365}; //
366
367static IntersectData intersectDataSet12[] = { // pathops_visualizer.htm:5481
368 { {{{67.000,912.000}, {67.000,913.000}}}, 2, 1, 0, {} }, // pathops_visualizer.htm:5439
369 { {{{67.000,913.000}, {67.000,917.389}, {67.224,921.726}, {67.662,926.000}}}, 4, 0, 1, {} }, // pathops_visualizer.htm:5439
370 { {{{194.000,1041.000}, {123.860,1041.000}, {67.000,983.692}, {67.000,913.000}}}, 4, 1, 0, {} }, // pathops_visualizer.htm:5439
371}; //
372
373static IntersectData intersectDataSet13[] = { // pathops_visualizer.htm:5735
374 { {{{6.000,0.000}, {0.000,4.000}}}, 2, 0.625, 0.25, {} }, // pathops_visualizer.htm:5693
375 { {{{0.000,1.000}, {0.000,6.000}, {4.000,0.000}, {6.000,1.000}}}, 4, 0.5, 0.833333333, {} }, // pathops_visualizer.htm:5693
376 { {{{0.000,1.000}, {0.000,6.000}, {4.000,0.000}, {6.000,1.000}}}, 4, 0.5, 0.379043969, {} }, // pathops_visualizer.htm:5693
377}; //
378
379static IntersectData intersectDataSet14[] = { // pathops_visualizer.htm:5875
380 { {{{0.000,1.000}, {4.000,6.000}, {2.000,1.000}, {2.000,0.000}}}, 4, 0.0756502183, 0.0594570973, {} }, // pathops_visualizer.htm:5833
381 { {{{1.000,2.000}, {0.000,2.000}, {1.000,0.000}, {6.000,4.000}}}, 4, 0.0756502184, 0, {} }, // pathops_visualizer.htm:5833
382 { {{{0.000,1.000}, {4.000,6.000}, {2.000,1.000}, {2.000,0.000}}}, 4, 0.0756502183, 0.531917258, {} }, // pathops_visualizer.htm:5833
383}; //
384
385static IntersectData intersectDataSet15[] = { // pathops_visualizer.htm:6580
386 { {{{490.435,879.407}, {405.593,909.436}}}, 2, 0.500554405, 1, {} }, // pathops_visualizer.htm:6538
387 { {{{447.967,894.438}, {448.007,894.424}, {448.014,894.422}}}, 3, 0, 1, {} }, // pathops_visualizer.htm:6538
388 { {{{490.435,879.407}, {405.593,909.436}}}, 2, 0.500554405, 0.500000273, {} }, // pathops_visualizer.htm:6538
389}; //
390
391static IntersectData intersectDataSet16[] = { // pathops_visualizer.htm:7419
392 { {{{1.000,4.000}, {4.000,5.000}, {3.000,2.000}, {6.000,3.000}}}, 4, 0.5, 0, {} }, // pathops_visualizer.htm:7377
393 { {{{2.000,3.000}, {3.000,6.000}, {4.000,1.000}, {5.000,4.000}}}, 4, 0.5, 0.112701665, {} }, // pathops_visualizer.htm:7377
394 { {{{5.000,4.000}, {2.000,3.000}}}, 2, 0.5, 0, {} }, // pathops_visualizer.htm:7377
395}; //
396
397// from skpi_gino_com_16
399 { /*seg=7*/ {{{270.974121f, 770.025879f}, {234.948273f, 734}, {184, 734}}}
400 , 3, 0.74590454, 0.547660352, {} },
401 { /*seg=8*/ {{{185, 734}, {252.93103f, 734}, {308, 789.06897f}, {308, 857}}}
402 , 4, 0.12052623, 0, {} },
403 { /*seg=7*/ {{{270.974121f, 770.025879f}, {234.948273f, 734}, {184, 734}}}
404 , 3, 0.74590454, 1, {} },
405};
406
408 { /*seg=7*/ {{{270.974121f, 770.025879f}, {234.948273f, 734}, {184, 734}}}
409 , 3, 0.74590454, 1, {} },
410 { /*seg=8*/ {{{185, 734}, {252.93103f, 734}, {308, 789.06897f}, {308, 857}}}
411 , 4, 0.12052623, 0.217351928, {} },
412 { /*seg=7*/ {{{270.974121f, 770.025879f}, {234.948273f, 734}, {184, 734}}}
413 , 3, 0.74590454, 0.547660352, {} },
414};
415
417 { /*seg=1*/ {{{0, 1}, {3, 5}, {2, 1}, {3, 1}}}
418 , 4, 0.135148995, 0.134791946, {} },
419 { /*seg=3*/ {{{1, 2}, {1, 2.15061641f}, {1, 2.21049166f}, {1.01366711f, 2.21379328f}}}
420 , 4, 0.956740456, 0.894913214, {} },
421 { /*seg=1*/ {{{0, 1}, {3, 5}, {2, 1}, {3, 1}}}
422 , 4, 0.135148995, 0.551812363, {} },
423};
424
425#define I(x) intersectDataSet##x
426
428 I(1), I(2), I(3), I(4), I(5), I(6), I(7), I(8), I(9), I(10),
429 I(11), I(12), I(13), I(14), I(15), I(16), I(17), I(18), I(19),
430};
431
432#undef I
433#define I(x) (int) std::size(intersectDataSet##x)
434
435static const int intersectDataSetSizes[] = {
436 I(1), I(2), I(3), I(4), I(5), I(6), I(7), I(8), I(9), I(10),
437 I(11), I(12), I(13), I(14), I(15), I(16), I(17), I(18), I(19),
438};
439
440#undef I
441
443
446};
447
448DEF_TEST(PathOpsAngleAfter, reporter) {
449 for (int index = intersectDataSetsSize - 1; index >= 0; --index) {
450 IntersectData* dataArray = intersectDataSets[index];
451 const int dataSize = intersectDataSetSizes[index];
452 for (int index2 = 0; index2 < dataSize - 2; ++index2) {
455 SkOpGlobalState state(&contour, &alloc SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
456 contour.init(&state, false, false);
457 for (int index3 = 0; index3 < 3; ++index3) {
458 IntersectData& data = dataArray[index2 + index3];
459 SkPoint* temp = (SkPoint*) alloc.make<FourPoints>();
460 for (int idx2 = 0; idx2 < data.fPtCount; ++idx2) {
461 temp[idx2] = data.fPts.fPts[idx2].asSkPoint();
462 }
463 switch (data.fPtCount) {
464 case 2: {
465 contour.addLine(temp);
466 } break;
467 case 3: {
468 contour.addQuad(temp);
469 } break;
470 case 4: {
471 contour.addCubic(temp);
472 } break;
473 }
474 }
475 SkOpSegment* seg1 = contour.first();
476 seg1->debugAddAngle(dataArray[index2 + 0].fTStart, dataArray[index2 + 0].fTEnd);
477 SkOpSegment* seg2 = seg1->next();
478 seg2->debugAddAngle(dataArray[index2 + 1].fTStart, dataArray[index2 + 1].fTEnd);
479 SkOpSegment* seg3 = seg2->next();
480 seg3->debugAddAngle(dataArray[index2 + 2].fTStart, dataArray[index2 + 2].fTEnd);
481 SkOpAngle& angle1 = *seg1->debugLastAngle();
482 SkOpAngle& angle2 = *seg2->debugLastAngle();
483 SkOpAngle& angle3 = *seg3->debugLastAngle();
484 PathOpsAngleTester::SetNext(angle1, angle3);
485 // These data sets are seeded when the set itself fails, so likely the dataset does not
486 // match the expected result. The tests above return 1 when first added, but
487 // return 0 after the bug is fixed.
488 SkDEBUGCODE(int result =) PathOpsAngleTester::After(angle2, angle1);
489 SkASSERT(result == 0 || result == 1);
490 }
491 }
492}
493
494DEF_TEST(PathOpsAngleAllOnOneSide, reporter) {
495 SkSTArenaAlloc<4096> allocator;
497 SkOpGlobalState state(&contour, &allocator SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
498 contour.init(&state, false, false);
499 SkPoint conicPts[3] = {{494.37100219726562f, 224.66200256347656f},
500 {494.37360910682298f, 224.6729026561527f},
501 {494.37600708007813f, 224.68400573730469f}};
502 SkPoint linePts[2] = {{494.371002f, 224.662003f}, {494.375000f, 224.675995f}};
503 for (int i = 10; i >= 0; --i) {
504 SkPoint modLinePts[2] = { linePts[0], linePts[1] };
505 modLinePts[1].fX += i * .1f;
506 contour.addLine(modLinePts);
507 contour.addQuad(conicPts);
508 // contour.addConic(conicPts, 0.999935746f, &allocator);
509 SkOpSegment* first = contour.first();
510 first->debugAddAngle(0, 1);
511 SkOpSegment* next = first->next();
512 next->debugAddAngle(0, 1);
513 /* int result = */
514 PathOpsAngleTester::AllOnOneSide(*first->debugLastAngle(), *next->debugLastAngle());
515 // SkDebugf("i=%d result=%d\n", i , result);
516 }
517}
Instance * fNext
reporter
Definition: FontMgrTest.cpp:39
static const int circleDataSetSize
static IntersectData intersectDataSet14[]
static IntersectData intersectDataSet2[]
static IntersectData intersectDataSet9[]
static IntersectData * intersectDataSets[]
static IntersectData intersectDataSet5[]
static CircleData circleDataSet[]
static IntersectData intersectDataSet16[]
static IntersectData intersectDataSet11[]
static float next(float f)
static IntersectData intersectDataSet12[]
DEF_TEST(PathOpsAngleFindCrossEpsilon, reporter)
#define I(x)
static IntersectData intersectDataSet7[]
static IntersectData intersectDataSet17[]
static const int intersectDataSetsSize
static IntersectData intersectDataSet18[]
static IntersectData intersectDataSet8[]
static IntersectData intersectDataSet1[]
static const int intersectDataSetSizes[]
static float prev(float f)
static IntersectData intersectDataSet3[]
static IntersectData intersectDataSet13[]
static double diamond_angle(double y, double x)
static const double slopTests[][4]
static IntersectData intersectDataSet10[]
static bool gDisableAngleTests
static IntersectData intersectDataSet19[]
static IntersectData intersectDataSet4[]
static IntersectData intersectDataSet15[]
static IntersectData intersectDataSet6[]
static int find_slop(double x, double y, double rx, double ry)
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static int32_t SkFloatAs2sCompliment(float x)
Definition: SkFloatBits.h:59
static float Sk2sComplimentAsFloat(int32_t x)
Definition: SkFloatBits.h:66
#define SkDEBUGPARAMS(...)
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64
static T SkTAbs(T value)
Definition: SkTemplates.h:43
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
static void SetNext(SkOpAngle &lh, SkOpAngle &rh)
static int After(SkOpAngle &lh, SkOpAngle &rh)
static int ConvexHullOverlaps(SkOpAngle &lh, SkOpAngle &rh)
static int Orderable(SkOpAngle &lh, SkOpAngle &rh)
static int AllOnOneSide(SkOpAngle &lh, SkOpAngle &rh)
static int EndsIntersect(SkOpAngle &lh, SkOpAngle &rh)
static void DebugReset(SkOpSegment *segment)
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
Definition: SkArenaAlloc.h:120
SkOpAngle * debugLastAngle()
void debugAddAngle(double startT, double endT)
SkOpSegment * next() const
Definition: SkOpSegment.h:304
float nextRangeF(float min, float max)
Definition: SkRandom.h:64
AtkStateType state
GAsyncResult * result
size_t length
double y
double x
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
const CubicPts fPts
const int fPtCount
SkPoint fShortPts[4]
SkPoint pts[4]
SkPoint fShortPts[4]
const CubicPts fPts
SkDPoint fPts[kPointCount]
SkPoint asSkPoint() const
void debugSet(const SkDPoint *pts)
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63