Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1892 Rev 3959
Line -... Line 1...
-
 
1
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
1
/* cairo - a vector graphics library with display and print output
2
/* cairo - a vector graphics library with display and print output
2
 *
3
 *
3
 * Copyright © 2004 Red Hat, Inc
4
 * Copyright © 2004 Red Hat, Inc
4
 *
5
 *
5
 * This library is free software; you can redistribute it and/or
6
 * This library is free software; you can redistribute it and/or
Line 34... Line 35...
34
 *	Kristian Høgsberg 
35
 *	Kristian Høgsberg 
35
 *	Carl Worth 
36
 *	Carl Worth 
36
 */
37
 */
Line 37... Line 38...
37
 
38
 
-
 
39
#include "cairoint.h"
38
#include "cairoint.h"
40
#include "cairo-array-private.h"
Line 39... Line 41...
39
#include "cairo-error-private.h"
41
#include "cairo-error-private.h"
40
 
42
 
41
/**
43
/**
Line 51... Line 53...
51
 *
53
 *
52
 * When finished using the array, _cairo_array_fini() should be
54
 * When finished using the array, _cairo_array_fini() should be
53
 * called to free resources allocated during use of the array.
55
 * called to free resources allocated during use of the array.
54
 **/
56
 **/
55
void
57
void
56
_cairo_array_init (cairo_array_t *array, int element_size)
58
_cairo_array_init (cairo_array_t *array, unsigned int element_size)
57
{
59
{
58
    array->size = 0;
60
    array->size = 0;
59
    array->num_elements = 0;
61
    array->num_elements = 0;
60
    array->element_size = element_size;
62
    array->element_size = element_size;
61
    array->elements = NULL;
63
    array->elements = NULL;
62
 
-
 
63
    array->is_snapshot = FALSE;
-
 
64
}
-
 
65
 
-
 
66
/**
-
 
67
 * _cairo_array_init_snapshot:
-
 
68
 * @array: A #cairo_array_t to be initialized as a snapshot
-
 
69
 * @other: The #cairo_array_t from which to create the snapshot
-
 
70
 *
-
 
71
 * Initialize @array as an immutable copy of @other. It is an error to
-
 
72
 * call an array-modifying function (other than _cairo_array_fini) on
-
 
73
 * @array after calling this function.
-
 
74
 **/
-
 
75
void
-
 
76
_cairo_array_init_snapshot (cairo_array_t	*array,
-
 
77
			    const cairo_array_t *other)
-
 
78
{
-
 
79
    array->size = other->size;
-
 
80
    array->num_elements = other->num_elements;
-
 
81
    array->element_size = other->element_size;
-
 
82
    array->elements = other->elements;
-
 
83
 
-
 
84
    array->is_snapshot = TRUE;
-
 
85
}
64
}
Line 86... Line 65...
86
 
65
 
87
/**
66
/**
88
 * _cairo_array_fini:
67
 * _cairo_array_fini:
Line 93... Line 72...
93
 * _cairo_array_init() again first.
72
 * _cairo_array_init() again first.
94
 **/
73
 **/
95
void
74
void
96
_cairo_array_fini (cairo_array_t *array)
75
_cairo_array_fini (cairo_array_t *array)
97
{
76
{
98
    if (array->is_snapshot)
-
 
99
	return;
-
 
100
 
-
 
101
    if (array->elements) {
-
 
102
	free (* array->elements);
-
 
103
	free (array->elements);
77
    free (array->elements);
104
    }
78
}
105
}
-
 
Line 106... Line 79...
106
 
79
 
107
/**
80
/**
108
 * _cairo_array_grow_by:
81
 * _cairo_array_grow_by:
109
 * @array: a #cairo_array_t
82
 * @array: a #cairo_array_t
Line 118... Line 91...
118
    char *new_elements;
91
    char *new_elements;
119
    unsigned int old_size = array->size;
92
    unsigned int old_size = array->size;
120
    unsigned int required_size = array->num_elements + additional;
93
    unsigned int required_size = array->num_elements + additional;
121
    unsigned int new_size;
94
    unsigned int new_size;
Line 122... Line -...
122
 
-
 
123
    assert (! array->is_snapshot);
-
 
124
 
95
 
125
    /* check for integer overflow */
