diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c index 16d937172..d84b5c3f5 100644 --- a/src/cairo-output-stream.c +++ b/src/cairo-output-stream.c @@ -329,6 +329,16 @@ stdio_write (void *closure, const unsigned char *data, unsigned int length) return CAIRO_STATUS_SUCCESS; } +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) { @@ -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 (const char *filename) +_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_filename (const char *filename) { FILE *file; diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index b01fcd970..03d161c95 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -380,7 +380,7 @@ cairo_pdf_surface_create (const char *filename, 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 8a3786871..756b774e4 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,32 +98,47 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface) 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" "%%%%EndComments\n"); } +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_internal (cairo_output_stream_t *stream, _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_internal (cairo_output_stream_t *stream, _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 *filename, 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_surface) { 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_surface) _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 21d73f693..d5c45eb5d 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -164,7 +164,7 @@ cairo_svg_surface_create (const char *filename, 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 6cd8bfbef..4cfa94840 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2190,7 +2190,10 @@ _cairo_output_stream_get_status (cairo_output_stream_t *stream); * 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 *