mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-13 17:30:36 +01:00
[cairo] Add cairo_path_extents()
This new function gets the extents of the current path, whether or not they would be inked by a 'fill'. It differs from cairo_fill_extents() when the area enclosed by the path is 0. Includes documentation and updated test.
This commit is contained in:
parent
d923457c0f
commit
4177208be6
7 changed files with 87 additions and 10 deletions
|
|
@ -326,6 +326,7 @@ cairo_text_path
|
|||
cairo_rel_curve_to
|
||||
cairo_rel_line_to
|
||||
cairo_rel_move_to
|
||||
cairo_path_extents
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
|
|
|||
|
|
@ -236,3 +236,13 @@ Creating paths and manipulating path data
|
|||
@dy:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_path_extents ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@cr:
|
||||
@x1:
|
||||
@y1:
|
||||
@x2:
|
||||
@y2:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
30
src/cairo.c
30
src/cairo.c
|
|
@ -1869,6 +1869,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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue