Bumped version to 0.1.12 for new cairo_in_stroke and cairo_in_fill functions.

Added new cairo_in_stroke and cairo_in_fill.
* src/cairo_gstate.c (_cairo_gstate_in_stroke): (_cairo_gstate_in_fill): New functions to support for cairo_in_stroke and cairo_in_fill. Many thanks to Thomas Hunger <info@teh-web.de> for the initial implementation which demonstrated how easy this would be and pushed me to go and write it already.
Fixed to use _cairo_fixed_from_double instead of XDoubleToFixed.
This commit is contained in:
Carl Worth 2003-11-06 18:33:28 +00:00
parent a3ad052795
commit f86a979b49
11 changed files with 294 additions and 27 deletions

View file

@ -1,3 +1,28 @@
2003-11-06 Carl Worth <cworth@isi.edu>
* configure.in (CAIRO_VERSION): Bumped version to 0.1.12 for new
cairo_in_stroke and cairo_in_fill functions.
* src/cairo.h:
* src/cairo.c (cairo_in_stroke):
(cairo_in_fill): Added new cairo_in_stroke and cairo_in_fill.
* src/cairo_traps.c (_cairo_trap_contains):
(_cairo_traps_contain): * src/cairo_gstate.c
(_cairo_gstate_in_stroke):
(_cairo_gstate_in_fill): New functions to support for
cairo_in_stroke and cairo_in_fill. Many thanks to Thomas Hunger
<info@teh-web.de> for the initial implementation which
demonstrated how easy this would be and pushed me to go and write
it already.
* src/cairo_gstate.c (_cairo_gstate_clip_and_composite_trapezoids):
* src/cairo_traps.c (_line_segs_intersect_ceil):
* src/cairo_path.c (_cairo_path_move_to):
(_cairo_path_line_to):
(_cairo_path_curve_to): Fixed to use _cairo_fixed_from_double
instead of XDoubleToFixed.
2003-11-06 Carl Worth <cworth@east.isi.edu>
* src/cairo.h: Add comment pondering memory management semantics

View file

@ -3,7 +3,7 @@ AC_INIT(src/cairo.h)
dnl ===========================================================================
# Package version number, (as distinct from shared library version)
CAIRO_VERSION=0.1.11
CAIRO_VERSION=0.1.12
# libtool shared library version

View file

