Originally: 2005-02-24 Carl Worth <cworth@cworth.org>

Add const qualifier to cairo_user_data_key_t arguments.
Originally: 2005-02-15 Kristian Høgsberg <krh@redhat.com>
Add these two functions to set and get user data on an surface.
Function prototypes for new functions.
Test case for user data functions.
This commit is contained in:
Carl Worth 2005-03-10 08:59:11 +00:00
parent 12abad4759
commit c67ba13a6e
22 changed files with 444 additions and 20 deletions

View file

@ -1,3 +1,21 @@
2005-03-10 Carl Worth <cworth@cworth.org>
Originally: 2005-02-24 Carl Worth <cworth@cworth.org>
* src/cairo_surface.c (cairo_surface_set_user_data)
(cairo_surface_get_user_data):
* src/cairo.h: Add const qualifier to cairo_user_data_key_t
arguments.
Originally: 2005-02-15 Kristian Høgsberg <krh@redhat.com>
* src/cairo_surface.c (cairo_surface_get_data, cairo_surface_set_data):
Add these two functions to set and get user data on an surface.
* src/cairo.h: Function prototypes for new functions.
* test/user_data.c: Test case for user data functions.
2005-03-09 Carl Worth <cworth@cworth.org>
* test/cairo_test.c (cairo_test): Move filename initialization up

View file

@ -14,6 +14,9 @@ ATSUI Fonts
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_atsui_font_create ##### -->
<para>

View file

@ -14,6 +14,9 @@ FreeType Fonts
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_ft_font_create ##### -->
<para>

View file

@ -14,6 +14,9 @@ Glitz backend
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_set_target_glitz ##### -->
<para>

View file

@ -38,6 +38,9 @@ cairo_matrix_t
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### TYPEDEF cairo_matrix_t ##### -->
<para>

View file

@ -14,6 +14,9 @@ cairo_pattern_t
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### TYPEDEF cairo_pattern_t ##### -->
<para>

View file

@ -14,6 +14,9 @@ PDF Backend
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_set_target_pdf ##### -->
<para>

View file

@ -14,6 +14,9 @@ PNG Backend
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_set_target_png ##### -->
<para>

View file

@ -14,6 +14,9 @@ PS Backend
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_set_target_ps ##### -->
<para>

View file

@ -14,6 +14,9 @@ Quartz Backend
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_set_target_quartz_context ##### -->
<para>

View file

@ -14,6 +14,9 @@ cairo_surface_t
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### TYPEDEF cairo_surface_t ##### -->
<para>

View file

@ -14,6 +14,9 @@ XCB Backend
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_set_target_xcb ##### -->
<para>

View file

@ -14,6 +14,9 @@ XLib Backend
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION cairo_set_target_drawable ##### -->
<para>

View file

