Index: src/cairo-private.h =================================================================== RCS file: /cvs/cairo/cairo/src/cairo-private.h,v retrieving revision 1.4 diff -u -8 -p -r1.4 cairo-private.h --- src/cairo-private.h 20 Jun 2005 16:59:23 -0000 1.4 +++ src/cairo-private.h 21 Nov 2005 22:42:12 -0000 @@ -42,11 +42,13 @@ struct _cairo { unsigned int ref_count; cairo_status_t status; cairo_path_fixed_t path; cairo_gstate_t *gstate; + + cairo_user_data_array_t user_data; }; #endif /* CAIRO_PRIVATE_H */ Index: src/cairo.c =================================================================== RCS file: /cvs/cairo/cairo/src/cairo.c,v retrieving revision 1.137 diff -u -8 -p -r1.137 cairo.c --- src/cairo.c 10 Oct 2005 16:16:21 -0000 1.137 +++ src/cairo.c 21 Nov 2005 22:42:13 -0000 @@ -48,17 +48,18 @@ static const cairo_t cairo_nil = { CAIRO_STATUS_NO_MEMORY, /* status */ { /* path */ NULL, NULL, /* op_buf_head, op_buf_tail */ NULL, NULL, /* arg_buf_head, arg_buf_tail */ { 0, 0 }, /* last_move_point */ { 0, 0 }, /* current point */ FALSE, /* has_current_point */ }, - NULL /* gstate */ + NULL, /* gstate */ + { 0, 0, 0, NULL } /* user_data */ }; #include /* This has to be updated whenever cairo_status_t is extended. That's * a bit of a pain, but it should be easy to always catch as long as * one adds a new test case to test a trigger of the new status value. */ @@ -199,16 +200,18 @@ cairo_create (cairo_surface_t *target) _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); return cr; } cr->gstate = _cairo_gstate_create (target); if (cr->gstate == NULL) _cairo_set_error (cr, CAIRO_STATUS_NO_MEMORY); + _cairo_user_data_array_init (&cr->user_data); + return cr; } /** * cairo_reference: * @cr: a #cairo_t * * Increases the reference count on @cr by one. This prevents @@ -254,16 +257,18 @@ cairo_destroy (cairo_t *cr) cairo_gstate_t *tmp = cr->gstate; cr->gstate = tmp->next; _cairo_gstate_destroy (tmp); } _cairo_path_fixed_fini (&cr->path); + _cairo_user_data_array_fini (&cr->user_data); + free (cr); } /** * cairo_save: * @cr: a #cairo_t * * Makes a copy of the current state of @cr and saves it @@ -2594,8 +2599,57 @@ cairo_status_to_string (cairo_status_t s void _cairo_restrict_value (double *value, double min, double max) { if (*value < min) *value = min; else if (*value > max) *value = max; } + +/** + * cairo_get_user_data + * @cr: a #cairo_t + * @key: the address of the #cairo_user_data_key_t the user data was + * attached to + * + * Return user data previously attached to @cr using the specified + * key. If no user data has been attached with the given key this + * function returns %NULL. + * + * Return value: the user data previously attached or %NULL. + **/ +void * +cairo_get_user_data (cairo_t *cr, + const cairo_user_data_key_t *key) +{ + return _cairo_user_data_array_get_data (&cr->user_data, + key); +} + +/** + * cairo_set_user_data: + * @cr: a #cairo_t + * @key: the address of a #cairo_user_data_key_t to attach the user data to + * @user_data: the user data to attach to the surface + * @destroy: a #cairo_destroy_func_t which will be called when the + * cairo object is destroyed or when new user data is attached using the + * same key. + * + * Attach user data to @cr. To remove user data from a cr, + * call this function with the key that was used to set it and %NULL + * for @data. + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a + * slot could not be allocated for the user data. + */ +cairo_status_t +cairo_set_user_data (cairo_t *cr, + const cairo_user_data_key_t *key, + void *user_data, + cairo_destroy_func_t destroy) +{ + if (cr->ref_count == -1) + return CAIRO_STATUS_NO_MEMORY; + + return _cairo_user_data_array_set_data (&cr->user_data, + key, user_data, destroy); +} Index: src/cairo.h =================================================================== RCS file: /cvs/cairo/cairo/src/cairo.h,v retrieving revision 1.155 diff -u -8 -p -r1.155 cairo.h --- src/cairo.h 10 Oct 2005 19:45:15 -0000 1.155 +++ src/cairo.h 21 Nov 2005 22:42:13 -0000 @@ -975,16 +975,28 @@ cairo_get_target (cairo_t *cr); typedef enum _cairo_path_data_type { CAIRO_PATH_MOVE_TO, CAIRO_PATH_LINE_TO, CAIRO_PATH_CURVE_TO, CAIRO_PATH_CLOSE_PATH } cairo_path_data_type_t; +/* User data */ + +cairo_public void * +cairo_get_user_data (cairo_t *cr, + const cairo_user_data_key_t *key); + +cairo_public cairo_status_t +cairo_set_user_data (cairo_t *cr, + const cairo_user_data_key_t *key, + void *user_data, + cairo_destroy_func_t destroy); + /** * cairo_path_data_t: * * #cairo_path_data_t is used to represent the path data inside a * #cairo_path_t. * * The data structure is designed to try to balance the demands of * efficiency and ease-of-use. A path is represented as an array of