diff options
-rw-r--r-- | doc/public/cairo-sections.txt | 1 | ||||
-rw-r--r-- | doc/public/tmpl/cairo-paths.sgml | 10 | ||||
-rw-r--r-- | src/cairo-gstate.c | 11 | ||||
-rw-r--r-- | src/cairo.c | 30 | ||||
-rw-r--r-- | src/cairo.h | 5 | ||||
-rw-r--r-- | src/cairoint.h | 7 | ||||
-rw-r--r-- | test/get-path-extents.c | 33 |
7 files changed, 87 insertions, 10 deletions
diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index 44842717..88e9c8ae 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -326,6 +326,7 @@ cairo_text_path cairo_rel_curve_to cairo_rel_line_to cairo_rel_move_to +cairo_path_extents </SECTION> <SECTION> diff --git a/doc/public/tmpl/cairo-paths.sgml b/doc/public/tmpl/cairo-paths.sgml index 3be71a45..3d68342c 100644 --- a/doc/public/tmpl/cairo-paths.sgml +++ b/doc/public/tmpl/cairo-paths.sgml @@ -236,3 +236,13 @@ Creating paths and manipulating path data @dy: +<!-- ##### FUNCTION cairo_path_extents ##### --> +<para> + +</para> + +@cr: +@x1: +@y1: +@x2: +@y2: diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 3577d845..a00a52c1 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -818,6 +818,17 @@ _cairo_gstate_stroke_to_path (cairo_gstate_t *gstate) } */ +void +_cairo_gstate_path_extents (cairo_gstate_t *gstate, + cairo_path_fixed_t *path, + double *x1, double *y1, + double *x2, double *y2) +{ + _cairo_path_fixed_bounds (path, x1, y1, x2, y2, gstate->tolerance); + + _cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL); +} + static cairo_status_t _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, cairo_pattern_t *pattern, diff --git a/src/cairo.c b/src/cairo.c index 4a7aec11..42411cee 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1870,6 +1870,36 @@ cairo_close_path (cairo_t *cr) slim_hidden_def(cairo_close_path); /** + * cairo_path_extents: + * @cr: a cairo context + * @x1: left of the resulting extents + * @y1: top of the resulting extents + * @x2: right of the resulting extents + * @y2: bottom of the resulting extents + * + * Computes a bounding box in user coordinates covering the points + * on the current path. If the current path is empty, + * returns an empty rectangle (0,0, 0,0). Stroke parameters, + * surface dimensions and clipping are not taken into account. This + * will be the same as the value returned by cairo_fill_extents() + * unless the area enclosed by the path is empty. + * + * Since: 1.6 + **/ +void +cairo_path_extents (cairo_t *cr, + double *x1, double *y1, double *x2, double *y2) +{ + if (cr->status) + return; + + _cairo_gstate_path_extents (cr->gstate, + cr->path, + x1, y1, x2, y2); +} +slim_hidden_def (cairo_path_extents); + +/** * cairo_paint: * @cr: a cairo context * diff --git a/src/cairo.h b/src/cairo.h index 4c58c144..157b6e13 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -584,6 +584,11 @@ cairo_stroke_to_path (cairo_t *cr); cairo_public void cairo_close_path (cairo_t *cr); +cairo_public void +cairo_path_extents (cairo_t *cr, + double *x1, double *y1, + double *x2, double *y2); + /* Painting functions */ cairo_public void cairo_paint (cairo_t *cr); diff --git a/src/cairoint.h b/src/cairoint.h index ea3c2b6f..7c1d2d50 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1005,6 +1005,12 @@ _cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate, double *x2, double *y2, cairo_bool_t *is_tight); +cairo_private void +_cairo_gstate_path_extents (cairo_gstate_t *gstate, + cairo_path_fixed_t *path, + double *x1, double *y1, + double *x2, double *y2); + cairo_private cairo_status_t _cairo_gstate_paint (cairo_gstate_t *gstate); @@ -2220,6 +2226,7 @@ slim_hidden_proto (cairo_matrix_translate); slim_hidden_proto (cairo_move_to); slim_hidden_proto (cairo_new_path); slim_hidden_proto (cairo_paint); +slim_hidden_proto (cairo_path_extents); slim_hidden_proto (cairo_pattern_create_for_surface); slim_hidden_proto (cairo_pattern_create_rgb); slim_hidden_proto (cairo_pattern_create_rgba); diff --git a/test/get-path-extents.c b/test/get-path-extents.c index b20b13f2..a06e301d 100644 --- a/test/get-path-extents.c +++ b/test/get-path-extents.c @@ -36,7 +36,7 @@ cairo_test_t test = { draw }; -enum ExtentsType { FILL, STROKE }; +enum ExtentsType { FILL, STROKE, PATH }; enum Relation { EQUALS, APPROX_EQUALS, CONTAINS }; @@ -59,6 +59,10 @@ check_extents (const char *message, cairo_t *cr, enum ExtentsType type, type_string = "stroke"; cairo_stroke_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2); break; + case PATH: + type_string = "path"; + cairo_path_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2); + break; } /* let empty rects match */ @@ -118,7 +122,8 @@ draw (cairo_t *cr, int width, int height) phase = "No path"; if (!check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0) || - !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 0, 0)) + !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 0, 0) || + !check_extents (phase, cr2, PATH, EQUALS, 0, 0, 0, 0)) ret = CAIRO_TEST_FAILURE; cairo_save (cr2); @@ -164,7 +169,8 @@ draw (cairo_t *cr, int width, int height) cairo_move_to (cr2, 0, 180); cairo_line_to (cr2, 750, 180); if (!check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0) || - !check_extents (phase, cr2, STROKE, EQUALS, -5, 175, 760, 10)) + !check_extents (phase, cr2, STROKE, EQUALS, -5, 175, 760, 10) || + !check_extents (phase, cr2, PATH, EQUALS, 0, 180, 755, 0)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); @@ -173,7 +179,8 @@ draw (cairo_t *cr, int width, int height) cairo_save (cr2); cairo_rectangle (cr2, 10, 10, 80, 80); if (!check_extents (phase, cr2, FILL, EQUALS, 10, 10, 80, 80) || - !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 90, 90)) + !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 90, 90) || + !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 80, 80)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); @@ -183,7 +190,8 @@ draw (cairo_t *cr, int width, int height) cairo_rectangle (cr2, 10, 10, 10, 10); cairo_rectangle (cr2, 20, 20, 10, 10); if (!check_extents (phase, cr2, FILL, EQUALS, 10, 10, 20, 20) || - !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 30, 30)) + !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 30, 30) || + !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 20, 20)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); @@ -197,7 +205,8 @@ draw (cairo_t *cr, int width, int height) /* miter joins protrude 5*(1+sqrt(2)) above the top-left corner and to the right of the bottom-right corner */ if (!check_extents (phase, cr2, FILL, EQUALS, 10, 10, 80, 80) || - !check_extents (phase, cr2, STROKE, CONTAINS, 0, 5, 95, 95)) + !check_extents (phase, cr2, STROKE, CONTAINS, 0, 5, 95, 95) || + !check_extents (phase, cr2, PATH, CONTAINS, 10, 10, 80, 80)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); @@ -240,7 +249,8 @@ draw (cairo_t *cr, int width, int height) cairo_text_path (cr2, "The quick brown fox jumped over the lazy dog."); cairo_set_line_width (cr2, 2.0); if (!check_extents (phase, cr2, FILL, EQUALS, 0, 0, extents.width, extents.height) || - !check_extents (phase, cr2, STROKE, EQUALS, -1, -1, extents.width+2, extents.height+2)) + !check_extents (phase, cr2, STROKE, EQUALS, -1, -1, extents.width+2, extents.height+2) || + !check_extents (phase, cr2, PATH, EQUALS, 0, 0, extents.width, extents.height)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); @@ -250,7 +260,8 @@ draw (cairo_t *cr, int width, int height) cairo_scale (cr2, 2, 2); cairo_rectangle (cr2, 5, 5, 40, 40); if (!check_extents (phase, cr2, FILL, EQUALS, 5, 5, 40, 40) || - !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 50, 50)) + !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 50, 50) || + !check_extents (phase, cr2, PATH, EQUALS, 5, 5, 40, 40)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); @@ -262,7 +273,8 @@ draw (cairo_t *cr, int width, int height) cairo_rectangle (cr2, 5, 5, 40, 40); cairo_restore (cr2); if (!check_extents (phase, cr2, FILL, EQUALS, 10, 10, 80, 80) || - !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 90, 90)) + !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 90, 90) || + !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 80, 80)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); @@ -281,7 +293,8 @@ draw (cairo_t *cr, int width, int height) the largest axis-aligned square is a bit over 38 on either side of the axes. */ if (!check_extents (phase, cr2, FILL, CONTAINS, -35, -35, 35, 35) || - !check_extents (phase, cr2, STROKE, CONTAINS, -38, -38, 38, 38)) + !check_extents (phase, cr2, STROKE, CONTAINS, -38, -38, 38, 38) || + !check_extents (phase, cr2, PATH, CONTAINS, -35, -35, 35, 35)) ret = CAIRO_TEST_FAILURE; cairo_new_path (cr2); cairo_restore (cr2); |