[cairo-commit] src/cairoint.h src/cairo-path-stroke.c src/cairo-rectangle.c src/cairo-stroke-style.c
Vladimir Vukicevic
vladimir at kemper.freedesktop.org
Wed Feb 6 13:09:26 PST 2008
src/cairo-path-stroke.c | 33 +++++++++++++--------------------
src/cairo-rectangle.c | 2 +-
src/cairo-stroke-style.c | 17 +++++++++++++++++
src/cairoint.h | 11 ++++++++++-
4 files changed, 41 insertions(+), 22 deletions(-)
New commits:
commit bf1f7f70b61b5bb657b2531dab63c541ac8fb59d
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Wed Feb 6 13:01:52 2008 -0800
Do correct calculation of pen dimensions for stroke optimization
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 71510b1..b82c28a 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 7ebdfb5..d2ec52d 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 a7c17b2..3bc234e 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 2a1df7b..0ca08f4 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 *
More information about the cairo-commit
mailing list