summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2010-11-02 22:39:57 +1030
committerAdrian Johnson <ajohnson@redneon.com>2010-11-23 00:13:02 +1030
commit9862c38fc71c6dcd444da3b079e5404cd14594c3 (patch)
tree33f6ec24b8c2dacb26500a122083b96953601258
parent3445401ae6bc8687fc76f690016cc281c388005d (diff)
Add unique_id mime type
to ensure surfaces with the same unique_id mime type are not embedded more than once in PDF files.
-rw-r--r--src/cairo-pdf-surface-private.h2
-rw-r--r--src/cairo-pdf-surface.c38
-rw-r--r--src/cairo-surface.c8
-rw-r--r--src/cairo.h1
4 files changed, 47 insertions, 2 deletions
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index 221418ec9..5c70ef973 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -67,6 +67,8 @@ typedef struct _cairo_pdf_group_resources {
typedef struct _cairo_pdf_source_surface_entry {
cairo_hash_entry_t base;
unsigned int id;
+ const unsigned char *unique_id;
+ unsigned long unique_id_length;
cairo_bool_t interpolate;
cairo_pdf_resource_t surface_res;
int width;
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index ae70a47b4..f048dc885 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1039,13 +1039,24 @@ _cairo_pdf_source_surface_equal (const void *key_a, const void *key_b)
const cairo_pdf_source_surface_entry_t *a = key_a;
const cairo_pdf_source_surface_entry_t *b = key_b;
- return (a->id == b->id) && (a->interpolate == b->interpolate);
+ if (a->interpolate != b->interpolate)
+ return FALSE;
+
+ if (a->unique_id && b->unique_id && a->unique_id_length == b->unique_id_length)
+ return (memcmp (a->unique_id, b->unique_id, a->unique_id_length) == 0);
+
+ return (a->id == b->id);
}
static void
_cairo_pdf_source_surface_init_key (cairo_pdf_source_surface_entry_t *key)
{
- key->base.hash = key->id;
+ if (key->unique_id && key->unique_id_length > 0) {
+ key->base.hash = _cairo_hash_bytes (_CAIRO_HASH_INIT_VALUE,
+ key->unique_id, key->unique_id_length);
+ } else {
+ key->base.hash = key->id;
+ }
}
static cairo_int_status_t
@@ -1146,6 +1157,8 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
cairo_pdf_source_surface_entry_t *surface_entry;
cairo_status_t status;
cairo_bool_t interpolate;
+ const unsigned char *unique_id;
+ unsigned long unique_id_length;
switch (filter) {
default:
@@ -1163,6 +1176,8 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
surface_key.id = source->unique_id;
surface_key.interpolate = interpolate;
+ cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_UNIQUE_ID,
+ &surface_key.unique_id, &surface_key.unique_id_length);
_cairo_pdf_source_surface_init_key (&surface_key);
surface_entry = _cairo_hash_table_lookup (surface->all_surfaces, &surface_key.base);
if (surface_entry) {
@@ -1179,6 +1194,22 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
surface_entry->id = surface_key.id;
surface_entry->interpolate = interpolate;
+ cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_UNIQUE_ID,
+ &unique_id, &unique_id_length);
+ if (unique_id && unique_id_length > 0) {
+ surface_entry->unique_id = malloc (unique_id_length);
+ if (surface_entry->unique_id == NULL) {
+ cairo_surface_destroy (source);
+ free (surface_entry);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+
+ surface_entry->unique_id_length = unique_id_length;
+ memcpy (surface_entry->unique_id, unique_id, unique_id_length);
+ } else {
+ surface_entry->unique_id = NULL;
+ surface_entry->unique_id_length = 0;
+ }
_cairo_pdf_source_surface_init_key (surface_entry);
src_surface.hash_entry = surface_entry;
@@ -1631,6 +1662,9 @@ _cairo_pdf_source_surface_entry_pluck (void *entry, void *closure)
cairo_hash_table_t *patterns = closure;
_cairo_hash_table_remove (patterns, &surface_entry->base);
+ if (surface_entry->unique_id)
+ free (surface_entry->unique_id);
+
free (surface_entry);
}
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 2293991f8..76f644716 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -892,6 +892,14 @@ _cairo_mime_data_destroy (void *ptr)
*/
/**
+ * CAIRO_MIME_TYPE_UNIQUE_ID:
+ *
+ * Unique identifier for a surface (cairo specific MIME type).
+ *
+ * @Since: 1.12
+ */
+
+/**
* cairo_surface_set_mime_data:
* @surface: a #cairo_surface_t
* @mime_type: the MIME type of the image data
diff --git a/src/cairo.h b/src/cairo.h
index 136c5dbf2..a45bf1489 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -2155,6 +2155,7 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
#define CAIRO_MIME_TYPE_PNG "image/png"
#define CAIRO_MIME_TYPE_JP2 "image/jp2"
#define CAIRO_MIME_TYPE_URI "text/x-uri"
+#define CAIRO_MIME_TYPE_UNIQUE_ID "application/x-cairo.uuid"
cairo_public void
cairo_surface_get_mime_data (cairo_surface_t *surface,