@ -24,6 +24,9 @@ Drawing contexts.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### TYPEDEF cairo_t ##### -->
<para>
@ -688,7 +691,7 @@ Drawing contexts.
@num_glyphs:
<!-- ##### FUNCTION cairo_current_font ##### -->
<!-- ##### FUNCTION cairo_get_font ##### -->
<para>
</para>
@ -697,7 +700,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_font_extents ##### -->
<!-- ##### FUNCTION cairo_get_font_extents ##### -->
<para>
</para>
@ -771,6 +774,17 @@ Drawing contexts.
@font:
<!-- ##### FUNCTION cairo_font_extents ##### -->
<para>
</para>
@font:
@font_matrix:
@extents:
@Returns:
<!-- ##### FUNCTION cairo_font_glyph_extents ##### -->
<para>
@ -794,7 +808,7 @@ Drawing contexts.
@height:
<!-- ##### FUNCTION cairo_current_operator ##### -->
<!-- ##### FUNCTION cairo_get_operator ##### -->
<para>
</para>
@ -803,7 +817,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_rgb_color ##### -->
<!-- ##### FUNCTION cairo_get_rgb_color ##### -->
<para>
</para>
@ -814,7 +828,7 @@ Drawing contexts.
@blue:
<!-- ##### FUNCTION cairo_current_pattern ##### -->
<!-- ##### FUNCTION cairo_get_pattern ##### -->
<para>
</para>
@ -823,7 +837,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_alpha ##### -->
<!-- ##### FUNCTION cairo_get_alpha ##### -->
<para>
</para>
@ -832,7 +846,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_tolerance ##### -->
<!-- ##### FUNCTION cairo_get_tolerance ##### -->
<para>
</para>
@ -841,7 +855,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_point ##### -->
<!-- ##### FUNCTION cairo_get_current_point ##### -->
<para>
</para>
@ -851,7 +865,7 @@ Drawing contexts.
@y:
<!-- ##### FUNCTION cairo_current_fill_rule ##### -->
<!-- ##### FUNCTION cairo_get_fill_rule ##### -->
<para>
</para>
@ -860,7 +874,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_line_width ##### -->
<!-- ##### FUNCTION cairo_get_line_width ##### -->
<para>
</para>
@ -869,7 +883,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_line_cap ##### -->
<!-- ##### FUNCTION cairo_get_line_cap ##### -->
<para>
</para>
@ -878,7 +892,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_line_join ##### -->
<!-- ##### FUNCTION cairo_get_line_join ##### -->
<para>
</para>
@ -887,7 +901,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_miter_limit ##### -->
<!-- ##### FUNCTION cairo_get_miter_limit ##### -->
<para>
</para>
@ -896,7 +910,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_matrix ##### -->
<!-- ##### FUNCTION cairo_get_matrix ##### -->
<para>
</para>
@ -905,7 +919,7 @@ Drawing contexts.
@matrix:
<!-- ##### FUNCTION cairo_current_target_surface ##### -->
<!-- ##### FUNCTION cairo_get_target_surface ##### -->
<para>
</para>
@ -914,7 +928,7 @@ Drawing contexts.
@Returns:
<!-- ##### FUNCTION cairo_current_path ##### -->
<!-- ##### FUNCTION cairo_get_path ##### -->
<para>
</para>
@ -927,7 +941,7 @@ Drawing contexts.
@closure:
<!-- ##### FUNCTION cairo_current_path_flat ##### -->
<!-- ##### FUNCTION cairo_get_path_flat ##### -->
<para>
</para>

View file

