[cairo-commit] 4 commits - src/cairoint.h src/cairo-output-stream.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-svg-surface.c

Carl Worth cworth at kemper.freedesktop.org
Wed Apr 12 13:43:21 PDT 2006


 src/cairo-output-stream.c |   23 ++++++++++++++-
 src/cairo-pdf-surface.c   |    2 -
 src/cairo-ps-surface.c    |   67 ++++++++++++++++++++++++++++++++++++----------
 src/cairo-svg-surface.c   |    2 -
 src/cairoint.h            |    5 ++-
 5 files changed, 80 insertions(+), 19 deletions(-)

New commits:
diff-tree 32994379db92ef8208ba11b825b1246e2b442566 (from 5444aa55b35aff7d6cff8b5e8a5ab020711562ac)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 12 13:40:05 2006 -0700

    Fix missing argument to printf in _cairo_ps_surface_stat_page

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 70e13ed..ef4b89c 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -359,8 +359,9 @@ _cairo_ps_surface_start_page (cairo_ps_s
 {
     _cairo_output_stream_printf (surface->stream,
 				 "%%%%Page: %d %d\n",
-				 ++surface->num_pages);
-
+				 surface->num_pages,
+				 surface->num_pages);
+    surface->num_pages++;
 
     _cairo_output_stream_printf (surface->stream,
 				 "gsave %f %f translate %f %f scale \n",
diff-tree 5444aa55b35aff7d6cff8b5e8a5ab020711562ac (from a7abf8e4513a7ca03cdb7db6f80a438a4897d208)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 12 13:34:03 2006 -0700

    Clean up output_stream error handling in _cairo_ps_surface_create.
    
    We teach the output stream to catch a NULL file error here, which
    allows for less checking in ps_surface_create. We also fix the ps
    surface code to look for the status of a nil stream rather than
    checking for NULL.

diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index a03131a..3b53aa9 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -356,6 +356,9 @@ stdio_close (void *closure)
 cairo_output_stream_t *
 _cairo_output_stream_create_for_file (FILE *file)
 {
+    if (file == NULL)
+	return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
+
     return _cairo_output_stream_create (stdio_write, stdio_flush, file);
 }
 
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 6bebd91..70e13ed 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -63,12 +63,16 @@ _cairo_ps_set_paginated_mode (cairo_surf
 typedef struct cairo_ps_surface {
     cairo_surface_t base;
 
-    /* PS-specific fields */
-    cairo_output_stream_t *stream;
+    /* Here final_stream corresponds to the stream/file passed to
+     * cairo_ps_surface_create surface is built. Meanwhile stream is a
+     * temporary stream in which the file output is built, (so that
+     * the header can be built and inserted into the target stream
+     * before the contents of the temporary stream are copied). */
     cairo_output_stream_t *final_stream;
 
     FILE *tmpfile;
-    
+    cairo_output_stream_t *stream;
+
     double width;
     double height;
     double x_dpi;
@@ -146,6 +150,7 @@ _cairo_ps_surface_create_for_stream_inte
 					      double		     width,
 					      double		     height)
 {
+    cairo_status_t status;
     cairo_ps_surface_t *surface;
 
     surface = malloc (sizeof (cairo_ps_surface_t));
@@ -157,18 +162,14 @@ _cairo_ps_surface_create_for_stream_inte
     _cairo_surface_init (&surface->base, &cairo_ps_surface_backend);
 
     surface->final_stream = stream;
+
     surface->tmpfile = tmpfile ();
-    
-    if (!surface->tmpfile) {
-	free (surface);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_surface_t*) &_cairo_surface_nil;
-    }
     surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile);
-    if (!surface->stream) {
+    status = _cairo_output_stream_get_status (surface->stream);
+    if (status) {
 	fclose (surface->tmpfile);
 	free (surface);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error (status);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
diff-tree a7abf8e4513a7ca03cdb7db6f80a438a4897d208 (from parents)
Merge: 0386a728957bdb3549da8e772c31b86295175a4b ade195cdba5b0d13c121e44709151bfbb0c44085
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 12 12:54:28 2006 -0700

    Merge 'Save PS output in temp file' from ps-type3 branch

diff-tree ade195cdba5b0d13c121e44709151bfbb0c44085 (from 732e06258c81427cf7fedfca98107e21244264eb)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sat Apr 8 21:29:14 2006 -0700

    Save PS output in temp file so we can prepend global data (like fonts)

diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index 16d9371..d84b5c3 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -330,6 +330,16 @@ stdio_write (void *closure, const unsign
 }
 
 static cairo_status_t
+stdio_flush (void *closure)
+{
+    FILE *file = closure;
+
+    fflush (file);
+
+    return CAIRO_STATUS_SUCCESS;    /* XXX errors */
+}
+
+static cairo_status_t
 stdio_close (void *closure)
 {
     FILE *file = closure;
@@ -337,11 +347,17 @@ stdio_close (void *closure)
     fflush (file);
     fclose (file);
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_STATUS_SUCCESS;    /* XXX errors */
+}
+
+cairo_output_stream_t *
+_cairo_output_stream_create_for_file (FILE *file)
+{
+    return _cairo_output_stream_create (stdio_write, stdio_flush, file);
 }
 
 cairo_output_stream_t *
-_cairo_output_stream_create_for_file (const char *filename)
+_cairo_output_stream_create_for_filename (const char *filename)
 {
     FILE *file;
 
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index b01fcd9..03d161c 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -380,7 +380,7 @@ cairo_pdf_surface_create (const char		*f
     cairo_status_t status;
     cairo_output_stream_t *stream;
 
-    stream = _cairo_output_stream_create_for_file (filename);
+    stream = _cairo_output_stream_create_for_filename (filename);
     status = _cairo_output_stream_get_status (stream);
     if (status) {
 	_cairo_error (status);
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 8a37868..756b774 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -65,7 +65,10 @@ typedef struct cairo_ps_surface {
 
     /* PS-specific fields */
     cairo_output_stream_t *stream;
+    cairo_output_stream_t *final_stream;
 
+    FILE *tmpfile;
+    
     double width;
     double height;
     double x_dpi;
@@ -95,18 +98,19 @@ _cairo_ps_surface_emit_header (cairo_ps_
 
     now = time (NULL);
 
-    _cairo_output_stream_printf (surface->stream,
+    _cairo_output_stream_printf (surface->final_stream,
 				 "%%!PS-Adobe-3.0\n"
 				 "%%%%Creator: cairo (http://cairographics.org)\n"
 				 "%%%%CreationDate: %s"
-				 "%%%%Pages: (atend)\n"
+				 "%%%%Pages: %d\n"
 				 "%%%%BoundingBox: %f %f %f %f\n",
 				 ctime (&now),
+				 surface->num_pages,
 				 0.0, 0.0, 
 				 surface->width,
 				 surface->height);
 
-    _cairo_output_stream_printf (surface->stream,
+    _cairo_output_stream_printf (surface->final_stream,
 				 "%%%%DocumentData: Clean7Bit\n"
 				 "%%%%LanguageLevel: 2\n"
 				 "%%%%Orientation: Portrait\n"
@@ -114,13 +118,27 @@ _cairo_ps_surface_emit_header (cairo_ps_
 }
 
 static void
+_cairo_ps_surface_emit_fonts (cairo_ps_surface_t *surface)
+{
+}
+
+static void
+_cairo_ps_surface_emit_body (cairo_ps_surface_t *surface)
+{
+    char    buf[4096];
+    int	    n;
+    
+    rewind (surface->tmpfile);
+    while ((n = fread (buf, 1, sizeof (buf), surface->tmpfile)) > 0)
+	_cairo_output_stream_write (surface->final_stream, buf, n);
+}
+
+static void
 _cairo_ps_surface_emit_footer (cairo_ps_surface_t *surface)
 {
-    _cairo_output_stream_printf (surface->stream,
+    _cairo_output_stream_printf (surface->final_stream,
 				 "%%%%Trailer\n"
-				 "%%%%Pages: %d\n"
-				 "%%%%EOF\n",
-				 surface->num_pages);
+				 "%%%%EOF\n");
 }
 
 static cairo_surface_t *
@@ -138,7 +156,21 @@ _cairo_ps_surface_create_for_stream_inte
 
     _cairo_surface_init (&surface->base, &cairo_ps_surface_backend);
 
-    surface->stream = stream;
+    surface->final_stream = stream;
+    surface->tmpfile = tmpfile ();
+    
+    if (!surface->tmpfile) {
+	free (surface);
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_surface_t*) &_cairo_surface_nil;
+    }
+    surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile);
+    if (!surface->stream) {
+	fclose (surface->tmpfile);
+	free (surface);
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_surface_t*) &_cairo_surface_nil;
+    }
 
     surface->width  = width;
     surface->height = height;
@@ -157,8 +189,6 @@ _cairo_ps_surface_create_for_stream_inte
     _cairo_array_init (&surface->fonts, sizeof (cairo_font_subset_t *));
 #endif
 
-    _cairo_ps_surface_emit_header (surface);
-
     return _cairo_paginated_surface_create (&surface->base,
 					    CAIRO_CONTENT_COLOR_ALPHA,
 					    width, height,
@@ -190,7 +220,7 @@ cairo_ps_surface_create (const char		*fi
     cairo_status_t status;
     cairo_output_stream_t *stream;
 
-    stream = _cairo_output_stream_create_for_file (filename);
+    stream = _cairo_output_stream_create_for_filename (filename);
     status = _cairo_output_stream_get_status (stream);
     if (status) {
 	_cairo_error (status);
@@ -297,9 +327,12 @@ _cairo_ps_surface_finish (void *abstract
 {
     cairo_ps_surface_t *surface = abstract_surface;
 
+    _cairo_ps_surface_emit_header (surface);
+    
 #if DONE_ADDING_FONTS_SUPPORT_BACK_AFTER_SWITCHING_TO_PAGINATED
     _cairo_ps_surface_write_font_subsets (surface);
 #endif
+    _cairo_ps_surface_emit_body (surface);
 
     _cairo_ps_surface_emit_footer (surface);
 
@@ -313,6 +346,10 @@ _cairo_ps_surface_finish (void *abstract
 
     _cairo_output_stream_destroy (surface->stream);
 
+    fclose (surface->tmpfile);
+
+    _cairo_output_stream_destroy (surface->final_stream);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 21d73f6..d5c45eb 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -164,7 +164,7 @@ cairo_svg_surface_create (const char	*fi
     cairo_status_t status;
     cairo_output_stream_t *stream;
 
-    stream = _cairo_output_stream_create_for_file (filename);
+    stream = _cairo_output_stream_create_for_filename (filename);
     status = _cairo_output_stream_get_status (stream);
     if (status) {
 	_cairo_error (status);
diff --git a/src/cairoint.h b/src/cairoint.h
index 6cd8bfb..4cfa948 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2190,7 +2190,10 @@ _cairo_output_stream_get_status (cairo_o
  * least) in order to ensure that everything is properly cleaned up.
  */
 cairo_private cairo_output_stream_t *
-_cairo_output_stream_create_for_file (const char *filename);
+_cairo_output_stream_create_for_filename (const char *filename);
+
+cairo_private cairo_output_stream_t *
+_cairo_output_stream_create_for_file (FILE *file);
 
 /* cairo_base85_stream.c */
 cairo_output_stream_t *


More information about the cairo-commit mailing list