[cairo-commit] cairo/src cairo-array.c, 1.11, 1.12 cairo-meta-surface.c, 1.23, 1.24 cairo-win32-font.c, 1.47, 1.48 cairoint.h, 1.239, 1.240

Carl Worth commit at pdx.freedesktop.org
Wed Dec 21 16:35:35 PST 2005


Committed by: cworth

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv21440/src

Modified Files:
	cairo-array.c cairo-meta-surface.c cairo-win32-font.c 
	cairoint.h 
Log Message:

2005-12-21  Carl Worth  <cworth at cworth.org>

        Here is a cleaner implementation of the _cairo_array_t change
        which was previously committed inadvertently.

        * src/cairoint.h:
        * src/cairo-array.c: (_cairo_array_fini), (_cairo_array_grow_by),
        (_cairo_array_index), (_cairo_array_allocate),
        (_cairo_user_data_array_fini), (_cairo_user_data_array_get_data),
        (_cairo_user_data_array_set_data): Fix buggy implementation of
        _cairo_array_snapshot by changing array->elements to be a pointer
        to a pointer. This extra level of indirection allows the snapshot
        array to point to a pointer which will itself get changed when new
        storage is needed for a growing array. Previously, the snapshot
        would be left pointing at stale storage.

        * src/cairo-meta-surface.c: (_cairo_meta_surface_finish),
        (_cairo_meta_surface_replay):
        * src/cairo-win32-font.c: (_flush_glyphs): Fix to call
        _cairo_array_index rather than grabbing array->elements directly
        and casting (which cast is now wrong with the change in
        implementation of array->index).


Index: cairo-array.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-array.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- cairo-array.c	21 Dec 2005 20:20:06 -0000	1.11
+++ cairo-array.c	22 Dec 2005 00:35:33 -0000	1.12
@@ -96,7 +96,10 @@
     if (array->is_snapshot)
 	return;
 
-    free (array->elements);
+    if (array->elements) {
+	free (* array->elements);
+	free (array->elements);
+    }
 }
 
 /**
@@ -127,8 +130,15 @@
     while (new_size < required_size)
 	new_size = new_size * 2;
 
+    if (array->elements == NULL) {
+	array->elements = malloc (sizeof (char *));
+	if (array->elements == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+	*array->elements = NULL;
+    }
+
     array->size = new_size;
-    new_elements = realloc (array->elements,
+    new_elements = realloc (*array->elements,
 			    array->size * array->element_size);
 
     if (new_elements == NULL) {
@@ -136,7 +146,7 @@
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
-    array->elements = new_elements;
+    *array->elements = new_elements;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -179,9 +189,25 @@
 void *
 _cairo_array_index (cairo_array_t *array, int index)
 {
+    /* We allow an index of 0 for the no-elements case.
+     * This makes for cleaner calling code which will often look like:
+     *
+     *    elements = _cairo_array_index (array, num_elements);
+     *	  for (i=0; i < num_elements; i++) {
+     *        ... use elements[i] here ...
+     *    }
+     *
+     * which in the num_elements==0 case gets the NULL pointer here,
+     * but never dereferences it.
+     */
+    if (array->elements == NULL) {
+	assert (index == 0);
+	return NULL;
+    }
+
     assert (0 <= index && index < array->num_elements);
 
-    return (void *) &array->elements[index * array->element_size];
+    return (void *) &(*array->elements)[index * array->element_size];
 }
 
 /**
@@ -276,7 +302,7 @@
 
     assert (array->num_elements + num_elements <= array->size);
 
-    *elements = &array->elements[array->num_elements * array->element_size];
+    *elements = &(*array->elements)[array->num_elements * array->element_size];
 
     array->num_elements += num_elements;
 
@@ -331,7 +357,7 @@
     cairo_user_data_slot_t *slots;
 
     num_slots = array->num_elements;
-    slots = (cairo_user_data_slot_t *) array->elements;
+    slots = _cairo_array_index (array, 0);
     for (i = 0; i < num_slots; i++) {
 	if (slots[i].user_data != NULL && slots[i].destroy != NULL)
 	    slots[i].destroy (slots[i].user_data);
@@ -365,7 +391,7 @@
 	return NULL;
 
     num_slots = array->num_elements;
-    slots = (cairo_user_data_slot_t *) array->elements;
+    slots = _cairo_array_index (array, 0);
     for (i = 0; i < num_slots; i++) {
 	if (slots[i].key == key)
 	    return slots[i].user_data;
@@ -412,7 +438,7 @@
 
     slot = NULL;
     num_slots = array->num_elements;
-    slots = (cairo_user_data_slot_t *) array->elements;
+    slots = _cairo_array_index (array, 0);
     for (i = 0; i < num_slots; i++) {
 	if (slots[i].key == key) {
 	    slot = &slots[i];

Index: cairo-meta-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-meta-surface.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- cairo-meta-surface.c	21 Dec 2005 20:20:06 -0000	1.23
+++ cairo-meta-surface.c	22 Dec 2005 00:35:33 -0000	1.24
@@ -104,7 +104,7 @@
     }
 
     num_elements = meta->commands.num_elements;
-    elements = (cairo_command_t **) meta->commands.elements;
+    elements = _cairo_array_index (&meta->commands, 0);
     for (i = 0; i < num_elements; i++) {
 	command = elements[i];
 	switch (command->type) {
@@ -605,7 +605,7 @@
     _cairo_clip_init (&clip, target);    
 
     num_elements = meta->commands.num_elements;
-    elements = (cairo_command_t **) meta->commands.elements;
+    elements = _cairo_array_index (&meta->commands, 0);
     for (i = 0; i < num_elements; i++) {
 	command = elements[i];
 	switch (command->type) {

Index: cairo-win32-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32-font.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- cairo-win32-font.c	21 Dec 2005 20:20:06 -0000	1.47
+++ cairo-win32-font.c	22 Dec 2005 00:35:33 -0000	1.48
@@ -893,16 +893,18 @@
 {
     cairo_status_t status;
     int dx = 0;
+    WCHAR * elements;
 
     status = _cairo_array_append (&state->dx, &dx);
     if (status)
 	return status;
     
+    elements = _cairo_array_index (&state->glyphs, 0);
     if (!ExtTextOutW (state->hdc,
 		      state->start_x, state->last_y,
 		      ETO_GLYPH_INDEX,
 		      NULL,
-		      (WCHAR *)state->glyphs.elements,
+		      elements,
 		      state->glyphs.num_elements,
 		      (int *)state->dx.elements)) {
 	return _cairo_win32_print_gdi_error ("_flush_glyphs");

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.239
retrieving revision 1.240
diff -u -d -r1.239 -r1.240
--- cairoint.h	21 Dec 2005 20:20:06 -0000	1.239
+++ cairoint.h	22 Dec 2005 00:35:33 -0000	1.240
@@ -334,7 +334,7 @@
     int size;
     int num_elements;
     int element_size;
-    char *elements;
+    char **elements;
 
     cairo_bool_t is_snapshot;
 };



More information about the cairo-commit mailing list