OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkIntersections.h" | 8 #include "SkIntersections.h" |
9 #include "SkPathOpsCubic.h" | 9 #include "SkPathOpsCubic.h" |
10 #include "SkPathOpsLine.h" | 10 #include "SkPathOpsLine.h" |
11 #include "SkPathOpsPoint.h" | 11 #include "SkPathOpsPoint.h" |
12 #include "SkPathOpsQuad.h" | 12 #include "SkPathOpsQuad.h" |
13 #include "SkPathOpsRect.h" | 13 #include "SkPathOpsRect.h" |
14 #include "SkReduceOrder.h" | 14 #include "SkReduceOrder.h" |
15 #include "SkTSort.h" | 15 #include "SkTSort.h" |
16 | 16 |
17 #if ONE_OFF_DEBUG | 17 #if ONE_OFF_DEBUG |
18 static const double tLimits1[2][2] = {{0.36, 0.37}, {0.63, 0.64}}; | 18 static const double tLimits1[2][2] = {{0.388600450, 0.388600452}, {0.245852802,
0.245852804}}; |
19 static const double tLimits2[2][2] = {{-0.865211397, -0.865215212}, {-0.86520769
6, -0.865208078}}; | 19 static const double tLimits2[2][2] = {{-0.865211397, -0.865215212}, {-0.86520769
6, -0.865208078}}; |
20 #endif | 20 #endif |
21 | 21 |
22 #define DEBUG_QUAD_PART 0 | 22 #define DEBUG_QUAD_PART ONE_OFF_DEBUG && 1 |
| 23 #define DEBUG_QUAD_PART_SHOW_SIMPLE DEBUG_QUAD_PART && 0 |
23 #define SWAP_TOP_DEBUG 0 | 24 #define SWAP_TOP_DEBUG 0 |
24 | 25 |
25 static const int kCubicToQuadSubdivisionDepth = 8; // slots reserved for cubic t
o quads subdivision | 26 static const int kCubicToQuadSubdivisionDepth = 8; // slots reserved for cubic t
o quads subdivision |
26 | 27 |
27 static int quadPart(const SkDCubic& cubic, double tStart, double tEnd, SkReduceO
rder* reducer) { | 28 static int quadPart(const SkDCubic& cubic, double tStart, double tEnd, SkReduceO
rder* reducer) { |
28 SkDCubic part = cubic.subDivide(tStart, tEnd); | 29 SkDCubic part = cubic.subDivide(tStart, tEnd); |
29 SkDQuad quad = part.toQuad(); | 30 SkDQuad quad = part.toQuad(); |
30 // FIXME: should reduceOrder be looser in this use case if quartic is going
to blow up on an | 31 // FIXME: should reduceOrder be looser in this use case if quartic is going
to blow up on an |
31 // extremely shallow quadratic? | 32 // extremely shallow quadratic? |
32 int order = reducer->reduce(quad, SkReduceOrder::kFill_Style); | 33 int order = reducer->reduce(quad, SkReduceOrder::kFill_Style); |
33 #if DEBUG_QUAD_PART | 34 #if DEBUG_QUAD_PART |
34 SkDebugf("%s cubic=(%1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g)
" | 35 SkDebugf("%s cubic=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)" |
35 " t=(%1.17g,%1.17g)\n", __FUNCTION__, cubic[0].fX, cubic[0].fY, | 36 " t=(%1.9g,%1.9g)\n", __FUNCTION__, cubic[0].fX, cubic[0].fY, |
36 cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY, | 37 cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY, |
37 cubic[3].fX, cubic[3].fY, tStart, tEnd); | 38 cubic[3].fX, cubic[3].fY, tStart, tEnd); |
38 SkDebugf("%s part=(%1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g)" | 39 SkDebugf(" {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n" |
39 " quad=(%1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g)\n", __FUNCTION__, | 40 " {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", |
40 part[0].fX, part[0].fY, part[1].fX, part[1].fY, part[2].fX, part[2].
fY, | 41 part[0].fX, part[0].fY, part[1].fX, part[1].fY, part[2].fX, part[2].
fY, |
41 part[3].fX, part[3].fY, quad[0].fX, quad[0].fY, | 42 part[3].fX, part[3].fY, quad[0].fX, quad[0].fY, |
42 quad[1].fX, quad[1].fY, quad[2].fX, quad[2].fY); | 43 quad[1].fX, quad[1].fY, quad[2].fX, quad[2].fY); |
43 SkDebugf("%s simple=(%1.17g,%1.17g", __FUNCTION__, reducer->fQuad[0].fX, red
ucer->fQuad[0].fY); | 44 #if DEBUG_QUAD_PART_SHOW_SIMPLE |
| 45 SkDebugf("%s simple=(%1.9g,%1.9g", __FUNCTION__, reducer->fQuad[0].fX, reduc
er->fQuad[0].fY); |
44 if (order > 1) { | 46 if (order > 1) { |
45 SkDebugf(" %1.17g,%1.17g", reducer->fQuad[1].fX, reducer->fQuad[1].fY); | 47 SkDebugf(" %1.9g,%1.9g", reducer->fQuad[1].fX, reducer->fQuad[1].fY); |
46 } | 48 } |
47 if (order > 2) { | 49 if (order > 2) { |
48 SkDebugf(" %1.17g,%1.17g", reducer->fQuad[2].fX, reducer->fQuad[2].fY); | 50 SkDebugf(" %1.9g,%1.9g", reducer->fQuad[2].fX, reducer->fQuad[2].fY); |
49 } | 51 } |
50 SkDebugf(")\n"); | 52 SkDebugf(")\n"); |
51 SkASSERT(order < 4 && order > 0); | 53 SkASSERT(order < 4 && order > 0); |
52 #endif | 54 #endif |
| 55 #endif |
53 return order; | 56 return order; |
54 } | 57 } |
55 | 58 |
56 static void intersectWithOrder(const SkDQuad& simple1, int order1, const SkDQuad
& simple2, | 59 static void intersectWithOrder(const SkDQuad& simple1, int order1, const SkDQuad
& simple2, |
57 int order2, SkIntersections& i) { | 60 int order2, SkIntersections& i) { |
58 if (order1 == 3 && order2 == 3) { | 61 if (order1 == 3 && order2 == 3) { |
59 i.intersect(simple1, simple2); | 62 i.intersect(simple1, simple2); |
60 } else if (order1 <= 2 && order2 <= 2) { | 63 } else if (order1 <= 2 && order2 <= 2) { |
61 i.intersect((const SkDLine&) simple1, (const SkDLine&) simple2); | 64 i.intersect((const SkDLine&) simple1, (const SkDLine&) simple2); |
62 } else if (order1 == 3 && order2 <= 2) { | 65 } else if (order1 == 3 && order2 <= 2) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 SkDebugf("%.*s %s 3 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Ma
x=%1.9g c2Min=%1.9g" | 236 SkDebugf("%.*s %s 3 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Ma
x=%1.9g c2Min=%1.9g" |
234 " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__
, to1, to2, c1Min, | 237 " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__
, to1, to2, c1Min, |
235 c1Max, c2Min, c2Max); | 238 c1Max, c2Min, c2Max); |
236 #endif | 239 #endif |
237 intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, of
fset, i); | 240 intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, of
fset, i); |
238 #if ONE_OFF_DEBUG | 241 #if ONE_OFF_DEBUG |
239 SkDebugf("%.*s %s 3 i.used=%d t=%1.9g\n", i.depth()*2, tab,
__FUNCTION__, | 242 SkDebugf("%.*s %s 3 i.used=%d t=%1.9g\n", i.depth()*2, tab,
__FUNCTION__, |
240 i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1); | 243 i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1); |
241 #endif | 244 #endif |
242 } | 245 } |
243 intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset
, i); | 246 // intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offs
et, i); |
244 // FIXME: if no intersection is found, either quadratics int
ersected where | 247 // FIXME: if no intersection is found, either quadratics int
ersected where |
245 // cubics did not, or the intersection was missed. In the fo
rmer case, expect | 248 // cubics did not, or the intersection was missed. In the fo
rmer case, expect |
246 // the quadratics to be nearly parallel at the point of inte
rsection, and check | 249 // the quadratics to be nearly parallel at the point of inte
rsection, and check |
247 // for that. | 250 // for that. |
248 } | 251 } |
249 } | 252 } |
250 SkASSERT(coStart[0] == -1); | 253 SkASSERT(coStart[0] == -1); |
251 t2Start = t2; | 254 t2Start = t2; |
252 } | 255 } |
253 t1Start = t1; | 256 t1Start = t1; |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 } | 487 } |
485 (void) intersect(c, c); | 488 (void) intersect(c, c); |
486 if (used() > 0) { | 489 if (used() > 0) { |
487 SkASSERT(used() == 1); | 490 SkASSERT(used() == 1); |
488 if (fT[0][0] > fT[1][0]) { | 491 if (fT[0][0] > fT[1][0]) { |
489 swapPts(); | 492 swapPts(); |
490 } | 493 } |
491 } | 494 } |
492 return used(); | 495 return used(); |
493 } | 496 } |
OLD | NEW |