Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1892 | Rev 3959 | ||
---|---|---|---|
Line 34... | Line 34... | ||
34 | * Carl D. Worth |
34 | * Carl D. Worth |
35 | */ |
35 | */ |
Line 36... | Line 36... | ||
36 | 36 | ||
Line -... | Line 37... | ||
- | 37 | #include "cairoint.h" |
|
37 | #include "cairoint.h" |
38 | |
Line 38... | Line 39... | ||
38 | 39 | #include "cairo-box-inline.h" |
|
- | 40 | #include "cairo-slope-private.h" |
|
- | 41 | ||
- | 42 | cairo_bool_t |
|
- | 43 | _cairo_spline_intersects (const cairo_point_t *a, |
|
- | 44 | const cairo_point_t *b, |
|
- | 45 | const cairo_point_t *c, |
|
- | 46 | const cairo_point_t *d, |
|
- | 47 | const cairo_box_t *box) |
|
- | 48 | { |
|
- | 49 | cairo_box_t bounds; |
|
- | 50 | ||
- | 51 | if (_cairo_box_contains_point (box, a) || |
|
- | 52 | _cairo_box_contains_point (box, b) || |
|
- | 53 | _cairo_box_contains_point (box, c) || |
|
- | 54 | _cairo_box_contains_point (box, d)) |
|
- | 55 | { |
|
- | 56 | return TRUE; |
|
- | 57 | } |
|
- | 58 | ||
- | 59 | bounds.p2 = bounds.p1 = *a; |
|
- | 60 | _cairo_box_add_point (&bounds, b); |
|
- | 61 | _cairo_box_add_point (&bounds, c); |
|
- | 62 | _cairo_box_add_point (&bounds, d); |
|
- | 63 | ||
- | 64 | if (bounds.p2.x <= box->p1.x || bounds.p1.x >= box->p2.x || |
|
- | 65 | bounds.p2.y <= box->p1.y || bounds.p1.y >= box->p2.y) |
|
- | 66 | { |
|
- | 67 | return FALSE; |
|
- | 68 | } |
|
- | 69 | ||
- | 70 | #if 0 /* worth refining? */ |
|
- | 71 | bounds.p2 = bounds.p1 = *a; |
|
- | 72 | _cairo_box_add_curve_to (&bounds, b, c, d); |
|
- | 73 | if (bounds.p2.x <= box->p1.x || bounds.p1.x >= box->p2.x || |
|
- | 74 | bounds.p2.y <= box->p1.y || bounds.p1.y >= box->p2.y) |
|
- | 75 | { |
|
- | 76 | return FALSE; |
|
- | 77 | } |
|
- | 78 | #endif |
|
- | 79 | ||
- | 80 | return TRUE; |
|
39 | #include "cairo-slope-private.h" |
81 | } |
40 | 82 | ||
41 | cairo_bool_t |
83 | cairo_bool_t |
42 | _cairo_spline_init (cairo_spline_t *spline, |
84 | _cairo_spline_init (cairo_spline_t *spline, |
43 | cairo_spline_add_point_func_t add_point_func, |
85 | cairo_spline_add_point_func_t add_point_func, |
44 | void *closure, |
86 | void *closure, |
- | 87 | const cairo_point_t *a, const cairo_point_t *b, |
|
- | 88 | const cairo_point_t *c, const cairo_point_t *d) |
|
- | 89 | { |
|
- | 90 | /* If both tangents are zero, this is just a straight line */ |
|
45 | const cairo_point_t *a, const cairo_point_t *b, |
91 | if (a->x == b->x && a->y == b->y && c->x == d->x && c->y == d->y) |
46 | const cairo_point_t *c, const cairo_point_t *d) |
92 | return FALSE; |
Line 47... | Line 93... | ||
47 | { |
93 | |
48 | spline->add_point_func = add_point_func; |
94 | spline->add_point_func = add_point_func; |
Line 65... | Line 111... | ||
65 | if (c->x != d->x || c->y != d->y) |
111 | if (c->x != d->x || c->y != d->y) |
66 | _cairo_slope_init (&spline->final_slope, &spline->knots.c, &spline->knots.d); |
112 | _cairo_slope_init (&spline->final_slope, &spline->knots.c, &spline->knots.d); |
67 | else if (b->x != d->x || b->y != d->y) |
113 | else if (b->x != d->x || b->y != d->y) |
68 | _cairo_slope_init (&spline->final_slope, &spline->knots.b, &spline->knots.d); |
114 | _cairo_slope_init (&spline->final_slope, &spline->knots.b, &spline->knots.d); |
69 | else |
115 | else |
- | 116 | return FALSE; /* just treat this as a straight-line from a -> d */ |
|
- | 117 | ||
70 | _cairo_slope_init (&spline->final_slope, &spline->knots.a, &spline->knots.d); |
118 | /* XXX if the initial, final and vector are all equal, this is just a line */ |
Line 71... | Line 119... | ||
71 | 119 | ||
72 | return TRUE; |
120 | return TRUE; |
Line 73... | Line 121... | ||
73 | } |
121 | } |
74 | 122 | ||
- | 123 | static cairo_status_t |
|
- | 124 | _cairo_spline_add_point (cairo_spline_t *spline, |
|
75 | static cairo_status_t |
125 | const cairo_point_t *point, |
76 | _cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *point) |
126 | const cairo_point_t *knot) |
- | 127 | { |
|
Line 77... | Line 128... | ||
77 | { |
128 | cairo_point_t *prev; |
78 | cairo_point_t *prev; |
129 | cairo_slope_t slope; |
79 | 130 | ||
Line -... | Line 131... | ||
- | 131 | prev = &spline->last_point; |
|
- | 132 | if (prev->x == point->x && prev->y == point->y) |
|
80 | prev = &spline->last_point; |
133 | return CAIRO_STATUS_SUCCESS; |
81 | if (prev->x == point->x && prev->y == point->y) |
134 | |
82 | return CAIRO_STATUS_SUCCESS; |
135 | _cairo_slope_init (&slope, point, knot); |
Line 83... | Line 136... | ||
83 | 136 | ||
84 | spline->last_point = *point; |
137 | spline->last_point = *point; |
85 | return spline->add_point_func (spline->closure, point); |
138 | return spline->add_point_func (spline->closure, point, &slope); |
Line 182... | Line 235... | ||
182 | else |
235 | else |
183 | return cerr; |
236 | return cerr; |
184 | } |
237 | } |
Line 185... | Line 238... | ||
185 | 238 | ||
186 | static cairo_status_t |
239 | static cairo_status_t |
- | 240 | _cairo_spline_decompose_into (cairo_spline_knots_t *s1, |
|
- | 241 | double tolerance_squared, |
|
187 | _cairo_spline_decompose_into (cairo_spline_knots_t *s1, double tolerance_squared, cairo_spline_t *result) |
242 | cairo_spline_t *result) |
188 | { |
243 | { |
189 | cairo_spline_knots_t s2; |
244 | cairo_spline_knots_t s2; |
Line 190... | Line 245... | ||
190 | cairo_status_t status; |
245 | cairo_status_t status; |
191 | 246 | ||
Line 192... | Line 247... | ||
192 | if (_cairo_spline_error_squared (s1) < tolerance_squared) |
247 | if (_cairo_spline_error_squared (s1) < tolerance_squared) |
Line 193... | Line 248... | ||
193 | return _cairo_spline_add_point (result, &s1->a); |
248 | return _cairo_spline_add_point (result, &s1->a, &s1->b); |
194 | 249 | ||
Line 211... | Line 266... | ||
211 | spline->last_point = s1.a; |
266 | spline->last_point = s1.a; |
212 | status = _cairo_spline_decompose_into (&s1, tolerance * tolerance, spline); |
267 | status = _cairo_spline_decompose_into (&s1, tolerance * tolerance, spline); |
213 | if (unlikely (status)) |
268 | if (unlikely (status)) |
214 | return status; |
269 | return status; |
Line 215... | Line 270... | ||
215 | 270 | ||
- | 271 | return spline->add_point_func (spline->closure, |
|
216 | return _cairo_spline_add_point (spline, &spline->knots.d); |
272 | &spline->knots.d, &spline->final_slope); |
Line 217... | Line 273... | ||
217 | } |
273 | } |
218 | 274 | ||
219 | /* Note: this function is only good for computing bounds in device space. */ |
275 | /* Note: this function is only good for computing bounds in device space. */ |
Line 323... | Line 379... | ||
323 | a = -y0 + 3*y1 - 3*y2 + y3; |
379 | a = -y0 + 3*y1 - 3*y2 + y3; |
324 | b = y0 - 2*y1 + y2; |
380 | b = y0 - 2*y1 + y2; |
325 | c = -y0 + y1; |
381 | c = -y0 + y1; |
326 | FIND_EXTREMES (a, b, c); |
382 | FIND_EXTREMES (a, b, c); |
Line 327... | Line 383... | ||
327 | 383 | ||
328 | status = add_point_func (closure, p0); |
384 | status = add_point_func (closure, p0, NULL); |
329 | if (unlikely (status)) |
385 | if (unlikely (status)) |
Line 330... | Line 386... | ||
330 | return status; |
386 | return status; |
331 | 387 | ||
Line 357... | Line 413... | ||
357 | + y2 * t_2_1_3 |
413 | + y2 * t_2_1_3 |
358 | + y3 * t_3_0; |
414 | + y3 * t_3_0; |
Line 359... | Line 415... | ||
359 | 415 | ||
360 | p.x = _cairo_fixed_from_double (x); |
416 | p.x = _cairo_fixed_from_double (x); |
361 | p.y = _cairo_fixed_from_double (y); |
417 | p.y = _cairo_fixed_from_double (y); |
362 | status = add_point_func (closure, &p); |
418 | status = add_point_func (closure, &p, NULL); |
363 | if (unlikely (status)) |
419 | if (unlikely (status)) |
364 | return status; |
420 | return status; |
Line 365... | Line 421... | ||
365 | } |
421 | } |
366 | 422 |