@ -1194,6 +1194,33 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate)
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_in_stroke (cairo_gstate_t *gstate,
double x,
double y,
int *inside_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_traps_t traps;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
_cairo_traps_init (&traps);
status = _cairo_path_stroke_to_traps (&gstate->path, gstate, &traps);
if (status)
goto BAIL;
*inside_ret = _cairo_traps_contain (&traps, x, y);
BAIL:
_cairo_traps_fini (&traps);
return status;
}
/* Warning: This call modifies the coordinates of traps */
static cairo_status_t
_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
@ -1241,8 +1268,8 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
an offset for the trapezoids. Need to manually shift all
the coordinates to align with the offset origin of the clip
surface. */
xoff = XDoubleToFixed (gstate->clip.x);
yoff = XDoubleToFixed (gstate->clip.y);
xoff = _cairo_fixed_from_double (gstate->clip.x);
yoff = _cairo_fixed_from_double (gstate->clip.y);
for (i=0, t=traps->traps; i < traps->num_traps; i++, t++) {
t->top -= yoff;
t->bottom -= yoff;
@ -1356,6 +1383,31 @@ _cairo_gstate_fill (cairo_gstate_t *gstate)
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
double x,
double y,
int *inside_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_traps_t traps;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
_cairo_traps_init (&traps);
status = _cairo_path_fill_to_traps (&gstate->path, gstate, &traps);
if (status)
goto BAIL;
*inside_ret = _cairo_traps_contain (&traps, x, y);
BAIL:
_cairo_traps_fini (&traps);
return status;
}
cairo_status_t
_cairo_gstate_copy_page (cairo_gstate_t *gstate)
{

View file

@ -127,8 +127,8 @@ _cairo_path_move_to (cairo_path_t *path, double x, double y)
{
cairo_point_t point;
point.x = XDoubleToFixed (x);
point.y = XDoubleToFixed (y);
point.x = _cairo_fixed_from_double (x);
point.y = _cairo_fixed_from_double (y);
return _cairo_path_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
}
@ -138,8 +138,8 @@ _cairo_path_line_to (cairo_path_t *path, double x, double y)
{
cairo_point_t point;
point.x = XDoubleToFixed (x);
point.y = XDoubleToFixed (y);
point.x = _cairo_fixed_from_double (x);
point.y = _cairo_fixed_from_double (y);
return _cairo_path_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
}
@ -152,14 +152,14 @@ _cairo_path_curve_to (cairo_path_t *path,
{
cairo_point_t point[3];
point[0].x = XDoubleToFixed (x1);
point[0].y = XDoubleToFixed (y1);
point[0].x = _cairo_fixed_from_double (x1);
point[0].y = _cairo_fixed_from_double (y1);
point[1].x = XDoubleToFixed (x2);
point[1].y = XDoubleToFixed (y2);
point[1].x = _cairo_fixed_from_double (x2);
point[1].y = _cairo_fixed_from_double (y2);
point[2].x = XDoubleToFixed (x3);
point[2].y = XDoubleToFixed (y3);
point[2].x = _cairo_fixed_from_double (x3);
point[2].y = _cairo_fixed_from_double (y3);
return _cairo_path_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
}

View file

@ -403,7 +403,7 @@ _line_segs_intersect_ceil (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_
if (m1 == m2)
return 0;
y_intersect = XDoubleToFixed ((b2 - b1) / (m1 - m2));
y_intersect = _cairo_fixed_from_double ((b2 - b1) / (m1 - m2));
if (m1 < m2) {
cairo_line_t *t;
@ -566,3 +566,45 @@ _cairo_traps_tessellate_polygon (cairo_traps_t *traps,
}
return CAIRO_STATUS_SUCCESS;
}
static int
_cairo_trap_contains (cairo_trapezoid_t *t, cairo_point_t *pt)
{
cairo_slope_t slope_left, slope_pt, slope_right;
if (t->top > pt->y)
return 0;
if (t->bottom < pt->y)
return 0;
_cairo_slope_init (&slope_left, &t->left.p1, &t->left.p2);
_cairo_slope_init (&slope_pt, &t->left.p1, pt);
if (_cairo_slope_compare (&slope_left, &slope_pt) < 0)
return 0;
_cairo_slope_init (&slope_right, &t->right.p1, &t->right.p2);
_cairo_slope_init (&slope_pt, &t->right.p1, pt);
if (_cairo_slope_compare (&slope_pt, &slope_right) < 0)
return 0;
return 1;
}
int
_cairo_traps_contain (cairo_traps_t *traps, double x, double y)
{
int i;
cairo_point_t point;
point.x = _cairo_fixed_from_double (x);
point.y = _cairo_fixed_from_double (y);
for (i = 0; i < traps->num_traps; i++) {
if (_cairo_trap_contains (&traps->traps[i], &point))
return 1;
}
return 0;
}

View file

@ -601,6 +601,38 @@ cairo_show_page (cairo_t *cr)
cr->status = _cairo_gstate_show_page (cr->gstate);
}
int
cairo_in_stroke (cairo_t *cr, double x, double y)
{
int inside;
if (cr->status)
return 0;
cr->status = _cairo_gstate_in_stroke (cr->gstate, x, y, &inside);
if (cr->status)
return 0;
return inside;
}
int
cairo_in_fill (cairo_t *cr, double x, double y)
{
int inside;
if (cr->status)
return 0;
cr->status = _cairo_gstate_in_fill (cr->gstate, x, y, &inside);
if (cr->status)
return 0;
return inside;
}
void
cairo_clip (cairo_t *cr)
{

View file

@ -301,6 +301,13 @@ cairo_copy_page (cairo_t *cr);
extern void __external_linkage
cairo_show_page (cairo_t *cr);
/* Insideness testing */
extern int __external_linkage
cairo_in_stroke (cairo_t *cr, double x, double y);
extern int __external_linkage
cairo_in_fill (cairo_t *cr, double x, double y);
/* Clipping */
extern void __external_linkage
cairo_clip (cairo_t *cr);

View file

@ -1194,6 +1194,33 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate)
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_in_stroke (cairo_gstate_t *gstate,
double x,
double y,
int *inside_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_traps_t traps;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
_cairo_traps_init (&traps);
status = _cairo_path_stroke_to_traps (&gstate->path, gstate, &traps);
if (status)
goto BAIL;
*inside_ret = _cairo_traps_contain (&traps, x, y);
BAIL:
_cairo_traps_fini (&traps);
return status;
}
/* Warning: This call modifies the coordinates of traps */
static cairo_status_t
_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
@ -1241,8 +1268,8 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
an offset for the trapezoids. Need to manually shift all
the coordinates to align with the offset origin of the clip
surface. */
xoff = XDoubleToFixed (gstate->clip.x);
yoff = XDoubleToFixed (gstate->clip.y);
xoff = _cairo_fixed_from_double (gstate->clip.x);
yoff = _cairo_fixed_from_double (gstate->clip.y);
for (i=0, t=traps->traps; i < traps->num_traps; i++, t++) {
t->top -= yoff;
t->bottom -= yoff;
@ -1356,6 +1383,31 @@ _cairo_gstate_fill (cairo_gstate_t *gstate)
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
double x,
double y,
int *inside_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_traps_t traps;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
_cairo_traps_init (&traps);
status = _cairo_path_fill_to_traps (&gstate->path, gstate, &traps);
if (status)
goto BAIL;
*inside_ret = _cairo_traps_contain (&traps, x, y);
BAIL:
_cairo_traps_fini (&traps);
return status;
}
cairo_status_t
_cairo_gstate_copy_page (cairo_gstate_t *gstate)
{

View file

@ -127,8 +127,8 @@ _cairo_path_move_to (cairo_path_t *path, double x, double y)
{
cairo_point_t point;
point.x = XDoubleToFixed (x);
point.y = XDoubleToFixed (y);
point.x = _cairo_fixed_from_double (x);
point.y = _cairo_fixed_from_double (y);
return _cairo_path_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
}
@ -138,8 +138,8 @@ _cairo_path_line_to (cairo_path_t *path, double x, double y)
{
cairo_point_t point;
point.x = XDoubleToFixed (x);
point.y = XDoubleToFixed (y);
point.x = _cairo_fixed_from_double (x);
point.y = _cairo_fixed_from_double (y);
return _cairo_path_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
}
@ -152,14 +152,14 @@ _cairo_path_curve_to (cairo_path_t *path,
{
cairo_point_t point[3];
point[0].x = XDoubleToFixed (x1);
point[0].y = XDoubleToFixed (y1);
point[0].x = _cairo_fixed_from_double (x1);
point[0].y = _cairo_fixed_from_double (y1);
point[1].x = XDoubleToFixed (x2);
point[1].y = XDoubleToFixed (y2);
point[1].x = _cairo_fixed_from_double (x2);
point[1].y = _cairo_fixed_from_double (y2);
point[2].x = XDoubleToFixed (x3);
point[2].y = XDoubleToFixed (y3);
point[2].x = _cairo_fixed_from_double (x3);
point[2].y = _cairo_fixed_from_double (y3);
return _cairo_path_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
}

View file

@ -403,7 +403,7 @@ _line_segs_intersect_ceil (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_
if (m1 == m2)
return 0;
y_intersect = XDoubleToFixed ((b2 - b1) / (m1 - m2));
y_intersect = _cairo_fixed_from_double ((b2 - b1) / (m1 - m2));
if (m1 < m2) {
cairo_line_t *t;
@ -566,3 +566,45 @@ _cairo_traps_tessellate_polygon (cairo_traps_t *traps,
}
return CAIRO_STATUS_SUCCESS;
}
static int
_cairo_trap_contains (cairo_trapezoid_t *t, cairo_point_t *pt)
{
cairo_slope_t slope_left, slope_pt, slope_right;
if (t->top > pt->y)
return 0;
if (t->bottom < pt->y)
return 0;
_cairo_slope_init (&slope_left, &t->left.p1, &t->left.p2);
_cairo_slope_init (&slope_pt, &t->left.p1, pt);
if (_cairo_slope_compare (&slope_left, &slope_pt) < 0)
return 0;
_cairo_slope_init (&slope_right, &t->right.p1, &t->right.p2);
_cairo_slope_init (&slope_pt, &t->right.p1, pt);
if (_cairo_slope_compare (&slope_pt, &slope_right) < 0)
return 0;
return 1;
}
int
_cairo_traps_contain (cairo_traps_t *traps, double x, double y)
{
int i;
cairo_point_t point;
point.x = _cairo_fixed_from_double (x);
point.y = _cairo_fixed_from_double (y);
for (i = 0; i < traps->num_traps; i++) {
if (_cairo_trap_contains (&traps->traps[i], &point))
return 1;
}
return 0;
}

View file

@ -721,6 +721,18 @@ _cairo_gstate_copy_page (cairo_gstate_t *gstate);
extern cairo_status_t __internal_linkage
_cairo_gstate_show_page (cairo_gstate_t *gstate);
extern cairo_status_t __internal_linkage
_cairo_gstate_in_stroke (cairo_gstate_t *gstate,
double x,
double y,
int *inside_ret);
extern cairo_status_t __internal_linkage
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
double x,
double y,
int *inside_ret);
extern cairo_status_t __internal_linkage
_cairo_gstate_clip (cairo_gstate_t *gstate);
@ -1125,6 +1137,9 @@ _cairo_traps_tessellate_polygon (cairo_traps_t *traps,
cairo_polygon_t *poly,
cairo_fill_rule_t fill_rule);
extern int __internal_linkage
_cairo_traps_contain (cairo_traps_t *traps, double x, double y);
/* cairo_slope.c */
extern void __internal_linkage
_cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b);