96
    /* check for integer overflow */
126
    if (required_size > INT_MAX || required_size < array->num_elements)
97
    if (required_size > INT_MAX || required_size < array->num_elements)
Line 127... Line 98...
127
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
98
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
Line 138... Line 109...
138
	new_size = old_size * 2;
109
	new_size = old_size * 2;
Line 139... Line 110...
139
 
110
 
140
    while (new_size < required_size)
111
    while (new_size < required_size)
Line 141... Line -...
141
	new_size = new_size * 2;
-
 
142
 
-
 
143
    if (array->elements == NULL) {
-
 
144
	array->elements = malloc (sizeof (char *));
-
 
145
	if (unlikely (array->elements == NULL))
-
 
146
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
147
 
-
 
148
	*array->elements = NULL;
-
 
149
    }
112
	new_size = new_size * 2;
150
 
113
 
151
    array->size = new_size;
114
    array->size = new_size;
Line 152... Line 115...
152
    new_elements = _cairo_realloc_ab (*array->elements,
115
    new_elements = _cairo_realloc_ab (array->elements,
153
			              array->size, array->element_size);
116
			              array->size, array->element_size);
154
 
117
 
155
    if (unlikely (new_elements == NULL)) {
118
    if (unlikely (new_elements == NULL)) {
Line 156... Line 119...
156
	array->size = old_size;
119
	array->size = old_size;
Line 157... Line 120...
157
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
120
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
158
    }
121
    }
Line 159... Line 122...
159
 
122
 
Line 171... Line 134...
171
 * beyond @num_elements are simply "forgotten".
134
 * beyond @num_elements are simply "forgotten".
172
 **/
135
 **/
173
void
136
void
174
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
137
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
175
{
138
{
176
    assert (! array->is_snapshot);
-
 
177
 
-
 
178
    if (num_elements < array->num_elements)
139
    if (num_elements < array->num_elements)
179
	array->num_elements = num_elements;
140
	array->num_elements = num_elements;
180
}
141
}
Line 181... Line 142...
181
 
142
 
