[cairo-commit] 9 commits - src/cairo-atomic-private.h src/cairo-pdf-surface.c src/cairo-png.c src/cairo-ps-surface.c src/cairo-scaled-font.c src/cairo-scaled-font-subsets.c src/cairo-scaled-font-subsets-private.h src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-svg-surface.c src/cairo-type1-fallback.c src/cairo-type1-subset.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Oct 5 07:35:17 PDT 2007
src/cairo-atomic-private.h | 8
src/cairo-pdf-surface.c | 20 +-
src/cairo-png.c | 6
src/cairo-ps-surface.c | 27 ++
src/cairo-scaled-font-subsets-private.h | 2
src/cairo-scaled-font-subsets.c | 20 +-
src/cairo-scaled-font.c | 67 +++----
src/cairo-surface-fallback.c | 11 -
src/cairo-surface.c | 12 +
src/cairo-svg-surface.c | 4
src/cairo-type1-fallback.c | 3
src/cairo-type1-subset.c | 293 +++++++++++++++-----------------
12 files changed, 259 insertions(+), 214 deletions(-)
New commits:
diff-tree 6598973661490ce90b9f42155d8397af491b90c9 (from 3a2dd9d33686d6a6d1549965cacf48a7f401c086)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 10:23:13 2007 +0100
[cairo-scaled-font-subset] Propagate errors during collection.
Propagate the errors encountered whilst iterating over the scaled font
subsets ie _cairo_scaled_font_subsets_foreach_scaled() and co.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 60ee04b..96c3e8f 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3607,7 +3607,7 @@ _cairo_pdf_surface_emit_type3_font_subse
return _cairo_array_append (&surface->fonts, &font);
}
-static void
+static cairo_status_t
_cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
@@ -3617,29 +3617,31 @@ _cairo_pdf_surface_emit_unscaled_font_su
if (font_subset->is_composite) {
status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
status = _cairo_pdf_surface_emit_cff_fallback_font (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
} else {
#if CAIRO_HAS_FT_FONT
status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
#endif
status = _cairo_pdf_surface_emit_type1_fallback_font (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
}
+
+ return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
_cairo_pdf_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
@@ -3648,7 +3650,9 @@ _cairo_pdf_surface_emit_scaled_font_subs
status = _cairo_pdf_surface_emit_type3_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 7bf2af5..06d0c82 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -714,7 +714,7 @@ _cairo_ps_surface_emit_type3_font_subset
}
-static void
+static cairo_status_t
_cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
@@ -724,19 +724,21 @@ _cairo_ps_surface_emit_unscaled_font_sub
#if CAIRO_HAS_FT_FONT
status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
#endif
status = _cairo_ps_surface_emit_truetype_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
status = _cairo_ps_surface_emit_type1_font_fallback (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
_cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
@@ -745,7 +747,9 @@ _cairo_ps_surface_emit_scaled_font_subse
status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return;
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@@ -761,9 +765,14 @@ _cairo_ps_surface_emit_font_subsets (cai
status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets,
_cairo_ps_surface_emit_unscaled_font_subset,
surface);
+ if (status)
+ goto BAIL;
+
status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
_cairo_ps_surface_emit_scaled_font_subset,
surface);
+
+BAIL:
_cairo_scaled_font_subsets_destroy (surface->font_subsets);
surface->font_subsets = NULL;
@@ -1284,13 +1293,15 @@ _cairo_ps_surface_finish (void *abstract
_cairo_ps_surface_emit_header (surface);
- _cairo_ps_surface_emit_font_subsets (surface);
+ status = _cairo_ps_surface_emit_font_subsets (surface);
_cairo_ps_surface_emit_body (surface);
_cairo_ps_surface_emit_footer (surface);
- status = _cairo_output_stream_destroy (surface->stream);
+ status2 = _cairo_output_stream_destroy (surface->stream);
+ if (status == CAIRO_STATUS_SUCCESS)
+ status = status2;
fclose (surface->tmpfile);
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 5b9467a..d6dcb3f 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -188,7 +188,7 @@ _cairo_scaled_font_subsets_map_glyph (ca
unsigned long scaled_font_glyph_index,
cairo_scaled_font_subsets_glyph_t *subset_glyph_ret);
-typedef void
+typedef cairo_status_t
(*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset,
void *closure);
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index efc7999..4912793 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -95,6 +95,7 @@ typedef struct _cairo_sub_font_collectio
unsigned int subset_id;
+ cairo_status_t status;
cairo_scaled_font_subset_callback_func_t font_subset_callback;
void *font_subset_callback_closure;
} cairo_sub_font_collection_t;
@@ -367,6 +368,9 @@ _cairo_sub_font_collect (void *entry, vo
int i;
unsigned int j;
+ if (collection->status)
+ return;
+
for (i = 0; i <= sub_font->current_subset; i++) {
collection->subset_id = i;
@@ -382,6 +386,10 @@ _cairo_sub_font_collect (void *entry, vo
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
_cairo_sub_font_glyph_collect, collection);
+ if (collection->status)
+ break;
+ if (collection->num_glyphs == 0)
+ continue;
/* Ensure the resulting array has no uninitialized holes */
assert (collection->num_glyphs == collection->max_glyph + 1);
@@ -401,11 +409,14 @@ _cairo_sub_font_collect (void *entry, vo
subset.to_unicode[j] = 0xfffd;
}
}
- (collection->font_subset_callback) (&subset,
+ collection->status = (collection->font_subset_callback) (&subset,
collection->font_subset_callback_closure);
if (subset.to_unicode != NULL)
free (subset.to_unicode);
+
+ if (collection->status)
+ break;
}
}
@@ -634,6 +645,7 @@ _cairo_scaled_font_subsets_foreach_inter
collection.font_subset_callback = font_subset_callback;
collection.font_subset_callback_closure = closure;
+ collection.status = CAIRO_STATUS_SUCCESS;
if (is_scaled)
_cairo_hash_table_foreach (font_subsets->scaled_sub_fonts,
@@ -644,10 +656,10 @@ _cairo_scaled_font_subsets_foreach_inter
free (collection.glyphs);
- return CAIRO_STATUS_SUCCESS;
+ return collection.status;
}
-cairo_private cairo_status_t
+cairo_status_t
_cairo_scaled_font_subsets_foreach_scaled (cairo_scaled_font_subsets_t *font_subsets,
cairo_scaled_font_subset_callback_func_t font_subset_callback,
void *closure)
@@ -658,7 +670,7 @@ _cairo_scaled_font_subsets_foreach_scale
TRUE);
}
-cairo_private cairo_status_t
+cairo_status_t
_cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *font_subsets,
cairo_scaled_font_subset_callback_func_t font_subset_callback,
void *closure)
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 6ec33d7..71adc39 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -707,7 +707,7 @@ _cairo_svg_document_emit_glyph (cairo_sv
return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
_cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
@@ -723,6 +723,8 @@ _cairo_svg_document_emit_font_subset (ca
if (status)
break;
}
+
+ return status;
}
static cairo_status_t
diff-tree 3a2dd9d33686d6a6d1549965cacf48a7f401c086 (from 81243ee7ef1c3fdf3d571778c414adb64e05fa9d)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 10:10:16 2007 +0100
[cairo-png] Markup a couple of original error sites with _cairo_error().
Add the _cairo_error() markup to the original error sites within the png
read/write functions.
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 2715067..03a7375 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -95,7 +95,7 @@ png_simple_error_callback (png_structp p
/* default to the most likely error */
if (*error == CAIRO_STATUS_SUCCESS)
- *error = CAIRO_STATUS_NO_MEMORY;
+ *error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
longjmp (png_save_ptr->jmpbuf, 1);
}
@@ -240,7 +240,7 @@ stdio_write_func (png_structp png, png_b
data += ret;
if (size && ferror (fp)) {
cairo_status_t *error = png_get_error_ptr (png);
- *error = CAIRO_STATUS_WRITE_ERROR;
+ *error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
png_error (png, NULL);
}
}
@@ -494,7 +494,7 @@ stdio_read_func (png_structp png, png_by
data += ret;
if (size && ferror (fp)) {
cairo_status_t *error = png_get_error_ptr (png);
- *error = CAIRO_STATUS_READ_ERROR;
+ *error = _cairo_error (CAIRO_STATUS_READ_ERROR);
png_error (png, NULL);
}
}
diff-tree 81243ee7ef1c3fdf3d571778c414adb64e05fa9d (from f3d921baca02af4db5f8f1743f32e800d2f492bc)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 09:57:56 2007 +0100
[cairo-scaled-font] Mask cannot be NULL so remove redundant check.
We either generate a mask for the glyphs or throw an error and bypass
the check, so at that point mask can never be NULL and we do not need
the test.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index a1568a3..1ce998a 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1163,6 +1163,7 @@ _cairo_scaled_font_show_glyphs (cairo_sc
{
cairo_status_t status;
cairo_surface_t *mask = NULL;
+ cairo_surface_pattern_t mask_pattern;
int i;
/* These operators aren't interpreted the same way by the backends;
@@ -1255,20 +1256,16 @@ _cairo_scaled_font_show_glyphs (cairo_sc
goto CLEANUP_MASK;
}
- if (mask != NULL) {
- cairo_surface_pattern_t mask_pattern;
+ _cairo_pattern_init_for_surface (&mask_pattern, mask);
- _cairo_pattern_init_for_surface (&mask_pattern, mask);
+ status = _cairo_surface_composite (op, pattern, &mask_pattern.base,
+ surface,
+ source_x, source_y,
+ 0, 0,
+ dest_x, dest_y,
+ width, height);
- status = _cairo_surface_composite (op, pattern, &mask_pattern.base,
- surface,
- source_x, source_y,
- 0, 0,
- dest_x, dest_y,
- width, height);
-
- _cairo_pattern_fini (&mask_pattern.base);
- }
+ _cairo_pattern_fini (&mask_pattern.base);
CLEANUP_MASK:
_cairo_cache_thaw (scaled_font->glyphs);
diff-tree f3d921baca02af4db5f8f1743f32e800d2f492bc (from 41aab58f3ae044f1baf668363376532381270ff4)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 09:53:36 2007 +0100
[cairo-scaled-font] Destroy the zombie font.
If we do not transfer the font to the holdovers array (because it has
been removed from the cache and left in a zombie state), destroy it.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 9cbe7bb..a1568a3 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -733,29 +733,31 @@ 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)
- && 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
- * the reference count). To make room for it, we do actually
- * destroy the least-recently-used holdover.
- */
- if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS)
- {
- lru = font_map->holdovers[0];
- assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&lru->ref_count));
-
- _cairo_hash_table_remove (font_map->hash_table, &lru->hash_entry);
-
- font_map->num_holdovers--;
- memmove (&font_map->holdovers[0],
- &font_map->holdovers[1],
- font_map->num_holdovers * sizeof (cairo_scaled_font_t*));
- }
+ if (_cairo_reference_count_dec_and_test (&scaled_font->ref_count)) {
+ if (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
+ * the reference count). To make room for it, we do actually
+ * destroy the least-recently-used holdover.
+ */
+ if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS)
+ {
+ lru = font_map->holdovers[0];
+ assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&lru->ref_count));
+
+ _cairo_hash_table_remove (font_map->hash_table, &lru->hash_entry);
+
+ font_map->num_holdovers--;
+ memmove (&font_map->holdovers[0],
+ &font_map->holdovers[1],
+ font_map->num_holdovers * sizeof (cairo_scaled_font_t*));
+ }
- font_map->holdovers[font_map->num_holdovers] = scaled_font;
- font_map->num_holdovers++;
+ font_map->holdovers[font_map->num_holdovers] = scaled_font;
+ font_map->num_holdovers++;
+ } else
+ lru = scaled_font;
}
_cairo_scaled_font_map_unlock ();
diff-tree 41aab58f3ae044f1baf668363376532381270ff4 (from f3ae783c9c81106bdb3aa2d15b848d131c39cd93)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 09:44:29 2007 +0100
[cairo-surface] Add the usual guards to the API entry point.
Add the checks for unmodifiable surfaces (snapshots, finished and error) to
cairo_surface_set_fallback_resolution.
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 94ee2de..d0a5c46 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -882,6 +882,18 @@ cairo_surface_set_fallback_resolution (c
double x_pixels_per_inch,
double y_pixels_per_inch)
{
+ cairo_status_t status;
+
+ assert (! surface->is_snapshot);
+
+ if (surface->status)
+ return;
+
+ if (surface->finished) {
+ status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+ return;
+ }
+
surface->x_fallback_resolution = x_pixels_per_inch;
surface->y_fallback_resolution = y_pixels_per_inch;
}
diff-tree f3ae783c9c81106bdb3aa2d15b848d131c39cd93 (from 29a5aae958fd9c6a8ec71326c7dad679c0bf5938)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 09:42:23 2007 +0100
[cairo-surface-fallback] Release the acquired image on error.
Add _cairo_surface_release_source_image() to the error paths.
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index e9a77ad..4abeaf9 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -1049,8 +1049,11 @@ _cairo_surface_fallback_snapshot (cairo_
snapshot = cairo_image_surface_create (image->format,
image->width,
image->height);
- if (cairo_surface_status (snapshot))
+ if (cairo_surface_status (snapshot)) {
+ _cairo_surface_release_source_image (surface,
+ image, &image_extra);
return snapshot;
+ }
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
@@ -1065,14 +1068,14 @@ _cairo_surface_fallback_snapshot (cairo_
image->height);
_cairo_pattern_fini (&pattern.base);
+ _cairo_surface_release_source_image (surface,
+ image, &image_extra);
+
if (status) {
cairo_surface_destroy (snapshot);
return (cairo_surface_t *) &_cairo_surface_nil;
}
- _cairo_surface_release_source_image (surface,
- image, image_extra);
-
snapshot->device_transform = surface->device_transform;
snapshot->device_transform_inverse = surface->device_transform_inverse;
diff-tree 29a5aae958fd9c6a8ec71326c7dad679c0bf5938 (from dd0f2d851cd4c4b2bab05668800e5379712f8ac6)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 09:39:20 2007 +0100
[cairo-type1-fallback] Propagate error from closing the stream.
Propagate the error from destroying the font and closing the output stream.
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 7f91643..24fb4d1 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -865,8 +865,7 @@ _cairo_type2_charstrings_init (cairo_typ
type2_subset->ascent = (int) font->y_max;
type2_subset->descent = (int) font->y_min;
- cairo_type1_font_destroy (font);
- return CAIRO_STATUS_SUCCESS;
+ return cairo_type1_font_destroy (font);
fail2:
_cairo_array_fini (&charstring);
diff-tree dd0f2d851cd4c4b2bab05668800e5379712f8ac6 (from 91d18eefe7be6ad3d1fa951c7424d5843e4718f9)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 15:22:13 2007 +0100
[cairo-atomic] Hide compiler warnings for _cairo_status_set_error().
gcc treats cairo_status_t as an unsigned integer and so generates a
warning when passing it address as signed integer pointer to
_cairo_atomic_int_cmpxchg(). Use an ugly cast to hide the warning and
similarly to hide the warning about the unused result.
diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index 3bf4e27..fbf1d9a 100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
@@ -81,8 +81,12 @@ _cairo_atomic_int_cmpxchg (int *x, int o
#endif
-#define _cairo_status_set_error(status, err) \
- (void) _cairo_atomic_int_cmpxchg (status, CAIRO_STATUS_SUCCESS, err)
+#define _cairo_status_set_error(status, err) do { \
+ /* hide compiler warnings about cairo_status_t != int (gcc treats its as \
+ * an unsigned integer instead, and about ignoring the return value. */ \
+ int ret__ = _cairo_atomic_int_cmpxchg ((int *) status, CAIRO_STATUS_SUCCESS, err); \
+ (void) ret__; \
+} while (0)
CAIRO_END_DECLS
diff-tree 91d18eefe7be6ad3d1fa951c7424d5843e4718f9 (from bd2245f8b87d85f5ea61200838c10de70e776cf5)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 5 15:16:28 2007 +0100
[cairo-type1-subset] Propagate error status (correctly!)
Adrian Johnson pointed out a couple of mistakes in my previous attempt,
535e7c161b907292eac098b6b4305373558948df, to ensure propagation of errors
throughout the generation of the type1 subset.
This time the status member of the cairo_type1_font_subset_t is removed
in favour of simply return the error status from each function. This
completely avoids the issue of whether we overwrite a pre-existing error
status and confustion of status returns and the status member. The
removal of the status from the structure is possible due to its
short-lived nature - it is not exposed outside of the
_cairo_type1_subset_init() function, and is not shared by any other
piece of code.
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index cdd6dfc..ba37731 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -99,21 +99,8 @@ typedef struct _cairo_type1_font_subset
unsigned short eexec_key;
cairo_bool_t hex_encode;
int hex_column;
-
- cairo_status_t status;
} cairo_type1_font_subset_t;
-static cairo_status_t
-_cairo_type1_font_subset_set_error (cairo_type1_font_subset_t *font,
- cairo_status_t status)
-{
- if (status == CAIRO_STATUS_SUCCESS || status == CAIRO_INT_STATUS_UNSUPPORTED)
- return status;
-
- _cairo_status_set_error (&font->status, status);
-
- return _cairo_error (status);
-}
static cairo_status_t
_cairo_type1_font_subset_create (cairo_unscaled_font_t *unscaled_font,
@@ -130,7 +117,7 @@ _cairo_type1_font_subset_create (cairo_u
ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
- if (!face)
+ if (face == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (FT_Get_PS_Font_Info(face, &font_info) != 0) {
@@ -192,8 +179,6 @@ _cairo_type1_font_subset_create (cairo_u
fail1:
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- status = _cairo_error (status);
return status;
}
@@ -223,6 +208,9 @@ find_token (const char *buffer, const ch
int i, length;
/* FIXME: find substring really must be find_token */
+ if (buffer == NULL)
+ return NULL;
+
length = strlen (token);
for (i = 0; buffer + i < end - length + 1; i++)
if (memcmp (buffer + i, token, length) == 0)
@@ -240,9 +228,6 @@ cairo_type1_font_subset_find_segments (c
const char *eexec_token;
int size;
- if (font->status)
- return font->status;
-
p = (unsigned char *) font->type1_data;
font->type1_end = font->type1_data + font->type1_length;
if (p[0] == 0x80 && p[1] == 0x01) {
@@ -265,7 +250,7 @@ cairo_type1_font_subset_find_segments (c
} else {
eexec_token = find_token ((char *) p, font->type1_end, "eexec");
if (eexec_token == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+ return CAIRO_INT_STATUS_UNSUPPORTED;
font->header_segment_size = eexec_token - (char *) p + strlen ("eexec\n");
font->header_segment = (char *) p;
@@ -284,14 +269,11 @@ cairo_type1_font_subset_write_header (ca
const char *start, *end, *segment_end;
unsigned int i;
- if (font->status)
- return font->status;
-
segment_end = font->header_segment + font->header_segment_size;
start = find_token (font->header_segment, segment_end, "/FontName");
if (start == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+ return CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_output_stream_write (font->output, font->header_segment,
start - font->header_segment);
@@ -300,12 +282,12 @@ cairo_type1_font_subset_write_header (ca
end = find_token (start, segment_end, "def");
if (end == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+ return CAIRO_INT_STATUS_UNSUPPORTED;
end += 3;
start = find_token (end, segment_end, "/Encoding");
if (start == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+ return CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_output_stream_write (font->output, end, start - end);
_cairo_output_stream_printf (font->output,
@@ -323,12 +305,12 @@ cairo_type1_font_subset_write_header (ca
end = find_token (start, segment_end, "def");
if (end == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+ return CAIRO_INT_STATUS_UNSUPPORTED;
end += 3;
_cairo_output_stream_write (font->output, end, segment_end - end);
- return _cairo_type1_font_subset_set_error(font, font->output->status);
+ return font->output->status;
}
static int
@@ -351,9 +333,6 @@ cairo_type1_font_subset_write_encrypted
static const char hex_digits[16] = "0123456789abcdef";
char digits[3];
- if (font->status)
- return font->status;
-
in = (const unsigned char *) data;
end = (const unsigned char *) data + length;
while (in < end) {
@@ -379,7 +358,7 @@ cairo_type1_font_subset_write_encrypted
}
}
- return _cairo_type1_font_subset_set_error (font, font->output->status);
+ return font->output->status;
}
static cairo_status_t
@@ -390,15 +369,12 @@ cairo_type1_font_subset_decrypt_eexec_se
char *out;
int c, p;
- if (font->status)
- return font->status;
-
in = (unsigned char *) font->eexec_segment;
end = (unsigned char *) in + font->eexec_segment_size;
font->cleartext = malloc (font->eexec_segment_size);
if (font->cleartext == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
out = font->cleartext;
while (in < end) {
@@ -458,9 +434,6 @@ cairo_type1_font_subset_get_glyph_names_
char buffer[256];
FT_Error error;
- if (font->status)
- return font->status;
-
/* Get glyph names and width using the freetype API */
for (i = 0; i < font->base.num_glyphs; i++) {
if (font->glyphs[i].name != NULL)
@@ -471,7 +444,7 @@ cairo_type1_font_subset_get_glyph_names_
FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
if (error != 0) {
printf ("could not load glyph %d\n", i);
- return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
font->glyphs[i].width = font->face->glyph->metrics.horiAdvance;
@@ -479,12 +452,12 @@ cairo_type1_font_subset_get_glyph_names_
error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
if (error != 0) {
printf ("could not get glyph name for glyph %d\n", i);
- return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
font->glyphs[i].name = strdup (buffer);
if (font->glyphs[i].name == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
return CAIRO_STATUS_SUCCESS;
@@ -709,35 +682,38 @@ static const int16_t ps_standard_encodin
#define ps_standard_encoding(index) ((index) ? ps_standard_encoding_symbol+ps_standard_encoding_offset[(index)] : NULL)
-static void
+static cairo_status_t
use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
{
const char *glyph_name;
if (index < 0 || index > 255)
- return;
+ return CAIRO_STATUS_SUCCESS;
glyph_name = ps_standard_encoding(index);
if (glyph_name == NULL)
- return;
+ return CAIRO_STATUS_SUCCESS;
index = cairo_type1_font_subset_lookup_glyph (font,
glyph_name,
strlen(glyph_name));
if (index < 0)
- return;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
cairo_type1_font_subset_use_glyph (font, index);
+
+ return CAIRO_STATUS_SUCCESS;
}
#define TYPE1_CHARSTRING_COMMAND_ESCAPE (12)
#define TYPE1_CHARSTRING_COMMAND_SEAC (32 + 6)
-static void
+static cairo_status_t
cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
const char *name, int name_length,
const char *encrypted_charstring, int encrypted_charstring_length)
{
+ cairo_status_t status;
unsigned char *charstring;
const unsigned char *end;
const unsigned char *p;
@@ -745,10 +721,8 @@ cairo_type1_font_subset_look_for_seac(ca
int command;
charstring = malloc (encrypted_charstring_length);
- if (charstring == NULL) {
- _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
- return;
- }
+ if (charstring == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
cairo_type1_font_subset_decrypt_charstring ((const unsigned char *)
encrypted_charstring,
@@ -774,8 +748,14 @@ cairo_type1_font_subset_look_for_seac(ca
* glyph is composed from. All we need to do is to
* make sure those glyphs are present in the subset
* under their standard names. */
- use_standard_encoding_glyph (font, stack[3]);
- use_standard_encoding_glyph (font, stack[4]);
+ status = use_standard_encoding_glyph (font, stack[3]);
+ if (status)
+ return status;
+
+ status = use_standard_encoding_glyph (font, stack[4]);
+ if (status)
+ return status;
+
sp = 0;
break;
@@ -792,35 +772,50 @@ cairo_type1_font_subset_look_for_seac(ca
}
free (charstring);
+
+ return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
write_used_glyphs (cairo_type1_font_subset_t *font,
const char *name, int name_length,
const char *charstring, int charstring_length)
{
+ cairo_status_t status;
char buffer[256];
int length;
length = snprintf (buffer, sizeof buffer,
"/%.*s %d %s ",
name_length, name, charstring_length, font->rd);
- cairo_type1_font_subset_write_encrypted (font, buffer, length);
- cairo_type1_font_subset_write_encrypted (font,
- charstring, charstring_length);
+ status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
+ if (status)
+ return status;
+
+ status = cairo_type1_font_subset_write_encrypted (font,
+ charstring,
+ charstring_length);
+ if (status)
+ return status;
+
length = snprintf (buffer, sizeof buffer, "%s\n", font->nd);
- cairo_type1_font_subset_write_encrypted (font, buffer, length);
+ status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
+ if (status)
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
}
-typedef void (*glyph_func_t) (cairo_type1_font_subset_t *font,
- const char *name, int name_length,
- const char *charstring, int charstring_length);
+typedef cairo_status_t (*glyph_func_t) (cairo_type1_font_subset_t *font,
+ const char *name, int name_length,
+ const char *charstring, int charstring_length);
-static const char *
+static cairo_status_t
cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
const char *dict_start,
const char *dict_end,
- glyph_func_t func)
+ glyph_func_t func,
+ const char **dict_out)
{
int charstring_length, name_length, glyph_index;
const char *p, *charstring, *name;
@@ -848,10 +843,8 @@ cairo_type1_font_subset_for_each_glyph (
name_length = p - name;
charstring_length = strtol (p, &end, 10);
- if (p == end) {
- _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
- return NULL;
- }
+ if (p == end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
/* Skip past -| or RD to binary data. There is exactly one space
* between the -| or RD token and the encrypted data, thus '+ 1'. */
@@ -864,36 +857,36 @@ cairo_type1_font_subset_for_each_glyph (
/* In case any of the skip_token() calls above reached EOF, p will
* be equal to dict_end. */
- if (p == dict_end) {
- _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
- return NULL;
- }
+ if (p == dict_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
glyph_index = cairo_type1_font_subset_lookup_glyph (font,
name, name_length);
- if (font->glyphs[glyph_index].subset_index >= 0)
- func (font, name, name_length, charstring, charstring_length);
-
- if (font->status)
- return NULL;
+ if (font->glyphs[glyph_index].subset_index >= 0) {
+ cairo_status_t status = func (font,
+ name, name_length,
+ charstring, charstring_length);
+ if (status)
+ return status;
+ }
}
- return p;
+ *dict_out = p;
+
+ return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
const char *name)
{
+ cairo_status_t status;
const char *p, *charstrings, *dict_start;
const char *closefile_token;
char buffer[32], *glyph_count_end;
int num_charstrings, length;
- if (font->status)
- return;
-
/* The private dict holds hint information, common subroutines and
* the actual glyph definitions (charstrings).
*
@@ -911,86 +904,98 @@ cairo_type1_font_subset_write_private_di
* conceivably have "/CharStrings" in it, so we might need to skip
* this more cleverly. */
charstrings = find_token (font->cleartext, font->cleartext_end, "/CharStrings");
- if (charstrings == NULL) {
- _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
- return;
- }
+ if (charstrings == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
/* Scan past /CharStrings and the integer following it. */
p = charstrings + strlen ("/CharStrings");
num_charstrings = strtol (p, &glyph_count_end, 10);
- if (p == glyph_count_end) {
- _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
- return;
- }
+ if (p == glyph_count_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
/* Look for a '/' which marks the beginning of the first glyph
* definition. */
for (p = glyph_count_end; p < font->cleartext_end; p++)
if (*p == '/')
break;
- if (p == font->cleartext_end) {
- _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
- return;
- }
+ if (p == font->cleartext_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
dict_start = p;
- if (cairo_type1_font_subset_get_glyph_names_and_widths (font))
- return;
+ status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
+ if (status)
+ return status;
/* Now that we have the private dictionary broken down in
* sections, do the first pass through the glyph definitions to
* figure out which subrs and othersubrs are use and which extra
* glyphs may be required by the seac operator. */
- p = cairo_type1_font_subset_for_each_glyph (font,
- dict_start,
- font->cleartext_end,
- cairo_type1_font_subset_look_for_seac);
+ status = cairo_type1_font_subset_for_each_glyph (font,
+ dict_start,
+ font->cleartext_end,
+ cairo_type1_font_subset_look_for_seac,
+ &p);
+ if (status)
+ return status;
closefile_token = find_token (p, font->cleartext_end, "closefile");
- if (closefile_token == NULL) {
- _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
- return;
- }
+ if (closefile_token == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
- if (cairo_type1_font_subset_get_glyph_names_and_widths (font))
- return;
+ status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
+ if (status)
+ return status;
/* We're ready to start outputting. First write the header,
* i.e. the public part of the font dict.*/
- if (cairo_type1_font_subset_write_header (font, name))
- return;
+ status = cairo_type1_font_subset_write_header (font, name);
+ if (status)
+ return status;
font->base.header_size = _cairo_output_stream_get_position (font->output);
/* Start outputting the private dict. First output everything up
* to the /CharStrings token. */
- cairo_type1_font_subset_write_encrypted (font, font->cleartext,
- charstrings - font->cleartext);
+ status = cairo_type1_font_subset_write_encrypted (font, font->cleartext,
+ charstrings - font->cleartext);
+ if (status)
+ return status;
/* Write out new charstring count */
length = snprintf (buffer, sizeof buffer,
"/CharStrings %d", font->num_glyphs);
- cairo_type1_font_subset_write_encrypted (font, buffer, length);
+ status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
+ if (status)
+ return status;
/* Write out text between the charstring count and the first
* charstring definition */
- cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
- dict_start - glyph_count_end);
+ status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
+ dict_start - glyph_count_end);
+ if (status)
+ return status;
/* Write out the charstring definitions for each of the glyphs in
* the subset. */
- p = cairo_type1_font_subset_for_each_glyph (font,
- dict_start,
- font->cleartext_end,
- write_used_glyphs);
+ status = cairo_type1_font_subset_for_each_glyph (font,
+ dict_start,
+ font->cleartext_end,
+ write_used_glyphs,
+ &p);
+ if (status)
+ return status;
/* Output what's left between the end of the glyph definitions and
* the end of the private dict to the output. */
- cairo_type1_font_subset_write_encrypted (font, p,
- closefile_token - p + strlen ("closefile") + 1);
+ status = cairo_type1_font_subset_write_encrypted (font, p,
+ closefile_token - p + strlen ("closefile") + 1);
+ if (status)
+ return status;
+
_cairo_output_stream_write (font->output, "\n", 1);
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@@ -1010,26 +1015,20 @@ cairo_type1_font_subset_write_trailer(ca
cleartomark_token = find_token (font->type1_data, font->type1_end, "cleartomark");
if (cleartomark_token == NULL)
- return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+ return CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_output_stream_write (font->output, cleartomark_token,
font->type1_end - cleartomark_token);
- return _cairo_type1_font_subset_set_error(font, font->output->status);
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
type1_font_write (void *closure, const unsigned char *data, unsigned int length)
{
cairo_type1_font_subset_t *font = closure;
- cairo_status_t status;
-
- if (font->status)
- return font->status;
- status = _cairo_array_append_multiple (&font->contents, data, length);
-
- return _cairo_type1_font_subset_set_error (font, status);
+ return _cairo_array_append_multiple (&font->contents, data, length);
}
static cairo_status_t
@@ -1038,14 +1037,12 @@ cairo_type1_font_subset_write (cairo_typ
{
cairo_status_t status;
- if (font->status)
- return font->status;
-
status = cairo_type1_font_subset_find_segments (font);
if (status)
return status;
status = cairo_type1_font_subset_decrypt_eexec_segment (font);
+ if (status)
return status;
/* Determine which glyph definition delimiters to use. */
@@ -1057,24 +1054,28 @@ cairo_type1_font_subset_write (cairo_typ
font->nd = "ND";
} else {
/* Don't know *what* kind of font this is... */
- return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
font->hex_column = 0;
- cairo_type1_font_subset_write_private_dict (font, name);
+ status = cairo_type1_font_subset_write_private_dict (font, name);
+ if (status)
+ return status;
font->base.data_size = _cairo_output_stream_get_position (font->output) -
font->base.header_size;
- cairo_type1_font_subset_write_trailer (font);
+ status = cairo_type1_font_subset_write_trailer (font);
+ if (status)
+ return status;
font->base.trailer_size =
_cairo_output_stream_get_position (font->output) -
font->base.header_size - font->base.data_size;
- return _cairo_type1_font_subset_set_error(font, font->output->status);
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@@ -1085,20 +1086,17 @@ cairo_type1_font_subset_generate (void
cairo_type1_font_subset_t *font = abstract_font;
cairo_ft_unscaled_font_t *ft_unscaled_font;
unsigned long ret;
+ cairo_status_t status;
ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
-
- /* If anything fails below, it's out of memory. */
- font->status = CAIRO_STATUS_NO_MEMORY;
-
font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
- if (!font->face)
+ if (font->face == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->type1_length = font->face->stream->size;
font->type1_data = malloc (font->type1_length);
if (font->type1_data == NULL) {
- _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
@@ -1113,22 +1111,25 @@ cairo_type1_font_subset_generate (void
font->face->stream->base, font->type1_length);
}
- if (_cairo_array_grow_by (&font->contents, 4096) != CAIRO_STATUS_SUCCESS)
+ status = _cairo_array_grow_by (&font->contents, 4096);
+ if (status)
goto fail;
font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
- if (font->output == NULL)
+ status = _cairo_output_stream_get_status (font->output);
+ if (status)
goto fail;
- font->status = CAIRO_STATUS_SUCCESS;
- cairo_type1_font_subset_write (font, name);
+ status = cairo_type1_font_subset_write (font, name);
+ if (status)
+ goto fail;
font->base.data = _cairo_array_index (&font->contents, 0);
fail:
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
- return font->status;
+ return status;
}
static void
@@ -1235,8 +1236,6 @@ _cairo_type1_subset_init (cairo_type1_su
fail1:
cairo_type1_font_subset_destroy (font);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- status = _cairo_error (status);
return status;
}
More information about the cairo-commit
mailing list