[cairo-commit] 2 commits - src/cairo-pdf-surface.c src/cairo-pdf-surface-private.h

Adrian Johnson ajohnson at kemper.freedesktop.org
Tue Sep 25 06:34:31 PDT 2007


 src/cairo-pdf-surface-private.h |    4 ++
 src/cairo-pdf-surface.c         |   69 +++++++++++++++++++++++++++++++---------
 2 files changed, 59 insertions(+), 14 deletions(-)

New commits:
diff-tree be327a7b49a62c684e133aad5d5d6adec30b60e6 (from 99fd9449c24055fd7b3623157397fe61282e2de0)
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Tue Sep 25 23:04:03 2007 +0930

    PDF: Compress the content stream
    
    The content stream compression that was previously implemented was
    inadvertently bypassed when the new stream handling for meta surface
    patterns was implemented.

diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index 0de4c0f..28b6fd1 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -83,6 +83,8 @@ struct _cairo_pdf_surface {
     cairo_pdf_resource_t next_available_resource;
     cairo_pdf_resource_t pages_resource;
 
+    cairo_bool_t compress_content;
+
     struct {
 	cairo_bool_t active;
 	cairo_pdf_resource_t self;
@@ -95,6 +97,7 @@ struct _cairo_pdf_surface {
     struct {
 	cairo_bool_t active;
 	cairo_output_stream_t *stream;
+	cairo_output_stream_t *mem_stream;
 	cairo_output_stream_t *old_output;
 	cairo_pdf_group_resources_t resources;
 	cairo_bool_t is_knockout;
@@ -104,6 +107,7 @@ struct _cairo_pdf_surface {
     struct {
 	cairo_bool_t active;
 	cairo_output_stream_t *stream;
+	cairo_output_stream_t *mem_stream;
 	cairo_output_stream_t *old_output;
 	cairo_pdf_group_resources_t resources;
     } content_stream;
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 94af547..ad1f96f 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -338,11 +338,14 @@ _cairo_pdf_surface_create_for_stream_int
     surface->next_available_resource.id = 1;
     surface->pages_resource = _cairo_pdf_surface_new_object (surface);
 
+    surface->compress_content = TRUE;
     surface->pdf_stream.active = FALSE;
     surface->content_stream.active = FALSE;
     surface->content_stream.stream = NULL;
+    surface->content_stream.mem_stream = NULL;
     surface->group_stream.active = FALSE;
     surface->group_stream.stream = NULL;
+    surface->group_stream.mem_stream = NULL;
 
     surface->current_group = NULL;
     surface->current_resources = NULL;
@@ -834,15 +837,22 @@ _cairo_pdf_surface_write_memory_stream (
     _cairo_output_stream_printf (surface->output,
 				 "%d 0 obj\r\n"
 				 "<< /Type /XObject\r\n"
-				 "   /Length %d\r\n"
+				 "   /Length %d\r\n",
+				 group.id,
+				 _cairo_memory_stream_length (mem_stream));
+
+    if (surface->compress_content) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /Filter /FlateDecode\r\n");
+    }
+
+    _cairo_output_stream_printf (surface->output,
 				 "   /Subtype /Form\r\n"
 				 "   /BBox [ 0 0 %f %f ]\r\n"
 				 "   /Group <<\r\n"
 				 "      /Type /Group\r\n"
 				 "      /S /Transparency\r\n"
 				 "      /CS /DeviceRGB\r\n",
-				 group.id,
-				 _cairo_memory_stream_length (mem_stream),
 				 surface->width,
 				 surface->height);
 
@@ -872,7 +882,15 @@ _cairo_pdf_surface_open_group (cairo_pdf
     assert (surface->group_stream.active == FALSE);
 
     surface->group_stream.active = TRUE;
-    surface->group_stream.stream = _cairo_memory_stream_create ();
+
+    surface->group_stream.mem_stream = _cairo_memory_stream_create ();
+    if (surface->compress_content) {
+	surface->group_stream.stream =
+	    _cairo_deflate_stream_create (surface->group_stream.mem_stream);
+    } else {
+	surface->group_stream.stream = surface->group_stream.mem_stream;
+    }
+
     surface->group_stream.old_output = surface->output;
     surface->output = surface->group_stream.stream;
     _cairo_pdf_group_resources_clear (&surface->group_stream.resources);
@@ -893,16 +911,26 @@ static cairo_status_t
 _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
 				cairo_pdf_resource_t *group)
 {
+    cairo_status_t status;
+
     assert (surface->pdf_stream.active == FALSE);
     assert (surface->group_stream.active == TRUE);
 
+    if (surface->compress_content) {
+	status = _cairo_output_stream_destroy (surface->group_stream.stream);
+	if (status)
+	    return status;
+
+	_cairo_output_stream_printf (surface->group_stream.mem_stream,
+				     "\r\n");
+    }
     surface->output = surface->group_stream.old_output;
     surface->group_stream.active = FALSE;
     *group = _cairo_pdf_surface_write_memory_stream (surface,
-						     surface->group_stream.stream,
+						     surface->group_stream.mem_stream,
 						     &surface->group_stream.resources,
 						     surface->group_stream.is_knockout);
-    return _cairo_output_stream_close (surface->group_stream.stream);
+    return _cairo_output_stream_close (surface->group_stream.mem_stream);
 }
 
 static void
@@ -945,7 +973,13 @@ _cairo_pdf_surface_start_content_stream 
     assert (surface->group_stream.active == FALSE);
 
     surface->content_stream.active = TRUE;
-    surface->content_stream.stream = _cairo_memory_stream_create ();
+    surface->content_stream.mem_stream = _cairo_memory_stream_create ();
+    if (surface->compress_content) {
+	surface->content_stream.stream =
+	    _cairo_deflate_stream_create (surface->content_stream.mem_stream);
+    } else {
+	surface->content_stream.stream = surface->content_stream.mem_stream;
+    }
     surface->content_stream.old_output = surface->output;
     surface->output = surface->content_stream.stream;
     _cairo_pdf_group_resources_clear (&surface->content_stream.resources);
@@ -994,22 +1028,31 @@ static cairo_status_t
 _cairo_pdf_surface_stop_content_stream (cairo_pdf_surface_t *surface)
 {
     cairo_pdf_resource_t group;
+    cairo_status_t status;
 
     assert (surface->pdf_stream.active == FALSE);
     assert (surface->content_stream.active == TRUE);
 
+    if (surface->compress_content) {
+	status = _cairo_output_stream_destroy (surface->content_stream.stream);
+	if (status)
+	    return status;
+
+	_cairo_output_stream_printf (surface->content_stream.mem_stream,
+				     "\r\n");
+    }
     surface->output = surface->content_stream.old_output;
     surface->content_stream.active = FALSE;
-    if (_cairo_memory_stream_length (surface->content_stream.stream) > 0) {
+    if (_cairo_memory_stream_length (surface->content_stream.mem_stream) > 0) {
 	group = _cairo_pdf_surface_write_memory_stream (surface,
-							surface->content_stream.stream,
+							surface->content_stream.mem_stream,
 							&surface->content_stream.resources,
 							FALSE);
 	_cairo_pdf_surface_add_group_to_content_stream (surface, group);
     }
     surface->content_stream.active = FALSE;
 
-    return _cairo_output_stream_close (surface->content_stream.stream);
+    return _cairo_output_stream_close (surface->content_stream.mem_stream);
 }
 
 static cairo_status_t
@@ -1020,7 +1063,7 @@ _cairo_pdf_surface_check_content_stream_
     if (surface->content_stream.active == FALSE)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (_cairo_memory_stream_length (surface->content_stream.stream) > GROUP_STREAM_LIMIT) {
+    if (_cairo_memory_stream_length (surface->content_stream.mem_stream) > GROUP_STREAM_LIMIT) {
 	status = _cairo_pdf_surface_stop_content_stream (surface);
 	if (status)
 	    return status;
diff-tree 99fd9449c24055fd7b3623157397fe61282e2de0 (from dc23ecb6198f1e28b6096cbef931e15407cc20a8)
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Tue Sep 25 21:57:46 2007 +0930

    PDF: Remove duplication from the resource dictionary
    
    The same font identifer was being added the resources every time it
    was referenced.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index ba631aa..94af547 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -623,10 +623,8 @@ _cairo_pdf_surface_add_font (cairo_pdf_s
     for (i = 0; i < num_fonts; i++) {
 	_cairo_array_copy_element (&surface->fonts, i, &font);
 	if (font.font_id == font_id &&
-	    font.subset_id == subset_id) {
-	    status = _cairo_array_append (&res->fonts, &font);
+	    font.subset_id == subset_id)
 	    return CAIRO_STATUS_SUCCESS;
-	}
     }
 
     font.font_id = font_id;


More information about the cairo-commit mailing list