[cairo-commit] 14 commits - src/cairo.c src/cairo-cff-subset.c src/cairo-debug.c src/cairo-font-face.c src/cairo-ft-font.c src/cairo-gstate.c src/cairoint.h src/cairo-matrix.c src/cairo-output-stream.c src/cairo-scaled-font.c
Chris Wilson
ickle at kemper.freedesktop.org
Thu Oct 4 09:36:55 PDT 2007
src/cairo-cff-subset.c | 291 +++++++++++++++++++++++++++++++++-------------
src/cairo-debug.c | 4
src/cairo-font-face.c | 46 +++++--
src/cairo-ft-font.c | 8 -
src/cairo-gstate.c | 27 +++-
src/cairo-matrix.c | 10 +
src/cairo-output-stream.c | 12 +
src/cairo-scaled-font.c | 88 +++++++++----
src/cairo.c | 51 +++++++-
src/cairoint.h | 9 +
10 files changed, 409 insertions(+), 137 deletions(-)
New commits:
diff-tree 37fd0d8967df21695d6536af1d7aedbeef2d2449 (from add0959328117e2023db0ba2432ed29ecb93275e)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 17:12:26 2007 +0100
[cairo-cff-subset] Propagate errors and review error paths.
Ensure that errors get duly propagated back to the caller and all
locally allocated resources are freed along error paths.
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 7bc7cb9..d1826df 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -385,6 +385,7 @@ cff_index_append_copy (cairo_array_t *in
unsigned int length)
{
cff_index_element_t element;
+ cairo_status_t status;
element.length = length;
element.is_copy = TRUE;
@@ -394,7 +395,13 @@ cff_index_append_copy (cairo_array_t *in
memcpy (element.data, object, element.length);
- return _cairo_array_append (index, &element);
+ status = _cairo_array_append (index, &element);
+ if (status) {
+ free (element.data);
+ return status;
+ }
+
+ return CAIRO_STATUS_SUCCESS;
}
static void
@@ -420,10 +427,14 @@ _cairo_cff_dict_equal (const void *key_a
return op_a->operator == op_b->operator;
}
-static void
+static cairo_status_t
cff_dict_init (cairo_hash_table_t **dict)
{
*dict = _cairo_hash_table_create (_cairo_cff_dict_equal);
+ if (*dict == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ return CAIRO_STATUS_SUCCESS;
}
static void
@@ -697,6 +708,7 @@ cairo_cff_font_read_private_dict (cairo_
unsigned char *ptr,
int size)
{
+ cairo_int_status_t status;
unsigned char buf[10];
unsigned char *end_buf;
int offset;
@@ -704,16 +716,23 @@ cairo_cff_font_read_private_dict (cairo_
unsigned char *operand;
unsigned char *p;
- cff_dict_read (private_dict, ptr, size);
+ status = cff_dict_read (private_dict, ptr, size);
+ if (status)
+ return status;
+
operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
if (operand) {
decode_integer (operand, &offset);
p = ptr + offset;
- cff_index_read (local_sub_index, &p, font->data_end);
+ status = cff_index_read (local_sub_index, &p, font->data_end);
+ if (status)
+ return status;
/* Use maximum sized encoding to reserve space for later modification. */
end_buf = encode_integer_max (buf, 0);
- cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
+ status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
+ if (status)
+ return status;
}
return CAIRO_STATUS_SUCCESS;
@@ -791,11 +810,10 @@ cairo_cff_font_read_cid_fontdict (cairo_
}
for (i = 0; i < font->num_fontdicts; i++) {
- cff_dict_init (&font->fd_dict[i]);
- if (font->fd_dict[i] == NULL) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ status = cff_dict_init (&font->fd_dict[i]);
+ if (status)
goto fail;
- }
+
element = _cairo_array_index (&index, i);
status = cff_dict_read (font->fd_dict[i], element->data, element->length);
if (status)
@@ -808,11 +826,10 @@ cairo_cff_font_read_cid_fontdict (cairo_
}
operand = decode_integer (operand, &size);
decode_integer (operand, &offset);
- cff_dict_init (&font->fd_private_dict[i]);
- if (font->fd_private_dict[i] == NULL) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ status = cff_dict_init (&font->fd_private_dict[i]);
+ if (status)
goto fail;
- }
+
cff_index_init (&font->fd_local_sub_index[i]);
status = cairo_cff_font_read_private_dict (font,
font->fd_private_dict[i],
@@ -877,28 +894,49 @@ cairo_cff_font_read_top_dict (cairo_cff_
if (font->is_cid) {
operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
decode_integer (operand, &offset);
- cairo_cff_font_read_fdselect (font, font->data + offset);
+ status = cairo_cff_font_read_fdselect (font, font->data + offset);
+ if (status)
+ goto fail;
operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
decode_integer (operand, &offset);
- cairo_cff_font_read_cid_fontdict (font, font->data + offset);
+ status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
+ if (status)
+ goto fail;
} else {
operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
operand = decode_integer (operand, &size);
decode_integer (operand, &offset);
- cairo_cff_font_read_private_dict (font,
- font->private_dict,
- &font->local_sub_index,
- font->data + offset,
- size);
+ status = cairo_cff_font_read_private_dict (font,
+ font->private_dict,
+ &font->local_sub_index,
+ font->data + offset,
+ size);
+ if (status)
+ goto fail;
}
/* Use maximum sized encoding to reserve space for later modification. */
end_buf = encode_integer_max (buf, 0);
- cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
+ status = cff_dict_set_operands (font->top_dict,
+ CHARSTRINGS_OP, buf, end_buf - buf);
+ if (status)
+ goto fail;
+
+ status = cff_dict_set_operands (font->top_dict,
+ FDSELECT_OP, buf, end_buf - buf);
+ if (status)
+ goto fail;
+
+ status = cff_dict_set_operands (font->top_dict,
+ FDARRAY_OP, buf, end_buf - buf);
+ if (status)
+ goto fail;
+
+ status = cff_dict_set_operands (font->top_dict,
+ CHARSET_OP, buf, end_buf - buf);
+ if (status)
+ goto fail;
cff_dict_remove (font->top_dict, ENCODING_OP);
cff_dict_remove (font->top_dict, PRIVATE_OP);
@@ -952,9 +990,10 @@ cairo_cff_font_read_font (cairo_cff_font
return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
{
+ cairo_status_t status;
unsigned char buf[30];
unsigned char *p;
int sid1, sid2;
@@ -974,10 +1013,16 @@ cairo_cff_font_set_ros_strings (cairo_cf
p = encode_integer (buf, sid1);
p = encode_integer (p, sid2);
p = encode_integer (p, 0);
- cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
+ status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
+ if (status)
+ return status;
p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
- cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
+ status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
+ if (status)
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@@ -1007,7 +1052,9 @@ cairo_cff_font_subset_dict_string(cairo_
return status;
p = encode_integer (buf, sid);
- cff_dict_set_operands (dict, operator, buf, p - buf);
+ status = cff_dict_set_operands (dict, operator, buf, p - buf);
+ if (status)
+ return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1107,13 +1154,19 @@ cairo_cff_font_create_cid_fontdict (cair
{
unsigned char buf[100];
unsigned char *end_buf;
+ cairo_status_t status;
font->num_fontdicts = 1;
font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
if (font->fd_dict == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- cff_dict_init (&font->fd_dict[0]);
+ if (cff_dict_init (&font->fd_dict[0])) {
+ free (font->fd_dict);
+ font->fd_dict = NULL;
+ font->num_fontdicts = 0;
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
font->fd_subset_map = malloc (sizeof (int));
if (font->fd_subset_map == NULL)
@@ -1130,7 +1183,9 @@ cairo_cff_font_create_cid_fontdict (cair
* space for any value later */
end_buf = encode_integer_max (buf, 0);
end_buf = encode_integer_max (end_buf, 0);
- cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
+ status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
+ if (status)
+ return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1144,6 +1199,7 @@ cairo_cff_font_subset_strings (cairo_cff
status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
if (status)
return status;
+
if (font->is_cid) {
for (i = 0; i < font->num_subset_fontdicts; i++) {
status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
@@ -1166,16 +1222,20 @@ cairo_cff_font_subset_font (cairo_cff_fo
{
cairo_status_t status;
- cairo_cff_font_set_ros_strings (font);
+ status = cairo_cff_font_set_ros_strings (font);
+ if (status)
+ return status;
status = cairo_cff_font_subset_charstrings (font);
if (status)
return status;
if (font->is_cid)
- cairo_cff_font_subset_fontdict (font);
+ status = cairo_cff_font_subset_fontdict (font);
else
- cairo_cff_font_create_cid_fontdict (font);
+ status = cairo_cff_font_create_cid_fontdict (font);
+ if (status)
+ return status;
status = cairo_cff_font_subset_strings (font);
if (status)
@@ -1218,21 +1278,25 @@ cairo_cff_font_write_header (cairo_cff_f
static cairo_status_t
cairo_cff_font_write_name (cairo_cff_font_t *font)
{
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_array_t index;
- cairo_status_t status;
cff_index_init (&index);
+
status = cff_index_append_copy (&index,
(unsigned char *) font->subset_font_name,
strlen(font->subset_font_name));
if (status)
- return status;
+ goto FAIL;
+
status = cff_index_write (&index, &font->output);
if (status)
- return status;
+ goto FAIL;
+
+FAIL:
cff_index_fini (&index);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
static cairo_status_t
@@ -1435,6 +1499,7 @@ cairo_cff_font_write_private_dict (cairo
status = cff_dict_write (private_dict, &font->output);
if (status)
return status;
+
size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
/* private entry has two operands - size and offset */
buf_end = encode_integer_max (buf, size);
@@ -1483,7 +1548,7 @@ static cairo_status_t
cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
{
unsigned int i;
- cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_int_status_t status;
if (font->is_cid) {
for (i = 0; i < font->num_subset_fontdicts; i++) {
@@ -1510,13 +1575,18 @@ cairo_cff_font_write_cid_private_dict_an
0,
font->fd_dict[0],
font->private_dict);
+ if (status)
+ return status;
+
status = cairo_cff_font_write_local_sub (font,
0,
font->private_dict,
&font->local_sub_index);
+ if (status)
+ return status;
}
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
typedef cairo_status_t
@@ -1701,7 +1771,7 @@ _cairo_cff_font_create (cairo_scaled_fon
font->subset_font_name = strdup (subset_name);
if (font->subset_font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail3;
+ goto fail2;
}
font->x_min = (int16_t) be16_to_cpu (head.x_min);
font->y_min = (int16_t) be16_to_cpu (head.y_min);
@@ -1737,7 +1807,7 @@ _cairo_cff_font_create (cairo_scaled_fon
font->font_name = malloc (30);
if (font->font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail4;
+ goto fail3;
}
snprintf(font->font_name, 30, "CairoFont-%u-%u",
scaled_font_subset->font_id,
@@ -1754,25 +1824,35 @@ _cairo_cff_font_create (cairo_scaled_fon
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
if (font->widths == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail5;
+ goto fail4;
}
- cairo_cff_font_create_set_widths (font);
+
+ status = cairo_cff_font_create_set_widths (font);
+ if (status)
+ goto fail5;
font->data_length = data_length;
font->data = malloc (data_length);
if (font->data == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail6;
+ goto fail5;
}
status = font->backend->load_truetype_table ( font->scaled_font_subset->scaled_font,
TT_TAG_CFF, 0, font->data,
&font->data_length);
if (status)
- goto fail7;
+ goto fail6;
+
font->data_end = font->data + font->data_length;
- cff_dict_init (&font->top_dict);
- cff_dict_init (&font->private_dict);
+ status = cff_dict_init (&font->top_dict);
+ if (status)
+ goto fail6;
+
+ status = cff_dict_init (&font->private_dict);
+ if (status)
+ goto fail7;
+
cff_index_init (&font->strings_index);
cff_index_init (&font->charstrings_index);
cff_index_init (&font->global_sub_index);
@@ -1793,16 +1873,17 @@ _cairo_cff_font_create (cairo_scaled_fon
return CAIRO_STATUS_SUCCESS;
fail7:
- free (font->data);
+ _cairo_hash_table_destroy (font->top_dict);
fail6:
- free (font->widths);
+ free (font->data);
fail5:
- free (font->font_name);
+ free (font->widths);
fail4:
- free (font->subset_font_name);
+ free (font->font_name);
fail3:
- _cairo_array_fini (&font->output);
+ free (font->subset_font_name);
fail2:
+ _cairo_array_fini (&font->output);
free (font);
fail1:
free (name);
@@ -1886,12 +1967,16 @@ _cairo_cff_subset_init (cairo_cff_subset
goto fail1;
cff_subset->base_font = strdup (font->font_name);
- if (cff_subset->base_font == NULL)
+ if (cff_subset->base_font == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
+ }
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
- if (cff_subset->widths == NULL)
+ if (cff_subset->widths == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
+ }
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
cff_subset->widths[i] = font->widths[i];
@@ -1903,8 +1988,10 @@ _cairo_cff_subset_init (cairo_cff_subset
cff_subset->descent = font->descent;
cff_subset->data = malloc (length);
- if (cff_subset->data == NULL)
+ if (cff_subset->data == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
+ }
memcpy (cff_subset->data, data, length);
cff_subset->data_length = length;
@@ -1954,13 +2041,13 @@ _cairo_cff_font_fallback_create (cairo_s
font->subset_font_name = strdup (subset_name);
if (font->subset_font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail2;
+ goto fail1;
}
font->font_name = strdup (subset_name);
if (font->subset_font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail3;
+ goto fail2;
}
font->x_min = 0;
@@ -1973,15 +2060,21 @@ _cairo_cff_font_fallback_create (cairo_s
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
if (font->widths == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail4;
+ goto fail3;
}
font->data_length = 0;
font->data = NULL;
- font->data_end = 0;
+ font->data_end = NULL;
+
+ status = cff_dict_init (&font->top_dict);
+ if (status)
+ goto fail4;
+
+ status = cff_dict_init (&font->private_dict);
+ if (status)
+ goto fail5;
- cff_dict_init (&font->top_dict);
- cff_dict_init (&font->private_dict);
cff_index_init (&font->strings_index);
cff_index_init (&font->charstrings_index);
cff_index_init (&font->global_sub_index);
@@ -2000,13 +2093,16 @@ _cairo_cff_font_fallback_create (cairo_s
return CAIRO_STATUS_SUCCESS;
+fail5:
+ _cairo_hash_table_destroy (font->top_dict);
fail4:
- free (font->font_name);
+ free (font->widths);
fail3:
- free (font->subset_font_name);
+ free (font->font_name);
fail2:
- _cairo_array_fini (&font->output);
+ free (font->subset_font_name);
fail1:
+ _cairo_array_fini (&font->output);
free (font);
return _cairo_error (status);
}
@@ -2037,16 +2133,40 @@ cairo_cff_font_fallback_generate (cairo_
end_buf = encode_integer (end_buf, type2_subset->y_min);
end_buf = encode_integer (end_buf, type2_subset->x_max);
end_buf = encode_integer (end_buf, type2_subset->y_max);
- cff_dict_set_operands (font->top_dict, FONTBBOX_OP, buf, end_buf - buf);
+ status = cff_dict_set_operands (font->top_dict,
+ FONTBBOX_OP, buf, end_buf - buf);
+ if (status)
+ return status;
+
end_buf = encode_integer_max (buf, 0);
- cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
- cairo_cff_font_set_ros_strings (font);
+ status = cff_dict_set_operands (font->top_dict,
+ CHARSTRINGS_OP, buf, end_buf - buf);
+ if (status)
+ return status;
+
+ status = cff_dict_set_operands (font->top_dict,
+ FDSELECT_OP, buf, end_buf - buf);
+ if (status)
+ return status;
+
+ status = cff_dict_set_operands (font->top_dict,
+ FDARRAY_OP, buf, end_buf - buf);
+ if (status)
+ return status;
+
+ status = cff_dict_set_operands (font->top_dict,
+ CHARSET_OP, buf, end_buf - buf);
+ if (status)
+ return status;
+
+ status = cairo_cff_font_set_ros_strings (font);
+ if (status)
+ return status;
/* Create CID FD dictionary */
- cairo_cff_font_create_cid_fontdict (font);
+ status = cairo_cff_font_create_cid_fontdict (font);
+ if (status)
+ return status;
/* Create charstrings */
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
@@ -2092,15 +2212,19 @@ _cairo_cff_fallback_init (cairo_cff_subs
status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
if (status)
- goto fail1;
+ goto fail2;
cff_subset->base_font = strdup (font->font_name);
- if (cff_subset->base_font == NULL)
- goto fail1;
+ if (cff_subset->base_font == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto fail2;
+ }
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
- if (cff_subset->widths == NULL)
- goto fail2;
+ if (cff_subset->widths == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto fail3;
+ }
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
cff_subset->widths[i] = type2_subset.widths[i];
@@ -2111,24 +2235,27 @@ _cairo_cff_fallback_init (cairo_cff_subs
cff_subset->ascent = type2_subset.y_max;
cff_subset->descent = type2_subset.y_min;
- _cairo_type2_charstrings_fini (&type2_subset);
-
cff_subset->data = malloc (length);
- if (cff_subset->data == NULL)
- goto fail3;
+ if (cff_subset->data == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto fail4;
+ }
memcpy (cff_subset->data, data, length);
cff_subset->data_length = length;
cff_subset->data_length = length;
+ _cairo_type2_charstrings_fini (&type2_subset);
cairo_cff_font_destroy (font);
return CAIRO_STATUS_SUCCESS;
- fail3:
+ fail4:
free (cff_subset->widths);
- fail2:
+ fail3:
free (cff_subset->base_font);
+ fail2:
+ _cairo_type2_charstrings_fini (&type2_subset);
fail1:
cairo_cff_font_destroy (font);
diff-tree add0959328117e2023db0ba2432ed29ecb93275e (from a4f20610afd18d58a964dbe84cc90c5723b2996d)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 17:00:26 2007 +0100
[cairo-debug] Finalize mutexes along with other static data.
Initialize (so repeated calls of cairo_debug_reset_static_data() is
safe) and finalize the mutexes with the reset of the static data.
diff --git a/src/cairo-debug.c b/src/cairo-debug.c
index 6a50353..cdd3ce9 100644
--- a/src/cairo-debug.c
+++ b/src/cairo-debug.c
@@ -59,6 +59,8 @@
void
cairo_debug_reset_static_data (void)
{
+ CAIRO_MUTEX_INITIALIZE ();
+
_cairo_font_reset_static_data ();
#if CAIRO_HAS_FT_FONT
@@ -66,4 +68,6 @@ cairo_debug_reset_static_data (void)
#endif
_cairo_pattern_reset_static_data ();
+
+ CAIRO_MUTEX_FINALIZE ();
}
diff-tree a4f20610afd18d58a964dbe84cc90c5723b2996d (from 80c06f4539962231df771b38e64834a238f410dd)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 16:37:44 2007 +0100
[cairo] Protect the getters when operating on the nil object.
Put a guard that checks the context's status at the start of each
getter that prevents the function from trying to dereference NULL state.
Use the status, as opposed to the invalid reference count, for
consistency with the existing guards on some of the getters.
diff --git a/src/cairo.c b/src/cairo.c
index ef628e7..73c2dc4 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -1073,6 +1073,9 @@ cairo_get_dash_count (cairo_t *cr)
{
int num_dashes;
+ if (cr->status)
+ return 0;
+
_cairo_gstate_get_dash (cr->gstate, NULL, &num_dashes, NULL);
return num_dashes;
@@ -1095,6 +1098,9 @@ cairo_get_dash (cairo_t *cr,
double *dashes,
double *offset)
{
+ if (cr->status)
+ return;
+
_cairo_gstate_get_dash (cr->gstate, dashes, NULL, offset);
}
@@ -2631,6 +2637,11 @@ cairo_set_font_matrix (cairo_t *cr,
void
cairo_get_font_matrix (cairo_t *cr, cairo_matrix_t *matrix)
{
+ if (cr->status) {
+ cairo_matrix_init_identity (matrix);
+ return;
+ }
+
_cairo_gstate_get_font_matrix (cr->gstate, matrix);
}
@@ -2682,6 +2693,11 @@ cairo_get_font_options (cairo_t
if (cairo_font_options_status (options))
return;
+ if (cr->status) {
+ _cairo_font_options_init_default (options);
+ return;
+ }
+
_cairo_gstate_get_font_options (cr->gstate, options);
}
@@ -3077,6 +3093,9 @@ cairo_glyph_path (cairo_t *cr, const cai
cairo_operator_t
cairo_get_operator (cairo_t *cr)
{
+ if (cr->status)
+ return (cairo_operator_t) 0;
+
return _cairo_gstate_get_operator (cr->gstate);
}
@@ -3091,6 +3110,9 @@ cairo_get_operator (cairo_t *cr)
double
cairo_get_tolerance (cairo_t *cr)
{
+ if (cr->status)
+ return 0.;
+
return _cairo_gstate_get_tolerance (cr->gstate);
}
slim_hidden_def (cairo_get_tolerance);
@@ -3106,6 +3128,9 @@ slim_hidden_def (cairo_get_tolerance);
cairo_antialias_t
cairo_get_antialias (cairo_t *cr)
{
+ if (cr->status)
+ return (cairo_antialias_t) 0;
+
return _cairo_gstate_get_antialias (cr->gstate);
}
@@ -3141,11 +3166,13 @@ cairo_get_antialias (cairo_t *cr)
void
cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret)
{
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_NO_CURRENT_POINT;
cairo_fixed_t x_fixed, y_fixed;
double x, y;
- status = _cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed);
+ if (cr->status == CAIRO_STATUS_SUCCESS)
+ status = _cairo_path_fixed_get_current_point (cr->path,
+ &x_fixed, &y_fixed);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0.0;
y = 0.0;
@@ -3173,6 +3200,9 @@ slim_hidden_def(cairo_get_current_point)
cairo_fill_rule_t
cairo_get_fill_rule (cairo_t *cr)
{
+ if (cr->status)
+ return (cairo_fill_rule_t) 0;
+
return _cairo_gstate_get_fill_rule (cr->gstate);
}
@@ -3190,6 +3220,9 @@ cairo_get_fill_rule (cairo_t *cr)
double
cairo_get_line_width (cairo_t *cr)
{
+ if (cr->status)
+ return 0.;
+
return _cairo_gstate_get_line_width (cr->gstate);
}
@@ -3204,6 +3237,9 @@ cairo_get_line_width (cairo_t *cr)
cairo_line_cap_t
cairo_get_line_cap (cairo_t *cr)
{
+ if (cr->status)
+ return (cairo_line_cap_t) 0;
+
return _cairo_gstate_get_line_cap (cr->gstate);
}
@@ -3218,6 +3254,9 @@ cairo_get_line_cap (cairo_t *cr)
cairo_line_join_t
cairo_get_line_join (cairo_t *cr)
{
+ if (cr->status)
+ return (cairo_line_join_t) 0;
+
return _cairo_gstate_get_line_join (cr->gstate);
}
@@ -3232,6 +3271,9 @@ cairo_get_line_join (cairo_t *cr)
double
cairo_get_miter_limit (cairo_t *cr)
{
+ if (cr->status)
+ return 0.;
+
return _cairo_gstate_get_miter_limit (cr->gstate);
}
@@ -3245,6 +3287,11 @@ cairo_get_miter_limit (cairo_t *cr)
void
cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix)
{
+ if (cr->status) {
+ cairo_matrix_init_identity (matrix);
+ return;
+ }
+
_cairo_gstate_get_matrix (cr->gstate, matrix);
}
slim_hidden_def (cairo_get_matrix);
diff-tree 80c06f4539962231df771b38e64834a238f410dd (from 6e93941a7605a3958269de195dc16f255dda7bfd)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 16:16:41 2007 +0100
[cairo-scaled-font] Don't hold onto to a dropped font.
Mark fonts that have been removed from the cache due to an error on a
shared object and do not put them into the holdovers array.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index e905917..9cbe7bb 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -177,8 +177,9 @@ _cairo_scaled_glyph_destroy (void *abstr
free (scaled_glyph);
}
+#define ZOMBIE 0
const cairo_scaled_font_t _cairo_scaled_font_nil = {
- { 0 }, /* hash_entry */
+ { ZOMBIE }, /* hash_entry */
CAIRO_STATUS_NO_MEMORY, /* status */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
{ 0, 0, 0, NULL }, /* user_data */
@@ -423,6 +424,7 @@ _cairo_scaled_font_init_key (cairo_scale
hash ^= cairo_font_options_hash (&scaled_font->options);
+ assert (hash != ZOMBIE);
scaled_font->hash_entry.hash = hash;
}
@@ -650,6 +652,7 @@ cairo_scaled_font_create (cairo_font_fac
/* the font has been put into an error status - abandon the cache */
_cairo_hash_table_remove (font_map->hash_table, &key.hash_entry);
+ scaled_font->hash_entry.hash = ZOMBIE;
}
/* Otherwise create it and insert it into the hash table. */
@@ -730,7 +733,8 @@ cairo_scaled_font_destroy (cairo_scaled_
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count));
- if (_cairo_reference_count_dec_and_test (&scaled_font->ref_count)) {
+ if (_cairo_reference_count_dec_and_test (&scaled_font->ref_count)
+ && scaled_font->hash_entry.hash != ZOMBIE) {
/* Rather than immediately destroying this object, we put it into
* the font_map->holdovers array in case it will get used again
* soon (and is why we must hold the lock over the atomic op on
diff-tree 6e93941a7605a3958269de195dc16f255dda7bfd (from 261971a3fb9c10c267cced53a440161f1acb4b5d)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 16:04:49 2007 +0100
[cairo-scaled-font] Acquire mutex around _cairo_scaled_font_glyph_path().
All calls that manipulate the scaled_font->cache must hold its mutex.
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index e2c7d13..3e92c54 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1631,9 +1631,11 @@ _cairo_gstate_glyph_path (cairo_gstate_t
_cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
transformed_glyphs);
+ CAIRO_MUTEX_LOCK (gstate->scaled_font->mutex);
status = _cairo_scaled_font_glyph_path (gstate->scaled_font,
transformed_glyphs, num_glyphs,
path);
+ CAIRO_MUTEX_UNLOCK (gstate->scaled_font->mutex);
if (transformed_glyphs != stack_transformed_glyphs)
free (transformed_glyphs);
diff-tree 261971a3fb9c10c267cced53a440161f1acb4b5d (from 4e44d54f3e99b65f5e80485b22d31890ea3d6561)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 16:03:12 2007 +0100
[cairo-gstate] Fix resource leaks on error paths.
Ensure that all locally allocated (or referenced) resources are freed
if we later encounter an error.
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 2867243..e2c7d13 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -93,8 +93,13 @@ _cairo_gstate_init (cairo_gstate_t *gst
gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
CAIRO_CONTENT_COLOR);
- if (gstate->source->status)
+ if (gstate->source->status) {
+ cairo_surface_destroy (gstate->target);
+ gstate->target = NULL;
+ cairo_surface_destroy (gstate->original_target);
+ gstate->original_target = NULL;
return gstate->source->status;
+ }
return target ? target->status : CAIRO_STATUS_NULL_POINTER;
}
@@ -131,8 +136,12 @@ _cairo_gstate_init_copy (cairo_gstate_t
_cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
status = _cairo_clip_init_copy (&gstate->clip, &other->clip);
- if (status)
+ if (status) {
+ _cairo_stroke_style_fini (&gstate->stroke_style);
+ cairo_font_face_destroy (gstate->font_face);
+ cairo_scaled_font_destroy (gstate->scaled_font);
return status;
+ }
gstate->target = cairo_surface_reference (other->target);
/* parent_target is always set to NULL; it's only ever set by redirect_target */
@@ -994,7 +1003,7 @@ _cairo_gstate_in_stroke (cairo_gstate_t
double y,
cairo_bool_t *inside_ret)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_status_t status;
cairo_traps_t traps;
if (gstate->stroke_style.line_width <= 0.0) {
@@ -1060,7 +1069,7 @@ _cairo_gstate_in_fill (cairo_gstate_t
double y,
cairo_bool_t *inside_ret)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_status_t status;
cairo_traps_t traps;
_cairo_gstate_user_to_backend (gstate, &x, &y);
@@ -1267,11 +1276,9 @@ _cairo_gstate_select_font_face (cairo_gs
return font_face->status;
status = _cairo_gstate_set_font_face (gstate, font_face);
- if (status)
- return status;
cairo_font_face_destroy (font_face);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
cairo_status_t
@@ -1558,7 +1565,6 @@ _cairo_gstate_show_glyphs (cairo_gstate_
cairo_glyph_t *transformed_glyphs;
cairo_glyph_t stack_transformed_glyphs[STACK_GLYPHS_LEN];
-
if (gstate->source->status)
return gstate->source->status;
diff-tree 4e44d54f3e99b65f5e80485b22d31890ea3d6561 (from 528da4e5e131fe385a60431eb6656a542b27c70f)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 15:58:21 2007 +0100
[cairo-matrix] Check whether a matrix is invertible before use.
Provide an early check as to whether the font matrix is invertible.
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index b1fc6b3..2867243 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1289,6 +1289,9 @@ cairo_status_t
_cairo_gstate_set_font_matrix (cairo_gstate_t *gstate,
const cairo_matrix_t *matrix)
{
+ if (! _cairo_matrix_is_invertible (matrix))
+ return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+
_cairo_gstate_unset_scaled_font (gstate);
gstate->font_matrix = *matrix;
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index cf31c5d..00c2d48 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -486,6 +486,16 @@ cairo_matrix_invert (cairo_matrix_t *mat
}
slim_hidden_def(cairo_matrix_invert);
+cairo_bool_t
+_cairo_matrix_is_invertible (const cairo_matrix_t *matrix)
+{
+ double det;
+
+ _cairo_matrix_compute_determinant (matrix, &det);
+
+ return det != 0. && det * det > 0.;
+}
+
void
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix,
double *det)
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 2da9912..e905917 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -603,6 +603,9 @@ cairo_scaled_font_create (cairo_font_fac
if (cairo_font_options_status ((cairo_font_options_t *) options))
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
+ if (! _cairo_matrix_is_invertible (font_matrix))
+ return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
+
font_map = _cairo_scaled_font_map_lock ();
if (font_map == NULL)
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
diff --git a/src/cairoint.h b/src/cairoint.h
index 80915d7..c5cdf1a 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2104,6 +2104,9 @@ _cairo_matrix_transform_bounding_box (co
double *x2, double *y2,
cairo_bool_t *is_tight);
+cairo_private cairo_bool_t
+_cairo_matrix_is_invertible (const cairo_matrix_t *matrix);
+
cairo_private void
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det);
diff-tree 528da4e5e131fe385a60431eb6656a542b27c70f (from 4b81eeb20ebe070692ef8099c00de3829da8bf69)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 15:50:40 2007 +0100
[cairo-scaled-font] Freeze the font cache whilst iterating over glyphs.
Prevent glyph cache removal whilst iterating over a glyph string.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index aec958a..2da9912 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -934,6 +934,7 @@ cairo_scaled_font_glyph_extents (cairo_s
return;
CAIRO_MUTEX_LOCK (scaled_font->mutex);
+ _cairo_scaled_font_freeze_cache (scaled_font);
for (i = 0; i < num_glyphs; i++) {
double left, top, right, bottom;
@@ -1000,6 +1001,7 @@ cairo_scaled_font_glyph_extents (cairo_s
}
UNLOCK:
+ _cairo_scaled_font_thaw_cache (scaled_font);
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
}
slim_hidden_def (cairo_scaled_font_glyph_extents);
@@ -1028,6 +1030,7 @@ _cairo_scaled_font_text_to_glyphs (cairo
}
CAIRO_MUTEX_LOCK (scaled_font->mutex);
+ _cairo_scaled_font_freeze_cache (scaled_font);
if (scaled_font->backend->text_to_glyphs) {
status = scaled_font->backend->text_to_glyphs (scaled_font,
@@ -1070,6 +1073,7 @@ _cairo_scaled_font_text_to_glyphs (cairo
}
DONE:
+ _cairo_scaled_font_thaw_cache (scaled_font);
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
if (ucs4)
@@ -1430,6 +1434,7 @@ _cairo_scaled_font_glyph_path (cairo_sca
return status;
closure.path = path;
+ _cairo_scaled_font_freeze_cache (scaled_font);
for (i = 0; i < num_glyphs; i++) {
cairo_scaled_glyph_t *scaled_glyph;
@@ -1482,6 +1487,7 @@ _cairo_scaled_font_glyph_path (cairo_sca
goto BAIL;
}
BAIL:
+ _cairo_scaled_font_thaw_cache (scaled_font);
return _cairo_scaled_font_set_error (scaled_font, status);
}
diff-tree 4b81eeb20ebe070692ef8099c00de3829da8bf69 (from d0b1308cd73a6b3602e5414abf03a3bdf8d2d001)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 15:46:13 2007 +0100
[cairo-scaled-font] Destroy the mask on the error path.
Do not leak the mask if we encounter an error whilst tracing.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index d506e93..aec958a 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1381,12 +1381,15 @@ _trace_mask_to_path (cairo_image_surface
double xoff, yoff;
if (mask->format == CAIRO_FORMAT_A1)
- a1_mask = mask;
+ a1_mask = (cairo_image_surface_t *) cairo_surface_reference (&mask->base);
else
a1_mask = _cairo_image_surface_clone (mask, CAIRO_FORMAT_A1);
- if (cairo_surface_status (&a1_mask->base))
- return cairo_surface_status (&a1_mask->base);
+ status = cairo_surface_status (&a1_mask->base);
+ if (status) {
+ cairo_surface_destroy (&a1_mask->base);
+ return status;
+ }
cairo_surface_get_device_offset (&mask->base, &xoff, &yoff);
@@ -1399,16 +1402,16 @@ _trace_mask_to_path (cairo_image_surface
status = _add_unit_rectangle_to_path (path,
x - xoff, y - yoff);
if (status)
- return status;
+ goto BAIL;
}
}
}
}
- if (a1_mask != mask)
- cairo_surface_destroy (&a1_mask->base);
+BAIL:
+ cairo_surface_destroy (&a1_mask->base);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
cairo_status_t
diff-tree d0b1308cd73a6b3602e5414abf03a3bdf8d2d001 (from 4c32e6bfde5d613e0eeef407b9b50c557b1878e3)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 15:43:09 2007 +0100
[cairo-scaled-font] Store fatal errors on the cairo_scaled_font_t.
Ensure that all fatal errors raised whilst using the font are stored on
the font.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 434e09c..d506e93 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -221,6 +221,9 @@ cairo_status_t
_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
cairo_status_t status)
{
+ if (status == CAIRO_STATUS_SUCCESS)
+ return status;
+
/* Don't overwrite an existing error. This preserves the first
* error, which is the most significant. */
_cairo_status_set_error (&scaled_font->status, status);
@@ -1011,9 +1014,13 @@ _cairo_scaled_font_text_to_glyphs (cairo
{
int i;
uint32_t *ucs4 = NULL;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_status_t status;
cairo_scaled_glyph_t *scaled_glyph;
+ status = scaled_font->status;
+ if (status)
+ return status;
+
if (utf8[0] == '\0') {
*num_glyphs = 0;
*glyphs = NULL;
@@ -1165,7 +1172,7 @@ _cairo_scaled_font_show_glyphs (cairo_sc
width, height,
glyphs, num_glyphs);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return status;
+ return _cairo_scaled_font_set_error (scaled_font, status);
}
/* Font display routine either does not exist or failed. */
@@ -1255,7 +1262,7 @@ CLEANUP_MASK:
if (mask != NULL)
cairo_surface_destroy (mask);
- return status;
+ return _cairo_scaled_font_set_error (scaled_font, status);
}
typedef struct _cairo_scaled_glyph_path_closure {
@@ -1415,8 +1422,9 @@ _cairo_scaled_font_glyph_path (cairo_sca
cairo_scaled_glyph_path_closure_t closure;
cairo_path_fixed_t *glyph_path;
- if (scaled_font->status)
- return scaled_font->status;
+ status = scaled_font->status;
+ if (status)
+ return status;
closure.path = path;
for (i = 0; i < num_glyphs; i++) {
@@ -1429,7 +1437,7 @@ _cairo_scaled_font_glyph_path (cairo_sca
if (status == CAIRO_STATUS_SUCCESS)
glyph_path = scaled_glyph->path;
else if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return status;
+ goto BAIL;
/* If the font is incapable of providing a path, then we'll
* have to trace our own from a surface. */
@@ -1439,16 +1447,18 @@ _cairo_scaled_font_glyph_path (cairo_sca
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
if (status)
- return status;
+ goto BAIL;
glyph_path = _cairo_path_fixed_create ();
- if (glyph_path == NULL)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ if (glyph_path == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto BAIL;
+ }
status = _trace_mask_to_path (scaled_glyph->surface, glyph_path);
if (status) {
_cairo_path_fixed_destroy (glyph_path);
- return status;
+ goto BAIL;
}
}
@@ -1466,10 +1476,11 @@ _cairo_scaled_font_glyph_path (cairo_sca
_cairo_path_fixed_destroy (glyph_path);
if (status)
- return status;
+ goto BAIL;
}
+ BAIL:
- return CAIRO_STATUS_SUCCESS;
+ return _cairo_scaled_font_set_error (scaled_font, status);
}
/**
diff-tree 4c32e6bfde5d613e0eeef407b9b50c557b1878e3 (from 06ae5f1ba3bb679c145d2f7e9ed8c244abf7ff17)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 15:31:25 2007 +0100
[cairo-scaled-font] Return the error status from _cairo_scaled_font_set_error()
Similar to the other _cairo_*_set_error() return the error status.
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index d6a6771..e141ba7 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2539,7 +2539,7 @@ cairo_ft_scaled_font_lock_face (cairo_sc
face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
if (face == NULL) {
- _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
+ status = _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
return NULL;
}
@@ -2547,7 +2547,7 @@ cairo_ft_scaled_font_lock_face (cairo_sc
&scaled_font->base.scale);
if (status) {
_cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
- _cairo_scaled_font_set_error (&scaled_font->base, status);
+ status = _cairo_scaled_font_set_error (&scaled_font->base, status);
return NULL;
}
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ff844a5..434e09c 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -214,8 +214,10 @@ const cairo_scaled_font_t _cairo_scaled_
* The purpose of this function is to allow the user to set a
* breakpoint in _cairo_error() to generate a stack trace for when the
* user causes cairo to detect an error.
+ *
+ * Return value: the error status.
**/
-void
+cairo_status_t
_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
cairo_status_t status)
{
@@ -223,7 +225,7 @@ _cairo_scaled_font_set_error (cairo_scal
* error, which is the most significant. */
_cairo_status_set_error (&scaled_font->status, status);
- _cairo_error_throw (status);
+ return _cairo_error (status);
}
/**
@@ -888,7 +890,7 @@ cairo_scaled_font_text_extents (cairo_sc
status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs);
if (status) {
- _cairo_scaled_font_set_error (scaled_font, status);
+ status = _cairo_scaled_font_set_error (scaled_font, status);
return;
}
cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents);
@@ -938,7 +940,7 @@ cairo_scaled_font_glyph_extents (cairo_s
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
if (status) {
- _cairo_scaled_font_set_error (scaled_font, status);
+ status = _cairo_scaled_font_set_error (scaled_font, status);
goto UNLOCK;
}
@@ -1096,10 +1098,8 @@ _cairo_scaled_font_glyph_device_extents
glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
- if (status) {
- _cairo_scaled_font_set_error (scaled_font, status);
- return status;
- }
+ if (status)
+ return _cairo_scaled_font_set_error (scaled_font, status);
/* glyph images are snapped to pixel locations */
x = _cairo_lround (glyphs[i].x);
@@ -1677,7 +1677,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled
if (status) {
/* It's not an error for the backend to not support the info we want. */
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- _cairo_scaled_font_set_error (scaled_font, status);
+ status = _cairo_scaled_font_set_error (scaled_font, status);
*scaled_glyph_ret = NULL;
} else {
*scaled_glyph_ret = scaled_glyph;
diff --git a/src/cairoint.h b/src/cairoint.h
index 9cd42f2..80915d7 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1360,7 +1360,7 @@ _cairo_scaled_font_thaw_cache (cairo_sca
cairo_private void
_cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font);
-cairo_private void
+cairo_private cairo_status_t
_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
cairo_status_t status);
diff-tree 06ae5f1ba3bb679c145d2f7e9ed8c244abf7ff17 (from 4cffdf2681ba254587bd774ea49718e71535b067)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 15:26:09 2007 +0100
[cairo-font-face] Set the error on the font.
Similar to the other shared objects, store fatal errors on the shared
font_face. And do not return a cached reference to an object in an
error state.
diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c
index 0285b52..f729476 100644
--- a/src/cairo-font-face.c
+++ b/src/cairo-font-face.c
@@ -55,6 +55,18 @@ const cairo_font_face_t _cairo_font_face
&_cairo_toy_font_face_backend
};
+cairo_status_t
+_cairo_font_face_set_error (cairo_font_face_t *font_face,
+ cairo_status_t status)
+{
+ if (status == CAIRO_STATUS_SUCCESS)
+ return status;
+
+ _cairo_status_set_error (&font_face->status, status);
+
+ return _cairo_error (status);
+}
+
void
_cairo_font_face_init (cairo_font_face_t *font_face,
const cairo_font_face_backend_t *backend)
@@ -308,6 +320,7 @@ _cairo_toy_font_face_init_key (cairo_toy
hash += ((unsigned long) slant) * 1607;
hash += ((unsigned long) weight) * 1451;
+ assert (hash != 0);
key->base.hash_entry.hash = hash;
}
@@ -386,11 +399,17 @@ _cairo_toy_font_face_create (const char
&key.base.hash_entry,
(cairo_hash_entry_t **) &font_face))
{
- /* We increment the reference count here manually to avoid
- double-locking. */
- _cairo_reference_count_inc (&font_face->base.ref_count);
- _cairo_toy_font_face_hash_table_unlock ();
- return &font_face->base;
+ if (! font_face->base.status) {
+ /* We increment the reference count here manually to avoid
+ double-locking. */
+ _cairo_reference_count_inc (&font_face->base.ref_count);
+ _cairo_toy_font_face_hash_table_unlock ();
+ return &font_face->base;
+ }
+
+ /* remove the bad font from the hash table */
+ _cairo_hash_table_remove (hash_table, &key.base.hash_entry);
+ font_face->base.hash_entry.hash = 0;
}
/* Otherwise create it and insert into hash table. */
@@ -427,14 +446,16 @@ _cairo_toy_font_face_destroy (void *abst
cairo_toy_font_face_t *font_face = abstract_face;
cairo_hash_table_t *hash_table;
- if (font_face == NULL)
+ if (font_face == NULL ||
+ CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->base.ref_count))
return;
hash_table = _cairo_toy_font_face_hash_table_lock ();
/* All created objects must have been mapped in the hash table. */
assert (hash_table != NULL);
- _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+ if (font_face->base.hash_entry.hash != 0)
+ _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
_cairo_toy_font_face_hash_table_unlock ();
@@ -452,12 +473,19 @@ _cairo_toy_font_face_scaled_font_create
const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
cairo_status_t status;
+ if (font_face->base.status)
+ return font_face->base.status;
+
status = cairo_font_options_status ((cairo_font_options_t *) options);
if (status)
return status;
- return backend->create_toy (font_face,
- font_matrix, ctm, options, scaled_font);
+ return _cairo_font_face_set_error (&font_face->base,
+ backend->create_toy (font_face,
+ font_matrix,
+ ctm,
+ options,
+ scaled_font));
}
static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 47f06e7..ff844a5 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -649,6 +649,7 @@ cairo_scaled_font_create (cairo_font_fac
ctm, options, &scaled_font);
if (status) {
_cairo_scaled_font_map_unlock ();
+ status = _cairo_font_face_set_error (font_face, status);
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 7382292..9cd42f2 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1371,6 +1371,10 @@ cairo_private void
_cairo_font_face_init (cairo_font_face_t *font_face,
const cairo_font_face_backend_t *backend);
+cairo_private cairo_status_t
+_cairo_font_face_set_error (cairo_font_face_t *font_face,
+ cairo_status_t status);
+
cairo_private cairo_font_face_t *
_cairo_toy_font_face_create (const char *family,
cairo_font_slant_t slant,
diff-tree 4cffdf2681ba254587bd774ea49718e71535b067 (from de1f92ae14bfc4d74d8df88ae81d7b90dd6739f0)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 14:59:55 2007 +0100
[cairo-ft-font] Always call _cairo_ft_unscaled_font_fini ().
The _cairo_ft_unscaled_font_fini() was skipped during the destroy for
fonts generated by cairo_ft_font_face_create_for_ft_face(). However
this causes a mutex to be 'leaked' for each font.
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 7768a77..d6a6771 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -486,6 +486,8 @@ _cairo_ft_unscaled_font_destroy (void *a
*/
if (unscaled->faces && !unscaled->faces->unscaled)
cairo_font_face_destroy (&unscaled->faces->base);
+
+ unscaled->face = NULL;
} else {
cairo_ft_unscaled_font_map_t *font_map;
@@ -497,10 +499,10 @@ _cairo_ft_unscaled_font_destroy (void *a
&unscaled->base.hash_entry);
_font_map_release_face_lock_held (font_map, unscaled);
- _cairo_ft_unscaled_font_fini (unscaled);
_cairo_ft_unscaled_font_map_unlock ();
}
+ _cairo_ft_unscaled_font_fini (unscaled);
}
static cairo_bool_t
diff-tree de1f92ae14bfc4d74d8df88ae81d7b90dd6739f0 (from 2c256f292fc4a9fd8414e29c4df32d347e360900)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 4 14:51:16 2007 +0100
[cairo-output-stream] Propagate error status when copying streams.
During _cairo_memory_stream_copy(), if set, copy the incoming error over
to the destination stream and return early.
diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index 791c0f2..323bd06 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -46,7 +46,7 @@
#endif /* _MSC_VER */
-cairo_private void
+void
_cairo_output_stream_init (cairo_output_stream_t *stream,
cairo_output_stream_write_func_t write_func,
cairo_output_stream_close_func_t close_func)
@@ -58,7 +58,7 @@ _cairo_output_stream_init (cairo_output_
stream->closed = FALSE;
}
-cairo_private cairo_status_t
+cairo_status_t
_cairo_output_stream_fini (cairo_output_stream_t *stream)
{
return _cairo_output_stream_close (stream);
@@ -560,6 +560,14 @@ _cairo_memory_stream_copy (cairo_output_
{
memory_stream_t *stream = (memory_stream_t *) base;
+ if (dest->status)
+ return;
+
+ if (base->status) {
+ dest->status = base->status;
+ return;
+ }
+
_cairo_output_stream_write (dest,
_cairo_array_index (&stream->array, 0),
_cairo_array_num_elements (&stream->array));
More information about the cairo-commit
mailing list