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 39... | Line 39... | ||
39 | #include "cairoint.h" |
39 | #include "cairoint.h" |
Line 40... | Line 40... | ||
40 | 40 | ||
41 | #include "cairo-error-private.h" |
41 | #include "cairo-error-private.h" |
Line 42... | Line -... | ||
42 | #include "cairo-slope-private.h" |
- | |
43 | - | ||
44 | static int |
- | |
45 | _cairo_pen_vertices_needed (double tolerance, |
- | |
46 | double radius, |
- | |
47 | const cairo_matrix_t *matrix); |
42 | #include "cairo-slope-private.h" |
48 | 43 | ||
Line 49... | Line 44... | ||
49 | static void |
44 | static void |
50 | _cairo_pen_compute_slopes (cairo_pen_t *pen); |
45 | _cairo_pen_compute_slopes (cairo_pen_t *pen); |
Line 86... | Line 81... | ||
86 | * a circle in user space and transform them to device space. To get a consistent |
81 | * a circle in user space and transform them to device space. To get a consistent |
87 | * orientation in device space, flip the pen if the transformation matrix |
82 | * orientation in device space, flip the pen if the transformation matrix |
88 | * is reflecting |
83 | * is reflecting |
89 | */ |
84 | */ |
90 | for (i=0; i < pen->num_vertices; i++) { |
85 | for (i=0; i < pen->num_vertices; i++) { |
91 | double theta = 2 * M_PI * i / (double) pen->num_vertices; |
- | |
92 | double dx = radius * cos (reflect ? -theta : theta); |
- | |
93 | double dy = radius * sin (reflect ? -theta : theta); |
- | |
94 | cairo_pen_vertex_t *v = &pen->vertices[i]; |
86 | cairo_pen_vertex_t *v = &pen->vertices[i]; |
- | 87 | double theta = 2 * M_PI * i / (double) pen->num_vertices, dx, dy; |
|
- | 88 | if (reflect) |
|
- | 89 | theta = -theta; |
|
- | 90 | dx = radius * cos (theta); |
|
- | 91 | dy = radius * sin (theta); |
|
95 | cairo_matrix_transform_distance (ctm, &dx, &dy); |
92 | cairo_matrix_transform_distance (ctm, &dx, &dy); |
96 | v->point.x = _cairo_fixed_from_double (dx); |
93 | v->point.x = _cairo_fixed_from_double (dx); |
97 | v->point.y = _cairo_fixed_from_double (dy); |
94 | v->point.y = _cairo_fixed_from_double (dy); |
98 | } |
95 | } |
Line 271... | Line 268... | ||
271 | 268 | ||
272 | Note that this also equation works for M == m (a circle) as it |
269 | Note that this also equation works for M == m (a circle) as it |
273 | doesn't matter where on the circle the error is computed. |
270 | doesn't matter where on the circle the error is computed. |
Line 274... | Line 271... | ||
274 | */ |
271 | */ |
275 | 272 | ||
276 | static int |
273 | int |
277 | _cairo_pen_vertices_needed (double tolerance, |
274 | _cairo_pen_vertices_needed (double tolerance, |
278 | double radius, |
275 | double radius, |
279 | const cairo_matrix_t *matrix) |
276 | const cairo_matrix_t *matrix) |
280 | { |
277 | { |
281 | /* |
278 | /* |
282 | * the pen is a circle that gets transformed to an ellipse by matrix. |
279 | * the pen is a circle that gets transformed to an ellipse by matrix. |
283 | * compute major axis length for a pen with the specified radius. |
280 | * compute major axis length for a pen with the specified radius. |
284 | * we don't need the minor axis length. |
- | |
285 | */ |
281 | * we don't need the minor axis length. |
286 | 282 | */ |
|
287 | double major_axis = _cairo_matrix_transformed_circle_major_axis (matrix, |
- | |
288 | radius); |
- | |
289 | - | ||
290 | /* |
- | |
291 | * compute number of vertices needed |
283 | double major_axis = _cairo_matrix_transformed_circle_major_axis (matrix, |
Line 292... | Line 284... | ||
292 | */ |
284 | radius); |
- | 285 | int num_vertices; |
|
293 | int num_vertices; |
286 | |
294 | 287 | if (tolerance >= 4*major_axis) { /* XXX relaxed from 2*major for inkscape */ |
|
295 | /* Where tolerance / M is > 1, we use 4 points */ |
288 | num_vertices = 1; |
296 | if (tolerance >= major_axis) { |
289 | } else if (tolerance >= major_axis) { |
297 | num_vertices = 4; |
- | |
Line 298... | Line 290... | ||
298 | } else { |
290 | num_vertices = 4; |
299 | double delta = acos (1 - tolerance / major_axis); |
291 | } else { |
300 | num_vertices = ceil (M_PI / delta); |
292 | num_vertices = ceil (2*M_PI / acos (1 - tolerance / major_axis)); |
Line 394... | Line 386... | ||
394 | if (i < 0) |
386 | if (i < 0) |
395 | i = pen->num_vertices - 1; |
387 | i = pen->num_vertices - 1; |
Line 396... | Line 388... | ||
396 | 388 | ||
397 | return i; |
389 | return i; |
- | 390 | } |
|
- | 391 | ||
- | 392 | void |
|
- | 393 | _cairo_pen_find_active_cw_vertices (const cairo_pen_t *pen, |
|
- | 394 | const cairo_slope_t *in, |
|
- | 395 | const cairo_slope_t *out, |
|
- | 396 | int *start, int *stop) |
|
- | 397 | { |
|
- | 398 | ||
- | 399 | int lo = 0, hi = pen->num_vertices; |
|
- | 400 | int i; |
|
- | 401 | ||
- | 402 | i = (lo + hi) >> 1; |
|
- | 403 | do { |
|
- | 404 | if (_cairo_slope_compare (&pen->vertices[i].slope_cw, in) < 0) |
|
- | 405 | lo = i; |
|
- | 406 | else |
|
- | 407 | hi = i; |
|
- | 408 | i = (lo + hi) >> 1; |
|
- | 409 | } while (hi - lo > 1); |
|
- | 410 | if (_cairo_slope_compare (&pen->vertices[i].slope_cw, in) < 0) |
|
- | 411 | if (++i == pen->num_vertices) |
|
- | 412 | i = 0; |
|
- | 413 | *start = i; |
|
- | 414 | ||
- | 415 | if (_cairo_slope_compare (out, &pen->vertices[i].slope_ccw) >= 0) { |
|
- | 416 | lo = i; |
|
- | 417 | hi = i + pen->num_vertices; |
|
- | 418 | i = (lo + hi) >> 1; |
|
- | 419 | do { |
|
- | 420 | int j = i; |
|
- | 421 | if (j >= pen->num_vertices) |
|
- | 422 | j -= pen->num_vertices; |
|
- | 423 | if (_cairo_slope_compare (&pen->vertices[j].slope_cw, out) > 0) |
|
- | 424 | hi = i; |
|
- | 425 | else |
|
- | 426 | lo = i; |
|
- | 427 | i = (lo + hi) >> 1; |
|
- | 428 | } while (hi - lo > 1); |
|
- | 429 | if (i >= pen->num_vertices) |
|
- | 430 | i -= pen->num_vertices; |
|
- | 431 | } |
|
- | 432 | *stop = i; |
|
- | 433 | } |
|
- | 434 | ||
- | 435 | void |
|
- | 436 | _cairo_pen_find_active_ccw_vertices (const cairo_pen_t *pen, |
|
- | 437 | const cairo_slope_t *in, |
|
- | 438 | const cairo_slope_t *out, |
|
- | 439 | int *start, int *stop) |
|
- | 440 | { |
|
- | 441 | int lo = 0, hi = pen->num_vertices; |
|
- | 442 | int i; |
|
- | 443 | ||
- | 444 | i = (lo + hi) >> 1; |
|
- | 445 | do { |
|
- | 446 | if (_cairo_slope_compare (in, &pen->vertices[i].slope_ccw) < 0) |
|
- | 447 | lo = i; |
|
- | 448 | else |
|
- | 449 | hi = i; |
|
- | 450 | i = (lo + hi) >> 1; |
|
- | 451 | } while (hi - lo > 1); |
|
- | 452 | if (_cairo_slope_compare (in, &pen->vertices[i].slope_ccw) < 0) |
|
- | 453 | if (++i == pen->num_vertices) |
|
- | 454 | i = 0; |
|
- | 455 | *start = i; |
|
- | 456 | ||
- | 457 | if (_cairo_slope_compare (&pen->vertices[i].slope_cw, out) <= 0) { |
|
- | 458 | lo = i; |
|
- | 459 | hi = i + pen->num_vertices; |
|
- | 460 | i = (lo + hi) >> 1; |
|
- | 461 | do { |
|
- | 462 | int j = i; |
|
- | 463 | if (j >= pen->num_vertices) |
|
- | 464 | j -= pen->num_vertices; |
|
- | 465 | if (_cairo_slope_compare (out, &pen->vertices[j].slope_ccw) > 0) |
|
- | 466 | hi = i; |
|
- | 467 | else |
|
- | 468 | lo = i; |
|
- | 469 | i = (lo + hi) >> 1; |
|
- | 470 | } while (hi - lo > 1); |
|
- | 471 | if (i >= pen->num_vertices) |
|
- | 472 | i -= pen->num_vertices; |
|
- | 473 | } |
|
- | 474 | *stop = i; |