diff options
author | Vladimir Vukicevic <vladimir@pobox.com> | 2008-02-06 13:01:52 -0800 |
---|---|---|
committer | Vladimir Vukicevic <vladimir@h-232.office.mozilla.org> | 2008-02-06 13:07:13 -0800 |
commit | bf1f7f70b61b5bb657b2531dab63c541ac8fb59d (patch) | |
tree | 4fd061561341162c7ea544c4382f72cbe597969c | |
parent | e104fcab1c8c8d9a7a7962a1dbea0c87867c8f9a (diff) |
Do correct calculation of pen dimensions for stroke optimization
-rw-r--r-- | src/cairo-path-stroke.c | 33 | ||||
-rw-r--r-- | src/cairo-rectangle.c | 2 | ||||
-rw-r--r-- | src/cairo-stroke-style.c | 17 | ||||
-rw-r--r-- | src/cairoint.h | 11 |
4 files changed, 41 insertions, 22 deletions
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 71510b1f9..b82c28a32 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -192,30 +192,23 @@ _cairo_stroker_init (cairo_stroker_t *stroker, stroker->has_bounds = _cairo_traps_get_limit (traps, &stroker->bounds); if (stroker->has_bounds) { - /* Extend the bounds by the line width in each direction so that we correctly - * capture segment endcaps and other similar renderings that would extend beyond - * the segment itself. + /* Extend the bounds in each direction to account for the maximum area + * we might generate trapezoids, to capture line segments that are outside + * of the bounds but which might generate rendering that's within bounds. */ - double width_x = stroker->style->line_width; - double width_y = stroker->style->line_width; - - cairo_fixed_t fixed_x, fixed_y; - - if (stroke_style->line_join == CAIRO_LINE_JOIN_MITER) { - width_x *= stroker->style->miter_limit; - width_y *= stroker->style->miter_limit; - } + double dx, dy; + cairo_fixed_t fdx, fdy; - cairo_matrix_transform_distance (stroker->ctm, &width_x, &width_y); + _cairo_stroke_style_max_distance_from_path (stroker->style, stroker->ctm, &dx, &dy); - fixed_x = _cairo_fixed_from_double (width_x); - fixed_y = _cairo_fixed_from_double (width_y); + fdx = _cairo_fixed_from_double (dx); + fdy = _cairo_fixed_from_double (dy); - stroker->bounds.p1.x -= fixed_x; - stroker->bounds.p2.x += fixed_x; + stroker->bounds.p1.x -= fdx; + stroker->bounds.p2.x += fdx; - stroker->bounds.p1.y -= fixed_y; - stroker->bounds.p2.y += fixed_y; + stroker->bounds.p1.y -= fdy; + stroker->bounds.p2.y += fdy; } return CAIRO_STATUS_SUCCESS; @@ -864,7 +857,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) segment.p2.y = _cairo_fixed_from_double (dy2) + p1->y; if (fully_in_bounds || - _cairo_box_intersects_line (&stroker->bounds, &segment)) + _cairo_box_intersects_line_segment (&stroker->bounds, &segment)) { if (stroker->dash_on) { status = _cairo_stroker_add_sub_edge (stroker, &segment.p1, &segment.p2, slope_dx, slope_dy, &sub_start, &sub_end); diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c index 7ebdfb59d..d2ec52d48 100644 --- a/src/cairo-rectangle.c +++ b/src/cairo-rectangle.c @@ -106,7 +106,7 @@ _cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t * */ cairo_bool_t -_cairo_box_intersects_line (cairo_box_t *box, cairo_line_t *line) +_cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line) { cairo_fixed_t t1, t2, t3, t4; cairo_int64_t t1y, t2y, t3x, t4x; diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c index a7c17b2fd..3bc234e90 100644 --- a/src/cairo-stroke-style.c +++ b/src/cairo-stroke-style.c @@ -84,3 +84,20 @@ _cairo_stroke_style_fini (cairo_stroke_style_t *style) } style->num_dashes = 0; } + +/* + * For a stroke in the given style, compute the maximum distance + * from the path that vertices could be generated. In the case + * of rotation in the ctm, the distance will not be exact. + */ +void +_cairo_stroke_style_max_distance_from_path (const cairo_stroke_style_t *style, + const cairo_matrix_t *ctm, + double *dx, double *dy) +{ + double style_expansion = MAX(style->line_cap == CAIRO_LINE_CAP_SQUARE ? M_SQRT1_2 : 0.5, + style->line_join == CAIRO_LINE_JOIN_MITER ? style->miter_limit : 0.5); + + *dx = style->line_width * style_expansion * (fabs(ctm->xx) + fabs(ctm->xy)); + *dy = style->line_width * style_expansion * (fabs(ctm->yy) + fabs(ctm->yx)); +} diff --git a/src/cairoint.h b/src/cairoint.h index 2a1df7bba..0ca08f40a 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -98,6 +98,10 @@ _cairo_win32_tmpfile (void); #define M_SQRT2 1.41421356237309504880 #endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.707106781186547524400844362104849039 +#endif + #undef ARRAY_LENGTH #define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0]))) @@ -180,7 +184,7 @@ cairo_private void _cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t *src); cairo_private cairo_bool_t -_cairo_box_intersects_line (cairo_box_t *box, cairo_line_t *line); +_cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line); cairo_private cairo_bool_t _cairo_box_contains_point (cairo_box_t *box, cairo_point_t *point); @@ -1482,6 +1486,11 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style, cairo_private void _cairo_stroke_style_fini (cairo_stroke_style_t *style); +cairo_private void +_cairo_stroke_style_max_distance_from_path (const cairo_stroke_style_t *style, + const cairo_matrix_t *ctm, + double *dx, double *dy); + /* cairo-surface.c */ cairo_private cairo_surface_t * |