From cf7311852298e7d86d065a12fa962ba10fe60dcc Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Fri, 23 Feb 2007 13:05:18 -0800 Subject: [PATCH] [core] Add user_data and reference count getters to all objects user_data setters/getters were added to public refcounted objects that were missing them (cairo_t, pattern, scaled_font). Also, a refcount getter (cairo_*_get_reference_count) was added to all public refcounted objects. --- src/cairo-font.c | 18 ++++++++++ src/cairo-pattern.c | 76 +++++++++++++++++++++++++++++++++++++++ src/cairo-private.h | 2 ++ src/cairo-scaled-font.c | 78 +++++++++++++++++++++++++++++++++++++++-- src/cairo-surface.c | 17 +++++++++ src/cairo.c | 75 +++++++++++++++++++++++++++++++++++++++ src/cairo.h | 45 ++++++++++++++++++++++++ src/cairoint.h | 17 +++++---- 8 files changed, 319 insertions(+), 9 deletions(-) diff --git a/src/cairo-font.c b/src/cairo-font.c index a31054286..1b62aed0d 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -1,3 +1,4 @@ +/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ /* cairo - a vector graphics library with display and print output * * Copyright © 2002 University of Southern California @@ -163,6 +164,23 @@ cairo_font_face_get_type (cairo_font_face_t *font_face) return font_face->backend->type; } +/** + * cairo_font_face_get_reference_count: + * @font_face: a #cairo_font_face_t + * + * Returns the current reference count of @font_face. + * + * Return value: the current reference count of @font_face. If the + * object is a nil object, 0 will be returned. + * + * Since: 1.4 + **/ +unsigned int +cairo_font_face_get_reference_count (cairo_font_face_t *font_face) +{ + return font_face->ref_count; +} + /** * cairo_font_face_status: * @font_face: a #cairo_font_face_t diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index ae271f860..5060eff85 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -34,6 +34,7 @@ const cairo_solid_pattern_t cairo_pattern_nil = { { CAIRO_PATTERN_TYPE_SOLID, /* type */ CAIRO_REF_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NO_MEMORY, /* status */ + { 0, 0, 0, NULL }, /* user_data */ { 1., 0., 0., 1., 0., 0., }, /* matrix */ CAIRO_FILTER_DEFAULT, /* filter */ CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */ @@ -43,6 +44,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = { { CAIRO_PATTERN_TYPE_SOLID, /* type */ CAIRO_REF_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NULL_POINTER,/* status */ + { 0, 0, 0, NULL }, /* user_data */ { 1., 0., 0., 1., 0., 0., }, /* matrix */ CAIRO_FILTER_DEFAULT, /* filter */ CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */ @@ -84,6 +86,8 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type) pattern->ref_count = 1; pattern->status = CAIRO_STATUS_SUCCESS; + _cairo_user_data_array_init (&pattern->user_data); + if (type == CAIRO_PATTERN_TYPE_SURFACE) pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT; else @@ -165,6 +169,8 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern, void _cairo_pattern_fini (cairo_pattern_t *pattern) { + _cairo_user_data_array_fini (&pattern->user_data); + switch (pattern->type) { case CAIRO_PATTERN_TYPE_SOLID: break; @@ -572,6 +578,76 @@ cairo_pattern_destroy (cairo_pattern_t *pattern) } slim_hidden_def (cairo_pattern_destroy); +/** + * cairo_pattern_get_reference_count: + * @pattern: a #cairo_pattern_t + * + * Returns the current reference count of @pattern. + * + * Return value: the current reference count of @pattern. If the + * object is a nil object, 0 will be returned. + * + * Since: 1.4 + **/ +unsigned int +cairo_pattern_get_reference_count (cairo_pattern_t *pattern) +{ + return pattern->ref_count; +} + +/** + * cairo_pattern_get_user_data: + * @pattern: a #cairo_pattern_t + * @key: the address of the #cairo_user_data_key_t the user data was + * attached to + * + * Return user data previously attached to @pattern 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. + * + * Since: 1.4 + **/ +void * +cairo_pattern_get_user_data (cairo_pattern_t *pattern, + const cairo_user_data_key_t *key) +{ + return _cairo_user_data_array_get_data (&pattern->user_data, + key); +} + +/** + * cairo_pattern_set_user_data: + * @pattern: a #cairo_pattern_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 #cairo_pattern_t + * @destroy: a #cairo_destroy_func_t which will be called when the + * #cairo_t is destroyed or when new user data is attached using the + * same key. + * + * Attach user data to @pattern. To remove user data from a surface, + * 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. + * + * Since: 1.4 + **/ +cairo_status_t +cairo_pattern_set_user_data (cairo_pattern_t *pattern, + const cairo_user_data_key_t *key, + void *user_data, + cairo_destroy_func_t destroy) +{ + if (pattern->ref_count == CAIRO_REF_COUNT_INVALID) + return CAIRO_STATUS_NO_MEMORY; + + return _cairo_user_data_array_set_data (&pattern->user_data, + key, user_data, destroy); +} + static void _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern, double offset, diff --git a/src/cairo-private.h b/src/cairo-private.h index 7051f7ebd..24ab3c136 100644 --- a/src/cairo-private.h +++ b/src/cairo-private.h @@ -44,6 +44,8 @@ struct _cairo { cairo_status_t status; + cairo_user_data_array_t user_data; + cairo_path_fixed_t path; cairo_gstate_t *gstate; diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 02af48748..46ba5717b 100755 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -1,5 +1,5 @@ -/* $Id: cairo-scaled-font.c,v 1.12 2006-01-22 10:33:26 behdad Exp $ - * +/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ +/* * Copyright © 2005 Keith Packard * * This library is free software; you can redistribute it and/or @@ -75,6 +75,7 @@ static const cairo_scaled_font_t _cairo_scaled_font_nil = { { 0 }, /* hash_entry */ CAIRO_STATUS_NO_MEMORY, /* status */ CAIRO_REF_COUNT_INVALID, /* ref_count */ + { 0, 0, 0, NULL }, /* user_data */ NULL, /* font_face */ { 1., 0., 0., 1., 0, 0}, /* font_matrix */ { 1., 0., 0., 1., 0, 0}, /* ctm */ @@ -353,6 +354,8 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, { scaled_font->ref_count = 1; + _cairo_user_data_array_init (&scaled_font->user_data); + _cairo_scaled_font_init_key (scaled_font, font_face, font_matrix, ctm, options); @@ -426,6 +429,7 @@ _cairo_scaled_font_fini (cairo_scaled_font_t *scaled_font) scaled_font->backend->fini (scaled_font); + _cairo_user_data_array_fini (&scaled_font->user_data); } /** @@ -620,6 +624,76 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font) } slim_hidden_def (cairo_scaled_font_destroy); +/** + * cairo_scaled_font_get_reference_count: + * @scaled_font: a #cairo_scaled_font_t + * + * Returns the current reference count of @scaled_font. + * + * Return value: the current reference count of @scaled_font. If the + * object is a nil object, 0 will be returned. + * + * Since: 1.4 + **/ +unsigned int +cairo_scaled_font_get_reference_count (cairo_scaled_font_t *scaled_font) +{ + return scaled_font->ref_count; +} + +/** + * cairo_scaled_font_get_user_data: + * @scaled_font: a #cairo_scaled_font_t + * @key: the address of the #cairo_user_data_key_t the user data was + * attached to + * + * Return user data previously attached to @scaled_font 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. + * + * Since: 1.4 + **/ +void * +cairo_scaled_font_get_user_data (cairo_scaled_font_t *scaled_font, + const cairo_user_data_key_t *key) +{ + return _cairo_user_data_array_get_data (&scaled_font->user_data, + key); +} + +/** + * cairo_scaled_font_set_user_data: + * @scaled_font: a #cairo_scaled_font_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 #cairo_scaled_font_t + * @destroy: a #cairo_destroy_func_t which will be called when the + * #cairo_t is destroyed or when new user data is attached using the + * same key. + * + * Attach user data to @scaled_font. To remove user data from a surface, + * 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. + * + * Since: 1.4 + **/ +cairo_status_t +cairo_scaled_font_set_user_data (cairo_scaled_font_t *scaled_font, + const cairo_user_data_key_t *key, + void *user_data, + cairo_destroy_func_t destroy) +{ + if (scaled_font->ref_count == CAIRO_REF_COUNT_INVALID) + return CAIRO_STATUS_NO_MEMORY; + + return _cairo_user_data_array_set_data (&scaled_font->user_data, + key, user_data, destroy); +} + /* Public font API follows. */ /** diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 3c9df995a..e640fac12 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -391,6 +391,23 @@ cairo_surface_destroy (cairo_surface_t *surface) } slim_hidden_def(cairo_surface_destroy); +/** + * cairo_surface_get_reference_count: + * @surface: a #cairo_surface_t + * + * Returns the current reference count of @surface. + * + * Return value: the current reference count of @surface. If the + * object is a nil object, 0 will be returned. + * + * Since: 1.4 + **/ +unsigned int +cairo_surface_get_reference_count (cairo_surface_t *surface) +{ + return surface->ref_count; +} + /** * cairo_surface_finish: * @surface: the #cairo_surface_t to finish diff --git a/src/cairo.c b/src/cairo.c index 2e522a63b..5eda36efb 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -47,6 +47,7 @@ static const cairo_t cairo_nil = { CAIRO_REF_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NO_MEMORY, /* status */ + { 0, 0, 0, NULL }, /* user_data */ { /* path */ NULL, NULL, /* op_buf_head, op_buf_tail */ NULL, NULL, /* arg_buf_head, arg_buf_tail */ @@ -195,6 +196,8 @@ cairo_create (cairo_surface_t *target) cr->status = CAIRO_STATUS_SUCCESS; + _cairo_user_data_array_init (&cr->user_data); + _cairo_path_fixed_init (&cr->path); if (target == NULL) { @@ -269,10 +272,82 @@ cairo_destroy (cairo_t *cr) _cairo_path_fixed_fini (&cr->path); + _cairo_user_data_array_fini (&cr->user_data); + free (cr); } slim_hidden_def (cairo_destroy); +/** + * 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. + * + * Since: 1.4 + **/ +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 #cairo_t + * @destroy: a #cairo_destroy_func_t which will be called when the + * #cairo_t is destroyed or when new user data is attached using the + * same key. + * + * Attach user data to @cr. To remove user data from a surface, + * 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. + * + * Since: 1.4 + **/ +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 == CAIRO_REF_COUNT_INVALID) + return CAIRO_STATUS_NO_MEMORY; + + return _cairo_user_data_array_set_data (&cr->user_data, + key, user_data, destroy); +} + +/** + * cairo_get_reference_count: + * @cr: a #cairo_t + * + * Returns the current reference count of @cr. + * + * Return value: the current reference count of @cr. If the + * object is a nil object, 0 will be returned. + * + * Since: 1.4 + **/ +unsigned int +cairo_get_reference_count (cairo_t *cr) +{ + return cr->ref_count; +} + /** * cairo_save: * @cr: a #cairo_t diff --git a/src/cairo.h b/src/cairo.h index 2cb8e96f6..ba5ead6f3 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -276,6 +276,19 @@ cairo_reference (cairo_t *cr); cairo_public void cairo_destroy (cairo_t *cr); +cairo_public unsigned int +cairo_get_reference_count (cairo_t *cr); + +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_public void cairo_save (cairo_t *cr); @@ -972,6 +985,9 @@ cairo_font_face_reference (cairo_font_face_t *font_face); cairo_public void cairo_font_face_destroy (cairo_font_face_t *font_face); +cairo_public unsigned int +cairo_font_face_get_reference_count (cairo_font_face_t *font_face); + cairo_public cairo_status_t cairo_font_face_status (cairo_font_face_t *font_face); @@ -1045,12 +1061,25 @@ cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font); cairo_public void cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font); +cairo_public unsigned int +cairo_scaled_font_get_reference_count (cairo_scaled_font_t *scaled_font); + cairo_public cairo_status_t cairo_scaled_font_status (cairo_scaled_font_t *scaled_font); cairo_public cairo_font_type_t cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font); +cairo_public void * +cairo_scaled_font_get_user_data (cairo_scaled_font_t *scaled_font, + const cairo_user_data_key_t *key); + +cairo_public cairo_status_t +cairo_scaled_font_set_user_data (cairo_scaled_font_t *scaled_font, + const cairo_user_data_key_t *key, + void *user_data, + cairo_destroy_func_t destroy); + cairo_public void cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font, cairo_font_extents_t *extents); @@ -1268,6 +1297,9 @@ cairo_surface_finish (cairo_surface_t *surface); cairo_public void cairo_surface_destroy (cairo_surface_t *surface); +cairo_public unsigned int +cairo_surface_get_reference_count (cairo_surface_t *surface); + cairo_public cairo_status_t cairo_surface_status (cairo_surface_t *surface); @@ -1489,9 +1521,22 @@ cairo_pattern_reference (cairo_pattern_t *pattern); cairo_public void cairo_pattern_destroy (cairo_pattern_t *pattern); +cairo_public unsigned int +cairo_pattern_get_reference_count (cairo_pattern_t *pattern); + cairo_public cairo_status_t cairo_pattern_status (cairo_pattern_t *pattern); +cairo_public void * +cairo_pattern_get_user_data (cairo_pattern_t *pattern, + const cairo_user_data_key_t *key); + +cairo_public cairo_status_t +cairo_pattern_set_user_data (cairo_pattern_t *pattern, + const cairo_user_data_key_t *key, + void *user_data, + cairo_destroy_func_t destroy); + /** * cairo_pattern_type_t * @CAIRO_PATTERN_TYPE_SOLID: The pattern is a solid (uniform) diff --git a/src/cairoint.h b/src/cairoint.h index 2c145e066..65b0123a8 100755 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -241,7 +241,7 @@ do { \ assert (NOT_REACHED); \ } while (0) -#define CAIRO_REF_COUNT_INVALID ((unsigned int) -1) +#define CAIRO_REF_COUNT_INVALID (0) #include "cairo-wideint-private.h" @@ -578,6 +578,7 @@ struct _cairo_scaled_font { /* useful bits for _cairo_scaled_font_nil */ cairo_status_t status; unsigned int ref_count; + cairo_user_data_array_t user_data; /* hash key members */ cairo_font_face_t *font_face; /* may be NULL */ @@ -1117,12 +1118,14 @@ typedef enum { #define CAIRO_FILTER_DEFAULT CAIRO_FILTER_BEST struct _cairo_pattern { - cairo_pattern_type_t type; - unsigned int ref_count; - cairo_status_t status; - cairo_matrix_t matrix; - cairo_filter_t filter; - cairo_extend_t extend; + cairo_pattern_type_t type; + unsigned int ref_count; + cairo_status_t status; + cairo_user_data_array_t user_data; + + cairo_matrix_t matrix; + cairo_filter_t filter; + cairo_extend_t extend; }; typedef struct _cairo_solid_pattern {