Line 205... Line 166...
205
_cairo_array_index (cairo_array_t *array, unsigned int index)
166
_cairo_array_index (cairo_array_t *array, unsigned int index)
206
{
167
{
207
    /* We allow an index of 0 for the no-elements case.
168
    /* We allow an index of 0 for the no-elements case.
208
     * This makes for cleaner calling code which will often look like:
169
     * This makes for cleaner calling code which will often look like:
209
     *
170
     *
210
     *    elements = _cairo_array_index (array, num_elements);
171
     *    elements = _cairo_array_index (array, 0);
211
     *	  for (i=0; i < num_elements; i++) {
172
     *	  for (i=0; i < num_elements; i++) {
212
     *        ... use elements[i] here ...
173
     *        ... use elements[i] here ...
213
     *    }
174
     *    }
214
     *
175
     *
215
     * which in the num_elements==0 case gets the NULL pointer here,
176
     * which in the num_elements==0 case gets the NULL pointer here,
Line 218... Line 179...
218
    if (index == 0 && array->num_elements == 0)
179
    if (index == 0 && array->num_elements == 0)
219
	return NULL;
180
	return NULL;
Line 220... Line 181...
220
 
181
 
Line -... Line 182...
-
 
182
    assert (index < array->num_elements);
-
 
183
 
-
 
184
    return array->elements + index * array->element_size;
-
 
185
}
-
 
186
 
-
 
187
/**
-
 
188
 * _cairo_array_index_const:
-
 
189
 * @array: a #cairo_array_t
-
 
190
 * Returns: A pointer to the object stored at @index.
-
 
191
 *
-
 
192
 * If the resulting value is assigned to a pointer to an object of the same
-
 
193
 * element_size as initially passed to _cairo_array_init() then that
-
 
194
 * pointer may be used for further direct indexing with []. For
-
 
195
 * example:
-
 
196
 *
-
 
197
 * 
-
 
198
 *	cairo_array_t array;
-
 
199
 *	const double *values;
-
 
200
 *
-
 
201
 *	_cairo_array_init (&array, sizeof(double));
-
 
202
 *	... calls to _cairo_array_append() here ...
-
 
203
 *
-
 
204
 *	values = _cairo_array_index_const (&array, 0);
-
 
205
 *      for (i = 0; i < _cairo_array_num_elements (&array); i++)
-
 
206
 *	    ... read values[i] here ...
-
 
207
 * 
-
 
208
 **/
-
 
209
const void *
-
 
210
_cairo_array_index_const (const cairo_array_t *array, unsigned int index)
-
 
211
{
-
 
212
    /* We allow an index of 0 for the no-elements case.
-
 
213
     * This makes for cleaner calling code which will often look like:
-
 
214
     *
-
 
215
     *    elements = _cairo_array_index_const (array, 0);
-
 
216
     *	  for (i=0; i < num_elements; i++) {
-
 
217
     *        ... read elements[i] here ...
-
 
218
     *    }
-
 
219
     *
-
 
220
     * which in the num_elements==0 case gets the NULL pointer here,
-
 
221
     * but never dereferences it.
-
 
222
     */
-
 
223
    if (index == 0 && array->num_elements == 0)
-
 
224
	return NULL;
-
 
225
 
221
    assert (index < array->num_elements);
226
    assert (index < array->num_elements);
222
 
227
 
Line 223... Line 228...
223
    return (void *) &(*array->elements)[index * array->element_size];
228
    return array->elements + index * array->element_size;
224
}
229
}
225
 
230
 
226
/**
231
/**
227
 * _cairo_array_copy_element:
232
 * _cairo_array_copy_element:
228
 * @array: a #cairo_array_t
233
 * @array: a #cairo_array_t
229
 *
234
 *
230
 * Copy a single element out of the array from index @index into the
235
 * Copy a single element out of the array from index @index into the
231
 * location pointed to by @dst.
236
 * location pointed to by @dst.
-
 
237
 **/
-
 
238
void
232
 **/
239
_cairo_array_copy_element (const cairo_array_t *array,
233
void
240
			   unsigned int         index,
234
_cairo_array_copy_element (cairo_array_t *array, int index, void *dst)
241
			   void                *dst)
Line 235... Line 242...
235
{
242
{
236
    memcpy (dst, _cairo_array_index (array, index), array->element_size);
243
    memcpy (dst, _cairo_array_index_const (array, index), array->element_size);
237
}
244
}
Line 253... Line 260...
253
 **/
260
 **/
254
cairo_status_t
261
cairo_status_t
255
_cairo_array_append (cairo_array_t	*array,
262
_cairo_array_append (cairo_array_t	*array,
256
		     const void		*element)
263
		     const void		*element)
257
{
264
{
258
    assert (! array->is_snapshot);
-
 
259
 
-
 
260
    return _cairo_array_append_multiple (array, element, 1);
265
    return _cairo_array_append_multiple (array, element, 1);
261
}
266
}
Line 262... Line 267...
262
 
267
 
263
/**
268
/**
Line 273... Line 278...
273
 * operation.
278
 * operation.
274
 **/
279
 **/
275
cairo_status_t
280
cairo_status_t
276
_cairo_array_append_multiple (cairo_array_t	*array,
281
_cairo_array_append_multiple (cairo_array_t	*array,
277
			      const void	*elements,
282
			      const void	*elements,
278
			      int		 num_elements)
283
			      unsigned int	 num_elements)
279
{
284
{
280
    cairo_status_t status;
285
    cairo_status_t status;
281
    void *dest;
286
    void *dest;
Line 282... Line -...
282
 
-
 
283
    assert (! array->is_snapshot);
-
 
284
 
287
 
285
    status = _cairo_array_allocate (array, num_elements, &dest);
288
    status = _cairo_array_allocate (array, num_elements, &dest);
286
    if (unlikely (status))
289
    if (unlikely (status))
Line 287... Line 290...
287
	return status;
290
	return status;
Line 309... Line 312...
309
		       unsigned int	  num_elements,
312
		       unsigned int	  num_elements,
310
		       void		**elements)
313
		       void		**elements)
311
{
314
{
312
    cairo_status_t status;
315
    cairo_status_t status;
Line 313... Line -...
313
 
-
 
314
    assert (! array->is_snapshot);
-
 
315
 
316
 
316
    status = _cairo_array_grow_by (array, num_elements);
317
    status = _cairo_array_grow_by (array, num_elements);
317
    if (unlikely (status))
318
    if (unlikely (status))
Line 318... Line 319...
318
	return status;
319
	return status;
Line 319... Line 320...
319
 
320
 
Line 320... Line 321...
320
    assert (array->num_elements + num_elements <= array->size);
321
    assert (array->num_elements + num_elements <= array->size);
Line 321... Line 322...
321
 
322
 
322
    *elements = &(*array->elements)[array->num_elements * array->element_size];
323
    *elements = array->elements + array->num_elements * array->element_size;
Line 331... Line 332...
331
 * @array: a #cairo_array_t
332
 * @array: a #cairo_array_t
332
 * Returns: The number of elements stored in @array.
333
 * Returns: The number of elements stored in @array.
333
 *
334
 *
334
 * This space was left intentionally blank, but gtk-doc filled it.
335
 * This space was left intentionally blank, but gtk-doc filled it.
335
 **/
336
 **/
336
int
337
unsigned int
337
_cairo_array_num_elements (cairo_array_t *array)
338
_cairo_array_num_elements (const cairo_array_t *array)
338
{
339
{
339
    return array->num_elements;
340
    return array->num_elements;
340
}
341
}
Line 341... Line 342...
341
 
342
 
Line 345... Line 346...
345
 * Returns: The number of elements for which there is currently space
346
 * Returns: The number of elements for which there is currently space
346
 * allocated in @array.
347
 * allocated in @array.
347
 *
348
 *
348
 * This space was left intentionally blank, but gtk-doc filled it.
349
 * This space was left intentionally blank, but gtk-doc filled it.
349
 **/
350
 **/
350
int
351
unsigned int
351
_cairo_array_size (cairo_array_t *array)
352
_cairo_array_size (const cairo_array_t *array)
352
{
353
{
353
    return array->size;
354
    return array->size;
354
}
355
}
Line 355... Line 356...
355
 
356
 
Line 383... Line 384...
383
    num_slots = array->num_elements;
384
    num_slots = array->num_elements;
384
    if (num_slots) {
385
    if (num_slots) {
385
	cairo_user_data_slot_t *slots;
386
	cairo_user_data_slot_t *slots;
Line 386... Line 387...
386
 
387
 
387
	slots = _cairo_array_index (array, 0);
388
	slots = _cairo_array_index (array, 0);
-
 
389
	while (num_slots--) {
388
	do {
390
	    cairo_user_data_slot_t *s = &slots[num_slots];
389
	    if (slots->user_data != NULL && slots->destroy != NULL)
391
	    if (s->user_data != NULL && s->destroy != NULL)
390
		slots->destroy (slots->user_data);
392
		s->destroy (s->user_data);
391
	    slots++;
-
 
392
	} while (--num_slots);
393
	}
Line 393... Line 394...
393
    }
394
    }
394
 
395
 
Line 491... Line 492...
491
    return CAIRO_STATUS_SUCCESS;
492
    return CAIRO_STATUS_SUCCESS;
492
}
493
}
Line 493... Line 494...
493
 
494
 
494
cairo_status_t
495
cairo_status_t
495
_cairo_user_data_array_copy (cairo_user_data_array_t	*dst,
496
_cairo_user_data_array_copy (cairo_user_data_array_t	*dst,
496
			     cairo_user_data_array_t	*src)
497
			     const cairo_user_data_array_t	*src)
497
{
498
{
498
    /* discard any existing user-data */
499
    /* discard any existing user-data */
499
    if (dst->num_elements != 0) {
500
    if (dst->num_elements != 0) {
500
	_cairo_user_data_array_fini (dst);
501
	_cairo_user_data_array_fini (dst);
501
	_cairo_user_data_array_init (dst);
502
	_cairo_user_data_array_init (dst);
Line 502... Line -...
502
    }
-
 
503
 
-
 
504
    if (src->num_elements == 0)
-
 
505
	return CAIRO_STATUS_SUCCESS;
503
    }
506
 
504
 
507
    return _cairo_array_append_multiple (dst,
505
    return _cairo_array_append_multiple (dst,
508
					 _cairo_array_index (src, 0),
506
					 _cairo_array_index_const (src, 0),
Line 509... Line 507...
509
					 src->num_elements);
507
					 src->num_elements);
510
}
508
}