@ -38,6 +38,12 @@
#include "cairoint.h"
typedef struct {
const cairo_user_data_key_t *key;
void *user_data;
cairo_destroy_func_t destroy;
} cairo_user_data_slot_t;
void
_cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend)
@ -45,6 +51,8 @@ _cairo_surface_init (cairo_surface_t *surface,
surface->backend = backend;
surface->ref_count = 1;
_cairo_array_init (&surface->user_data_slots,
sizeof (cairo_user_data_slot_t));
_cairo_matrix_init (&surface->matrix);
surface->filter = CAIRO_FILTER_NEAREST;
@ -145,6 +153,88 @@ cairo_surface_destroy (cairo_surface_t *surface)
}
slim_hidden_def(cairo_surface_destroy);
/**
* cairo_surface_get_user_data:
* @surface: a #cairo_surface_t
* @key: the address of the #cairo_user_data_key_t the user data was
* attached to
*
* Return user data previously attached to @surface 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_surface_get_user_data (cairo_surface_t *surface,
const cairo_user_data_key_t *key)
{
int i, num_slots;
cairo_user_data_slot_t *slots;
num_slots = surface->user_data_slots.num_elements;
slots = (cairo_user_data_slot_t *) surface->user_data_slots.elements;
for (i = 0; i < num_slots; i++) {
if (slots[i].key == key)
return slots[i].user_data;
}
return NULL;
}
/**
* cairo_surface_set_user_data:
* @surface: a #cairo_surface_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
* surface is destroyed or when new user data is attached using the
* same key.
*
* Attach user data to @surface. 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.
**/
cairo_status_t
cairo_surface_set_user_data (cairo_surface_t *surface,
const cairo_user_data_key_t *key,
void *user_data,
cairo_destroy_func_t destroy)
{
int i, num_slots;
cairo_user_data_slot_t *slots, *s;
s = NULL;
num_slots = surface->user_data_slots.num_elements;
slots = (cairo_user_data_slot_t *) surface->user_data_slots.elements;
for (i = 0; i < num_slots; i++) {
if (slots[i].key == key) {
if (slots[i].user_data != NULL)
slots[i].destroy (slots[i].user_data);
s = &slots[i];
break;
}
if (slots[i].user_data == NULL) {
s = &slots[i];
break;
}
}
if (s == NULL)
s = _cairo_array_append (&surface->user_data_slots, NULL, 1);
if (s == NULL)
return CAIRO_STATUS_NO_MEMORY;
s->key = key;
s->user_data = user_data;
s->destroy = destroy;
return CAIRO_STATUS_SUCCESS;
}
double
_cairo_surface_pixels_per_inch (cairo_surface_t *surface)
{

View file

@ -705,6 +705,15 @@ cairo_status (cairo_t *cr);
const char *
cairo_status_string (cairo_t *cr);
/**
* cairo_destroy_func_t
*
* #cairo_destroy_func_t the type of function which is called when a
* data element is destroyed. It is passed the pointer to the data
* element and should free any memory and resources allocated for it.
*/
typedef void (*cairo_destroy_func_t) (void *data);
/* Surface manipulation */
/* XXX: We may want to rename this function in light of the new
virtualized surface backends... */
@ -759,6 +768,30 @@ cairo_surface_set_filter (cairo_surface_t *surface, cairo_filter_t filter);
cairo_filter_t
cairo_surface_get_filter (cairo_surface_t *surface);
/**
* cairo_user_data_key_t
*
* #cairo_user_data_key_t is used for attaching user data to cairo
* data structures. The actual contents of the struct is never used,
* and there is no need to initialize the object; only the unique
* address of a #cairo_data_key_t object is used. Typically, you
* would just use the address of a static #cairo_data_key_t object.
*/
typedef struct _cairo_user_data_key {
int unused;
} cairo_user_data_key_t;
void *
cairo_surface_get_user_data (cairo_surface_t *surface,
const cairo_user_data_key_t *key);
cairo_status_t
cairo_surface_set_user_data (cairo_surface_t *surface,
const cairo_user_data_key_t *key,
void *data,
cairo_destroy_func_t destroy);
/* Image-surface functions */
cairo_surface_t *

View file

@ -38,6 +38,12 @@
#include "cairoint.h"
typedef struct {
const cairo_user_data_key_t *key;
void *user_data;
cairo_destroy_func_t destroy;
} cairo_user_data_slot_t;
void
_cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend)
@ -45,6 +51,8 @@ _cairo_surface_init (cairo_surface_t *surface,
surface->backend = backend;
surface->ref_count = 1;
_cairo_array_init (&surface->user_data_slots,
sizeof (cairo_user_data_slot_t));
_cairo_matrix_init (&surface->matrix);
surface->filter = CAIRO_FILTER_NEAREST;
@ -145,6 +153,88 @@ cairo_surface_destroy (cairo_surface_t *surface)
}
slim_hidden_def(cairo_surface_destroy);
/**
* cairo_surface_get_user_data:
* @surface: a #cairo_surface_t
* @key: the address of the #cairo_user_data_key_t the user data was
* attached to
*
* Return user data previously attached to @surface 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_surface_get_user_data (cairo_surface_t *surface,
const cairo_user_data_key_t *key)
{
int i, num_slots;
cairo_user_data_slot_t *slots;
num_slots = surface->user_data_slots.num_elements;
slots = (cairo_user_data_slot_t *) surface->user_data_slots.elements;
for (i = 0; i < num_slots; i++) {
if (slots[i].key == key)
return slots[i].user_data;
}
return NULL;
}
/**
* cairo_surface_set_user_data:
* @surface: a #cairo_surface_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
* surface is destroyed or when new user data is attached using the
* same key.
*
* Attach user data to @surface. 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.
**/
cairo_status_t
cairo_surface_set_user_data (cairo_surface_t *surface,
const cairo_user_data_key_t *key,
void *user_data,
cairo_destroy_func_t destroy)
{
int i, num_slots;
cairo_user_data_slot_t *slots, *s;
s = NULL;
num_slots = surface->user_data_slots.num_elements;
slots = (cairo_user_data_slot_t *) surface->user_data_slots.elements;
for (i = 0; i < num_slots; i++) {
if (slots[i].key == key) {
if (slots[i].user_data != NULL)
slots[i].destroy (slots[i].user_data);
s = &slots[i];
break;
}
if (slots[i].user_data == NULL) {
s = &slots[i];
break;
}
}
if (s == NULL)
s = _cairo_array_append (&surface->user_data_slots, NULL, 1);
if (s == NULL)
return CAIRO_STATUS_NO_MEMORY;
s->key = key;
s->user_data = user_data;
s->destroy = destroy;
return CAIRO_STATUS_SUCCESS;
}
double
_cairo_surface_pixels_per_inch (cairo_surface_t *surface)
{

View file

@ -666,6 +666,7 @@ struct _cairo_surface {
const cairo_surface_backend_t *backend;
unsigned int ref_count;
cairo_array_t user_data_slots;
cairo_matrix_t matrix;
cairo_filter_t filter;

View file

@ -2,6 +2,7 @@
.libs
Makefile
Makefile.in
clip_twice
coverage
fill_rule
imagediff
@ -11,7 +12,7 @@ move_to_show_surface
pixman_rotate
text_cache_crash
text_rotate
clip_twice
user_data
*-out.png
*-diff.png

View file

@ -10,8 +10,8 @@ linear_gradient \
move_to_show_surface \
pixman_rotate \
text_cache_crash \
text_rotate
text_rotate \
user_data
# And all new tests go here too. I really don't like having to repeat
# this list. Anyone know a good way to avoid it? Can I use a wildcard
@ -79,6 +79,7 @@ move_to_show_surface_SOURCES = move_to_show_surface.c $(cairo_test_lib)
pixman_rotate_SOURCES = pixman_rotate.c $(cairo_test_lib)
text_cache_crash_SOURCES = text_cache_crash.c $(cairo_test_lib)
text_rotate_SOURCES = text_rotate.c $(cairo_test_lib)
user_data_SOURCES = user_data.c
noinst_PROGRAMS = imagediff
imagediff_SOURCES = imagediff.c $(cairo_test_lib)

70
test/user-data.c Normal file
View file

@ -0,0 +1,70 @@
/*
* Copyright © 2005 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Red Hat, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. Red Hat, Inc. makes no representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Kristian Høgsberg <krh@redhat.com>
*/
#include <cairo.h>
#include <assert.h>
#include <stdlib.h>
static void
destroy_data1 (void *p)
{
*(int *) p = 1;
}
static void
destroy_data2 (void *p)
{
*(int *) p = 2;
}
int
main (void)
{
cairo_surface_t *surface;
static const cairo_user_data_key_t key1, key2;
int data1, data2;
data1 = 0;
data2 = 0;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
assert (cairo_surface_set_user_data (surface, &key1, &data1, destroy_data1)
== CAIRO_STATUS_SUCCESS);
assert (cairo_surface_set_user_data (surface, &key2, &data2, destroy_data2)
== CAIRO_STATUS_SUCCESS);
assert (cairo_surface_get_user_data (surface, &key1) == &data1);
assert (cairo_surface_set_user_data (surface, &key1, NULL, NULL)
== CAIRO_STATUS_SUCCESS);
assert (data1 == 1);
assert (data2 == 0);
data1 = 0;
assert (cairo_surface_set_user_data (surface, &key1, &data1, destroy_data1)
== CAIRO_STATUS_SUCCESS);
cairo_surface_destroy (surface);
assert (data1 = 1);
assert (data2 = 2);
return 0;
}

70
test/user_data.c Normal file
View file

@ -0,0 +1,70 @@
/*
* Copyright © 2005 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Red Hat, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. Red Hat, Inc. makes no representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Kristian Høgsberg <krh@redhat.com>
*/
#include <cairo.h>
#include <assert.h>
#include <stdlib.h>
static void
destroy_data1 (void *p)
{
*(int *) p = 1;
}
static void
destroy_data2 (void *p)
{
*(int *) p = 2;
}
int
main (void)
{
cairo_surface_t *surface;
static const cairo_user_data_key_t key1, key2;
int data1, data2;
data1 = 0;
data2 = 0;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
assert (cairo_surface_set_user_data (surface, &key1, &data1, destroy_data1)
== CAIRO_STATUS_SUCCESS);
assert (cairo_surface_set_user_data (surface, &key2, &data2, destroy_data2)
== CAIRO_STATUS_SUCCESS);
assert (cairo_surface_get_user_data (surface, &key1) == &data1);
assert (cairo_surface_set_user_data (surface, &key1, NULL, NULL)
== CAIRO_STATUS_SUCCESS);
assert (data1 == 1);
assert (data2 == 0);
data1 = 0;
assert (cairo_surface_set_user_data (surface, &key1, &data1, destroy_data1)
== CAIRO_STATUS_SUCCESS);
cairo_surface_destroy (surface);
assert (data1 = 1);
assert (data2 = 2);
return 0;
}