[cairo-commit] 2 commits - src/cairo-pdf-surface.c
Carl Worth
cworth at kemper.freedesktop.org
Fri May 12 15:00:21 PDT 2006
src/cairo-pdf-surface.c | 1215 ++++++++++++++++++++----------------------------
1 files changed, 526 insertions(+), 689 deletions(-)
New commits:
diff-tree f500cef19f049a4a0ed296172618db2f26794932 (from d84a1cac1cc2da8a34fb6aa91c3c4f4058527207)
Author: Carl Worth <cworth at cworth.org>
Date: Fri May 12 14:56:11 2006 -0700
PDF: Fold (unused) cairo_pdf_document_t into cairo_pdf_surface_t
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index d0e5ebb..2746cd0 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -88,7 +88,6 @@
typedef struct cairo_pdf_object cairo_pdf_object_t;
typedef struct cairo_pdf_resource cairo_pdf_resource_t;
-typedef struct cairo_pdf_document cairo_pdf_document_t;
typedef struct cairo_pdf_surface cairo_pdf_surface_t;
struct cairo_pdf_object {
@@ -99,17 +98,25 @@ struct cairo_pdf_resource {
unsigned int id;
};
-struct cairo_pdf_document {
- cairo_output_stream_t *output_stream;
- unsigned long ref_count;
- cairo_surface_t *owner;
- cairo_bool_t finished;
+struct cairo_pdf_surface {
+ cairo_surface_t base;
+
+ /* Prefer the name "output" here to avoid confusion over the
+ * structure within a PDF document known as a "stream". */
+ cairo_output_stream_t *output;
double width;
double height;
double x_dpi;
double y_dpi;
+ cairo_array_t objects;
+ cairo_array_t pages;
+ cairo_array_t patterns;
+ cairo_array_t xobjects;
+ cairo_array_t streams;
+ cairo_array_t alphas;
+
cairo_pdf_resource_t next_available_resource;
cairo_pdf_resource_t pages_resource;
@@ -120,25 +127,6 @@ struct cairo_pdf_document {
long start_offset;
} current_stream;
- cairo_array_t objects;
- cairo_array_t pages;
-
- cairo_array_t fonts;
-};
-
-struct cairo_pdf_surface {
- cairo_surface_t base;
-
- double width;
- double height;
-
- cairo_pdf_document_t *document;
-
- cairo_array_t patterns;
- cairo_array_t xobjects;
- cairo_array_t streams;
- cairo_array_t alphas;
- cairo_array_t fonts;
cairo_bool_t has_clip;
cairo_paginated_mode_t paginated_mode;
@@ -146,77 +134,70 @@ struct cairo_pdf_surface {
#define DEFAULT_DPI 300
-static cairo_pdf_document_t *
-_cairo_pdf_document_create (cairo_output_stream_t *stream,
- double width,
- double height);
-
-static void
-_cairo_pdf_document_destroy (cairo_pdf_document_t *document);
-
-static cairo_status_t
-_cairo_pdf_document_finish (cairo_pdf_document_t *document);
-
-static cairo_pdf_document_t *
-_cairo_pdf_document_reference (cairo_pdf_document_t *document);
-
static cairo_pdf_resource_t
-_cairo_pdf_document_new_object (cairo_pdf_document_t *document);
-
-static cairo_status_t
-_cairo_pdf_document_add_page (cairo_pdf_document_t *document,
- cairo_pdf_surface_t *surface);
+_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface);
static void
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface);
static cairo_pdf_resource_t
-_cairo_pdf_document_open_stream (cairo_pdf_document_t *document,
- const char *fmt,
- ...) CAIRO_PRINTF_FORMAT(2, 3);
+_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
+ const char *fmt,
+ ...) CAIRO_PRINTF_FORMAT(2, 3);
static void
-_cairo_pdf_document_close_stream (cairo_pdf_document_t *document);
+_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface);
-static cairo_surface_t *
-_cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document,
- double width,
- double height);
static void
_cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t stream);
+static void
+_cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface);
+
+static cairo_pdf_resource_t
+_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface);
+
+static cairo_pdf_resource_t
+_cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface);
+
+static long
+_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface);
+
+static cairo_status_t
+_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
+
static const cairo_surface_backend_t cairo_pdf_surface_backend;
static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend;
static cairo_pdf_resource_t
-_cairo_pdf_document_new_object (cairo_pdf_document_t *document)
+_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface)
{
cairo_pdf_resource_t resource;
cairo_status_t status;
cairo_pdf_object_t object;
- object.offset = _cairo_output_stream_get_position (document->output_stream);
+ object.offset = _cairo_output_stream_get_position (surface->output);
- status = _cairo_array_append (&document->objects, &object);
+ status = _cairo_array_append (&surface->objects, &object);
if (status) {
resource.id = 0;
return resource;
}
- resource = document->next_available_resource;
- document->next_available_resource.id++;
+ resource = surface->next_available_resource;
+ surface->next_available_resource.id++;
return resource;
}
static void
-_cairo_pdf_document_update_object (cairo_pdf_document_t *document,
- cairo_pdf_resource_t resource)
+_cairo_pdf_surface_update_object (cairo_pdf_surface_t *surface,
+ cairo_pdf_resource_t resource)
{
cairo_pdf_object_t *object;
- object = _cairo_array_index (&document->objects, resource.id - 1);
- object->offset = _cairo_output_stream_get_position (document->output_stream);
+ object = _cairo_array_index (&surface->objects, resource.id - 1);
+ object->offset = _cairo_output_stream_get_position (surface->output);
}
static void
@@ -259,25 +240,48 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_
}
static cairo_surface_t *
-_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *stream,
+_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
double width,
double height)
{
- cairo_pdf_document_t *document;
- cairo_surface_t *target;
+ cairo_pdf_surface_t *surface;
- document = _cairo_pdf_document_create (stream, width, height);
- if (document == NULL) {
+ surface = malloc (sizeof (cairo_pdf_surface_t));
+ if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
- target = _cairo_pdf_surface_create_for_document (document, width, height);
+ _cairo_surface_init (&surface->base, &cairo_pdf_surface_backend);
+
+ surface->output = output;
+
+ surface->width = width;
+ surface->height = height;
+ surface->x_dpi = DEFAULT_DPI;
+ surface->y_dpi = DEFAULT_DPI;
+
+ _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t));
+ _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t));
+ _cairo_array_init (&surface->patterns, sizeof (cairo_pdf_resource_t));
+ _cairo_array_init (&surface->xobjects, sizeof (cairo_pdf_resource_t));
+ _cairo_array_init (&surface->streams, sizeof (cairo_pdf_resource_t));
+ _cairo_array_init (&surface->alphas, sizeof (double));
+
+ surface->next_available_resource.id = 1;
+ surface->pages_resource = _cairo_pdf_surface_new_object (surface);
+
+ surface->current_stream.active = FALSE;
- document->owner = target;
- _cairo_pdf_document_destroy (document);
+ surface->has_clip = FALSE;
+
+ surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
+
+ /* Document header */
+ _cairo_output_stream_printf (surface->output,
+ "%%PDF-1.4\r\n");
- return _cairo_paginated_surface_create (target,
+ return _cairo_paginated_surface_create (&surface->base,
CAIRO_CONTENT_COLOR_ALPHA,
width, height,
&cairo_pdf_surface_paginated_backend);
@@ -289,7 +293,7 @@ _cairo_pdf_surface_create_for_stream_int
* @closure: the closure argument for @write
* @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
* @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
- *
+ *
* Creates a PDF surface of the specified size in points to be written
* incrementally to the stream represented by @write and @closure.
*
@@ -308,16 +312,16 @@ cairo_pdf_surface_create_for_stream (cai
double height_in_points)
{
cairo_status_t status;
- cairo_output_stream_t *stream;
+ cairo_output_stream_t *output;
- stream = _cairo_output_stream_create (write, NULL, closure);
- status = _cairo_output_stream_get_status (stream);
+ output = _cairo_output_stream_create (write, NULL, closure);
+ status = _cairo_output_stream_get_status (output);
if (status) {
_cairo_error (status);
return (cairo_surface_t*) &_cairo_surface_nil;
}
- return _cairo_pdf_surface_create_for_stream_internal (stream,
+ return _cairo_pdf_surface_create_for_stream_internal (output,
width_in_points,
height_in_points);
}
@@ -327,10 +331,10 @@ cairo_pdf_surface_create_for_stream (cai
* @filename: a filename for the PDF output (must be writable)
* @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
* @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
- *
+ *
* Creates a PDF surface of the specified size in points to be written
* to @filename.
- *
+ *
* Return value: a pointer to the newly created surface. The caller
* owns the surface and should call cairo_surface_destroy when done
* with it.
@@ -345,16 +349,16 @@ cairo_pdf_surface_create (const char *f
double height_in_points)
{
cairo_status_t status;
- cairo_output_stream_t *stream;
+ cairo_output_stream_t *output;
- stream = _cairo_output_stream_create_for_filename (filename);
- status = _cairo_output_stream_get_status (stream);
+ output = _cairo_output_stream_create_for_filename (filename);
+ status = _cairo_output_stream_get_status (output);
if (status) {
_cairo_error (status);
return (cairo_surface_t*) &_cairo_surface_nil;
}
- return _cairo_pdf_surface_create_for_stream_internal (stream,
+ return _cairo_pdf_surface_create_for_stream_internal (output,
width_in_points,
height_in_points);
}
@@ -393,7 +397,7 @@ _extract_pdf_surface (cairo_surface_t
* @surface: a PDF cairo_surface_t
* @x_dpi: horizontal dpi
* @y_dpi: vertical dpi
- *
+ *
* Set the horizontal and vertical resolution for image fallbacks.
* When the pdf backend needs to fall back to image overlays, it will
* use this resolution. These DPI values are not used for any other
@@ -414,8 +418,8 @@ cairo_pdf_surface_set_dpi (cairo_surface
return;
}
- pdf_surface->document->x_dpi = x_dpi;
- pdf_surface->document->y_dpi = y_dpi;
+ pdf_surface->x_dpi = x_dpi;
+ pdf_surface->y_dpi = y_dpi;
}
/**
@@ -423,7 +427,7 @@ cairo_pdf_surface_set_dpi (cairo_surface
* @surface: a PDF cairo_surface_t
* @width_in_points: new surface width, in points (1 point == 1/72.0 inch)
* @height_in_points: new surface height, in points (1 point == 1/72.0 inch)
- *
+ *
* Changes the size of a PDF surface for the current (and
* subsequent) pages.
*
@@ -451,37 +455,6 @@ cairo_pdf_surface_set_size (cairo_surfac
pdf_surface->height = height_in_points;
}
-static cairo_surface_t *
-_cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document,
- double width,
- double height)
-{
- cairo_pdf_surface_t *surface;
-
- surface = malloc (sizeof (cairo_pdf_surface_t));
- if (surface == NULL) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
- return (cairo_surface_t*) &_cairo_surface_nil;
- }
-
- _cairo_surface_init (&surface->base, &cairo_pdf_surface_backend);
-
- surface->width = width;
- surface->height = height;
-
- surface->document = _cairo_pdf_document_reference (document);
- _cairo_array_init (&surface->streams, sizeof (cairo_pdf_resource_t));
- _cairo_array_init (&surface->patterns, sizeof (cairo_pdf_resource_t));
- _cairo_array_init (&surface->xobjects, sizeof (cairo_pdf_resource_t));
- _cairo_array_init (&surface->alphas, sizeof (double));
- _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_resource_t));
- surface->has_clip = FALSE;
-
- surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
-
- return &surface->base;
-}
-
static void
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
{
@@ -489,7 +462,6 @@ _cairo_pdf_surface_clear (cairo_pdf_surf
_cairo_array_truncate (&surface->patterns, 0);
_cairo_array_truncate (&surface->xobjects, 0);
_cairo_array_truncate (&surface->alphas, 0);
- _cairo_array_truncate (&surface->fonts, 0);
}
static cairo_surface_t *
@@ -506,63 +478,61 @@ _cairo_pdf_surface_create_similar (void
}
static cairo_pdf_resource_t
-_cairo_pdf_document_open_stream (cairo_pdf_document_t *document,
- const char *fmt,
- ...)
+_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
+ const char *fmt,
+ ...)
{
- cairo_output_stream_t *output_stream = document->output_stream;
va_list ap;
- document->current_stream.active = TRUE;
- document->current_stream.self = _cairo_pdf_document_new_object (document);
- document->current_stream.length = _cairo_pdf_document_new_object (document);
+ surface->current_stream.active = TRUE;
+ surface->current_stream.self = _cairo_pdf_surface_new_object (surface);
+ surface->current_stream.length = _cairo_pdf_surface_new_object (surface);
- _cairo_output_stream_printf (output_stream,
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Length %d 0 R\r\n",
- document->current_stream.self.id,
- document->current_stream.length.id);
+ surface->current_stream.self.id,
+ surface->current_stream.length.id);
if (fmt != NULL) {
va_start (ap, fmt);
- _cairo_output_stream_vprintf (output_stream, fmt, ap);
+ _cairo_output_stream_vprintf (surface->output, fmt, ap);
va_end (ap);
}
- _cairo_output_stream_printf (output_stream,
+ _cairo_output_stream_printf (surface->output,
">>\r\n"
"stream\r\n");
- document->current_stream.start_offset = _cairo_output_stream_get_position (output_stream);
+ surface->current_stream.start_offset = _cairo_output_stream_get_position (surface->output);
- return document->current_stream.self;
+ return surface->current_stream.self;
}
static void
-_cairo_pdf_document_close_stream (cairo_pdf_document_t *document)
+_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
{
- cairo_output_stream_t *output_stream = document->output_stream;
long length;
- if (! document->current_stream.active)
+ if (! surface->current_stream.active)
return;
- length = _cairo_output_stream_get_position (output_stream) -
- document->current_stream.start_offset;
- _cairo_output_stream_printf (output_stream,
+ length = _cairo_output_stream_get_position (surface->output) -
+ surface->current_stream.start_offset;
+ _cairo_output_stream_printf (surface->output,
"endstream\r\n"
"endobj\r\n");
- _cairo_pdf_document_update_object (document,
- document->current_stream.length);
- _cairo_output_stream_printf (output_stream,
+ _cairo_pdf_surface_update_object (surface,
+ surface->current_stream.length);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
" %ld\r\n"
"endobj\r\n",
- document->current_stream.length.id,
+ surface->current_stream.length.id,
length);
- document->current_stream.active = FALSE;
+ surface->current_stream.active = FALSE;
}
static cairo_status_t
@@ -570,46 +540,63 @@ _cairo_pdf_surface_finish (void *abstrac
{
cairo_status_t status;
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
+ long offset;
+ cairo_pdf_resource_t info, catalog;
- _cairo_pdf_document_close_stream (document);
+ _cairo_pdf_surface_close_stream (surface);
- if (document->owner == &surface->base)
- status = _cairo_pdf_document_finish (document);
- else
- status = CAIRO_STATUS_SUCCESS;
+ _cairo_pdf_surface_write_pages (surface);
- _cairo_pdf_document_destroy (document);
+ info = _cairo_pdf_surface_write_info (surface);
+ catalog = _cairo_pdf_surface_write_catalog (surface);
+ offset = _cairo_pdf_surface_write_xref (surface);
- _cairo_array_fini (&surface->streams);
+ _cairo_output_stream_printf (surface->output,
+ "trailer\r\n"
+ "<< /Size %d\r\n"
+ " /Root %d 0 R\r\n"
+ " /Info %d 0 R\r\n"
+ ">>\r\n",
+ surface->next_available_resource.id,
+ catalog.id,
+ info.id);
+
+ _cairo_output_stream_printf (surface->output,
+ "startxref\r\n"
+ "%ld\r\n"
+ "%%%%EOF\r\n",
+ offset);
+
+ status = _cairo_output_stream_get_status (surface->output);
+ _cairo_output_stream_destroy (surface->output);
+
+ _cairo_array_fini (&surface->objects);
+ _cairo_array_fini (&surface->pages);
_cairo_array_fini (&surface->patterns);
_cairo_array_fini (&surface->xobjects);
+ _cairo_array_fini (&surface->streams);
_cairo_array_fini (&surface->alphas);
- _cairo_array_fini (&surface->fonts);
return status;
}
-static void
+static void
_cairo_pdf_surface_pause_content_stream (cairo_pdf_surface_t *surface)
{
- cairo_pdf_document_t *document = surface->document;
-
- _cairo_pdf_document_close_stream (document);
+ _cairo_pdf_surface_close_stream (surface);
}
static void
_cairo_pdf_surface_resume_content_stream (cairo_pdf_surface_t *surface)
{
- cairo_pdf_document_t *document = surface->document;
cairo_pdf_resource_t stream;
- stream = _cairo_pdf_document_open_stream (document,
- " /Type /XObject\r\n"
- " /Subtype /Form\r\n"
- " /BBox [ 0 0 %f %f ]\r\n",
- surface->width,
- surface->height);
+ stream = _cairo_pdf_surface_open_stream (surface,
+ " /Type /XObject\r\n"
+ " /Subtype /Form\r\n"
+ " /BBox [ 0 0 %f %f ]\r\n",
+ surface->width,
+ surface->height);
_cairo_pdf_surface_add_stream (surface, stream);
}
@@ -618,20 +605,18 @@ static cairo_int_status_t
_cairo_pdf_surface_start_page (void *abstract_surface)
{
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t stream;
- stream = _cairo_pdf_document_open_stream (document,
- " /Type /XObject\r\n"
- " /Subtype /Form\r\n"
- " /BBox [ 0 0 %f %f ]\r\n",
- surface->width,
- surface->height);
+ stream = _cairo_pdf_surface_open_stream (surface,
+ " /Type /XObject\r\n"
+ " /Subtype /Form\r\n"
+ " /BBox [ 0 0 %f %f ]\r\n",
+ surface->width,
+ surface->height);
_cairo_pdf_surface_add_stream (surface, stream);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"1 0 0 -1 0 %f cm\r\n",
surface->height);
@@ -662,12 +647,11 @@ compress_dup (const void *data, unsigned
* no SMask object will be emitted and *id_ret will be set to 0.
*/
static cairo_status_t
-emit_smask (cairo_pdf_document_t *document,
+emit_smask (cairo_pdf_surface_t *surface,
cairo_image_surface_t *image,
cairo_pdf_resource_t *stream_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
- cairo_output_stream_t *output = document->output_stream;
char *alpha, *alpha_compressed;
unsigned long alpha_size, alpha_compressed_size;
pixman_bits_t *pixel;
@@ -708,21 +692,20 @@ emit_smask (cairo_pdf_document_t *docume
if (alpha_compressed == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEANUP_ALPHA;
-
}
- *stream_ret = _cairo_pdf_document_open_stream (document,
- " /Type /XObject\r\n"
- " /Subtype /Image\r\n"
- " /Width %d\r\n"
- " /Height %d\r\n"
- " /ColorSpace /DeviceGray\r\n"
- " /BitsPerComponent 8\r\n"
- " /Filter /FlateDecode\r\n",
- image->width, image->height);
- _cairo_output_stream_write (output, alpha_compressed, alpha_compressed_size);
- _cairo_output_stream_printf (output, "\r\n");
- _cairo_pdf_document_close_stream (document);
+ *stream_ret = _cairo_pdf_surface_open_stream (surface,
+ " /Type /XObject\r\n"
+ " /Subtype /Image\r\n"
+ " /Width %d\r\n"
+ " /Height %d\r\n"
+ " /ColorSpace /DeviceGray\r\n"
+ " /BitsPerComponent 8\r\n"
+ " /Filter /FlateDecode\r\n",
+ image->width, image->height);
+ _cairo_output_stream_write (surface->output, alpha_compressed, alpha_compressed_size);
+ _cairo_output_stream_printf (surface->output, "\r\n");
+ _cairo_pdf_surface_close_stream (surface);
free (alpha_compressed);
CLEANUP_ALPHA:
@@ -732,15 +715,14 @@ emit_smask (cairo_pdf_document_t *docume
}
-/* Emit image data into the given document, providing an id that can
- * be used to reference the data in id_ret. */
+/* Emit image data into the given surface, providing a resource that
+ * can be used to reference the data in image_ret. */
static cairo_status_t
-emit_image (cairo_pdf_document_t *document,
+emit_image (cairo_pdf_surface_t *surface,
cairo_image_surface_t *image,
cairo_pdf_resource_t *image_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
- cairo_output_stream_t *output = document->output_stream;
char *rgb, *compressed;
unsigned long rgb_size, compressed_size;
pixman_bits_t *pixel;
@@ -756,7 +738,7 @@ emit_image (cairo_pdf_document_t *docume
/* These are the only image formats we currently support, (which
* makes things a lot simpler here). This is enforeced through
* _analyze_operation which only accept source surfaces of
- * CONTENT_COLOR or CONTENT_COLOR_ALPHA.
+ * CONTENT_COLOR or CONTENT_COLOR_ALPHA.
*/
assert (image->format == CAIRO_FORMAT_RGB24 || image->format == CAIRO_FORMAT_ARGB32);
@@ -805,7 +787,7 @@ emit_image (cairo_pdf_document_t *docume
need_smask = FALSE;
if (image->format == CAIRO_FORMAT_ARGB32) {
- status = emit_smask (document, image, &smask);
+ status = emit_smask (surface, image, &smask);
if (status)
goto CLEANUP_COMPRESSED;
@@ -823,21 +805,21 @@ emit_image (cairo_pdf_document_t *docume
if (need_smask)
- *image_ret = _cairo_pdf_document_open_stream (document,
- IMAGE_DICTIONARY
- " /SMask %d 0 R\r\n",
- image->width, image->height,
- smask.id);
+ *image_ret = _cairo_pdf_surface_open_stream (surface,
+ IMAGE_DICTIONARY
+ " /SMask %d 0 R\r\n",
+ image->width, image->height,
+ smask.id);
else
- *image_ret = _cairo_pdf_document_open_stream (document,
- IMAGE_DICTIONARY,
- image->width, image->height);
+ *image_ret = _cairo_pdf_surface_open_stream (surface,
+ IMAGE_DICTIONARY,
+ image->width, image->height);
#undef IMAGE_DICTIONARY
- _cairo_output_stream_write (output, compressed, compressed_size);
- _cairo_output_stream_printf (output, "\r\n");
- _cairo_pdf_document_close_stream (document);
+ _cairo_output_stream_write (surface->output, compressed, compressed_size);
+ _cairo_output_stream_printf (surface->output, "\r\n");
+ _cairo_pdf_surface_close_stream (surface);
CLEANUP_COMPRESSED:
free (compressed);
@@ -851,15 +833,13 @@ static cairo_status_t
emit_solid_pattern (cairo_pdf_surface_t *surface,
cairo_solid_pattern_t *pattern)
{
- cairo_pdf_document_t *document = surface->document;
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t alpha;
alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha);
/* With some work, we could separate the stroking
* or non-stroking color here as actually needed. */
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"%f %f %f RG "
"%f %f %f rg "
"/a%d gs\r\n",
@@ -875,11 +855,9 @@ emit_solid_pattern (cairo_pdf_surface_t
}
static cairo_status_t
-emit_surface_pattern (cairo_pdf_surface_t *dst,
+emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_surface_pattern_t *pattern)
{
- cairo_pdf_document_t *document = dst->document;
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t stream;
cairo_image_surface_t *image;
void *image_extra;
@@ -888,21 +866,21 @@ emit_surface_pattern (cairo_pdf_surface_
cairo_matrix_t cairo_p2d, pdf_p2d;
cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base);
int xstep, ystep;
- cairo_rectangle_fixed_t dst_extents;
+ cairo_rectangle_fixed_t surface_extents;
/* XXX: Should do something clever here for PDF source surfaces ? */
- _cairo_pdf_surface_pause_content_stream (dst);
+ _cairo_pdf_surface_pause_content_stream (surface);
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
if (status)
return status;
- status = emit_image (dst->document, image, &image_resource);
+ status = emit_image (surface, image, &image_resource);
if (status)
goto BAIL;
- _cairo_surface_get_extents (&dst->base, &dst_extents);
+ _cairo_surface_get_extents (&surface->base, &surface_extents);
/* In PDF, (as far as I can tell), all patterns are repeating. So
* we support cairo's EXTEND_NONE semantics by setting the repeat
@@ -912,8 +890,8 @@ emit_surface_pattern (cairo_pdf_surface_
*/
switch (extend) {
case CAIRO_EXTEND_NONE:
- xstep = MAX(image->width, dst_extents.width);
- ystep = MAX(image->height, dst_extents.height);
+ xstep = MAX(image->width, surface_extents.width);
+ ystep = MAX(image->height, surface_extents.height);
break;
case CAIRO_EXTEND_REPEAT:
xstep = image->width;
@@ -956,44 +934,44 @@ emit_surface_pattern (cairo_pdf_surface_
cairo_matrix_invert (&cairo_p2d);
cairo_matrix_init_identity (&pdf_p2d);
- cairo_matrix_translate (&pdf_p2d, 0.0, dst_extents.height);
+ cairo_matrix_translate (&pdf_p2d, 0.0, surface_extents.height);
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
cairo_matrix_translate (&pdf_p2d, 0.0, image->height);
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
- stream = _cairo_pdf_document_open_stream (document,
- " /BBox [0 0 %d %d]\r\n"
- " /XStep %d\r\n"
- " /YStep %d\r\n"
- " /PatternType 1\r\n"
- " /TilingType 1\r\n"
- " /PaintType 1\r\n"
- " /Matrix [ %f %f %f %f %f %f ]\r\n"
- " /Resources << /XObject << /res%d %d 0 R >> >>\r\n",
- image->width, image->height,
- xstep, ystep,
- pdf_p2d.xx, pdf_p2d.yx,
- pdf_p2d.xy, pdf_p2d.yy,
- pdf_p2d.x0, pdf_p2d.y0,
- image_resource.id,
- image_resource.id);
+ stream = _cairo_pdf_surface_open_stream (surface,
+ " /BBox [0 0 %d %d]\r\n"
+ " /XStep %d\r\n"
+ " /YStep %d\r\n"
+ " /PatternType 1\r\n"
+ " /TilingType 1\r\n"
+ " /PaintType 1\r\n"
+ " /Matrix [ %f %f %f %f %f %f ]\r\n"
+ " /Resources << /XObject << /res%d %d 0 R >> >>\r\n",
+ image->width, image->height,
+ xstep, ystep,
+ pdf_p2d.xx, pdf_p2d.yx,
+ pdf_p2d.xy, pdf_p2d.yy,
+ pdf_p2d.x0, pdf_p2d.y0,
+ image_resource.id,
+ image_resource.id);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"q %d 0 0 %d 0 0 cm /res%d Do Q\r\n",
image->width, image->height,
image_resource.id);
- _cairo_pdf_document_close_stream (document);
+ _cairo_pdf_surface_close_stream (surface);
- _cairo_pdf_surface_resume_content_stream (dst);
+ _cairo_pdf_surface_resume_content_stream (surface);
- _cairo_pdf_surface_add_pattern (dst, stream);
+ _cairo_pdf_surface_add_pattern (surface, stream);
- alpha = _cairo_pdf_surface_add_alpha (dst, 1.0);
+ alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
/* With some work, we could separate the stroking
* or non-stroking pattern here as actually needed. */
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"/Pattern CS /res%d SCN "
"/Pattern cs /res%d scn "
"/a%d gs\r\n",
@@ -1005,7 +983,6 @@ emit_surface_pattern (cairo_pdf_surface_
return status;
}
-
typedef struct _cairo_pdf_color_stop {
double offset;
cairo_pdf_resource_t gradient;
@@ -1013,14 +990,13 @@ typedef struct _cairo_pdf_color_stop {
} cairo_pdf_color_stop_t;
static cairo_pdf_resource_t
-emit_linear_colorgradient (cairo_pdf_document_t *document,
- cairo_pdf_color_stop_t *stop1,
- cairo_pdf_color_stop_t *stop2)
-{
- cairo_output_stream_t *output = document->output_stream;
- cairo_pdf_resource_t function = _cairo_pdf_document_new_object (document);
-
- _cairo_output_stream_printf (output,
+emit_linear_colorgradient (cairo_pdf_surface_t *surface,
+ cairo_pdf_color_stop_t *stop1,
+ cairo_pdf_color_stop_t *stop2)
+{
+ cairo_pdf_resource_t function = _cairo_pdf_surface_new_object (surface);
+
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /FunctionType 0\r\n"
" /Domain [ 0 1 ]\r\n"
@@ -1032,54 +1008,70 @@ emit_linear_colorgradient (cairo_pdf_doc
"stream\r\n",
function.id);
- _cairo_output_stream_write (output, stop1->color_char, 3);
- _cairo_output_stream_write (output, stop2->color_char, 3);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_write (surface->output, stop1->color_char, 3);
+ _cairo_output_stream_write (surface->output, stop2->color_char, 3);
+ _cairo_output_stream_printf (surface->output,
"\r\n"
"endstream\r\n"
"endobj\r\n");
-
+
return function;
}
static cairo_pdf_resource_t
-emit_stiched_colorgradient (cairo_pdf_document_t *document,
+emit_stiched_colorgradient (cairo_pdf_surface_t *surface,
unsigned int n_stops,
cairo_pdf_color_stop_t stops[])
{
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t function;
unsigned int i;
-
+
/* emit linear gradients between pairs of subsequent stops... */
for (i = 0; i < n_stops-1; i++) {
- stops[i].gradient = emit_linear_colorgradient (document,
- &stops[i],
+ stops[i].gradient = emit_linear_colorgradient (surface,
+ &stops[i],
&stops[i+1]);
}
-
+
/* ... and stich them together */
- function = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ function = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /FunctionType 3\r\n"
- " /Domain [ 0 1 ]\r\n"
- " /Functions [ ",
+ " /Domain [ 0 1 ]\r\n",
function.id);
+
+ _cairo_output_stream_printf (surface->output,
+ " /Functions [ ");
for (i = 0; i < n_stops-1; i++)
- _cairo_output_stream_printf (output, "%d 0 R ", stops[i].gradient.id);
- _cairo_output_stream_printf (output,
- "]\r\n"
+ {
+ _cairo_output_stream_printf (surface->output,
+ "%d 0 R ", stops[i].gradient.id);
+ }
+ _cairo_output_stream_printf (surface->output,
+ "]\r\n");
+
+ _cairo_output_stream_printf (surface->output,
" /Bounds [ ");
for (i = 1; i < n_stops-1; i++)
- _cairo_output_stream_printf (output, "%f ", stops[i].offset);
- _cairo_output_stream_printf (output,
- "]\r\n"
+ {
+ _cairo_output_stream_printf (surface->output,
+ "%f ", stops[i].offset);
+ }
+ _cairo_output_stream_printf (surface->output,
+ "]\r\n");
+
+ _cairo_output_stream_printf (surface->output,
" /Encode [ ");
for (i = 1; i < n_stops; i++)
- _cairo_output_stream_printf (output, "0 1 ");
- _cairo_output_stream_printf (output,
- "]\r\n"
+ {
+ _cairo_output_stream_printf (surface->output,
+ "0 1 ");
+ }
+ _cairo_output_stream_printf (surface->output,
+ "]\r\n");
+
+ _cairo_output_stream_printf (surface->output,
">>\r\n"
"endobj\r\n");
@@ -1091,13 +1083,12 @@ emit_stiched_colorgradient (cairo_pdf_do
static cairo_pdf_resource_t
emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern)
{
- cairo_pdf_document_t *document = surface->document;
cairo_pdf_resource_t function;
cairo_pdf_color_stop_t *allstops, *stops;
unsigned int n_stops;
unsigned int i;
- function = _cairo_pdf_document_new_object (document);
+ function = _cairo_pdf_surface_new_object (surface);
allstops = malloc ((pattern->n_stops + 2) * sizeof (cairo_pdf_color_stop_t));
if (allstops == NULL) {
@@ -1107,7 +1098,7 @@ emit_pattern_stops (cairo_pdf_surface_t
}
stops = &allstops[1];
n_stops = pattern->n_stops;
-
+
for (i = 0; i < pattern->n_stops; i++) {
stops[i].color_char[0] = pattern->stops[i].color.red >> 8;
stops[i].color_char[1] = pattern->stops[i].color.green >> 8;
@@ -1125,21 +1116,21 @@ emit_pattern_stops (cairo_pdf_surface_t
n_stops++;
}
if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILLON) {
- memcpy (&stops[n_stops],
- &stops[n_stops - 1],
+ memcpy (&stops[n_stops],
+ &stops[n_stops - 1],
sizeof (cairo_pdf_color_stop_t));
stops[n_stops].offset = 1.0;
n_stops++;
}
-
+
if (n_stops == 2) {
/* no need for stiched function */
- function = emit_linear_colorgradient (document, &stops[0], &stops[1]);
+ function = emit_linear_colorgradient (surface, &stops[0], &stops[1]);
} else {
/* multiple stops: stich. XXX possible optimization: regulary spaced
* stops do not require stiching. XXX */
- function = emit_stiched_colorgradient (document,
- n_stops,
+ function = emit_stiched_colorgradient (surface,
+ n_stops,
stops);
}
@@ -1151,8 +1142,6 @@ emit_pattern_stops (cairo_pdf_surface_t
static cairo_status_t
emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *pattern)
{
- cairo_pdf_document_t *document = surface->document;
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t function, pattern_resource, alpha;
double x0, y0, x1, y1;
cairo_matrix_t p2u;
@@ -1173,8 +1162,8 @@ emit_linear_pattern (cairo_pdf_surface_t
y1 = _cairo_fixed_to_double (pattern->gradient.p2.y);
cairo_matrix_transform_point (&p2u, &x1, &y1);
- pattern_resource = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ pattern_resource = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /Pattern\r\n"
" /PatternType 2\r\n"
@@ -1189,10 +1178,10 @@ emit_linear_pattern (cairo_pdf_surface_t
">>\r\n"
"endobj\r\n",
pattern_resource.id,
- document->height,
+ surface->height,
x0, y0, x1, y1,
function.id);
-
+
_cairo_pdf_surface_add_pattern (surface, pattern_resource);
alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
@@ -1200,7 +1189,7 @@ emit_linear_pattern (cairo_pdf_surface_t
/* Use pattern */
/* With some work, we could separate the stroking
* or non-stroking pattern here as actually needed. */
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"/Pattern CS /res%d SCN "
"/Pattern cs /res%d scn "
"/a%d gs\r\n",
@@ -1212,12 +1201,10 @@ emit_linear_pattern (cairo_pdf_surface_t
return CAIRO_STATUS_SUCCESS;
}
-
+
static cairo_status_t
emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *pattern)
{
- cairo_pdf_document_t *document = surface->document;
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t function, pattern_resource, alpha;
double x0, y0, x1, y1, r0, r1;
cairo_matrix_t p2u;
@@ -1251,8 +1238,8 @@ emit_radial_pattern (cairo_pdf_surface_t
* to infinity. Setting extend=true in PDF gives the cairo default
* behavoir, not yet sure how to implement the cairo mirror and
* repeat behaviour. */
- pattern_resource = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ pattern_resource = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /Pattern\r\n"
" /PatternType 2\r\n"
@@ -1267,10 +1254,10 @@ emit_radial_pattern (cairo_pdf_surface_t
">>\r\n"
"endobj\r\n",
pattern_resource.id,
- document->height,
+ surface->height,
x0, y0, r0, x1, y1, r1,
function.id);
-
+
_cairo_pdf_surface_add_pattern (surface, pattern_resource);
alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
@@ -1278,7 +1265,7 @@ emit_radial_pattern (cairo_pdf_surface_t
/* Use pattern */
/* With some work, we could separate the stroking
* or non-stroking pattern here as actually needed. */
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"/Pattern CS /res%d SCN "
"/Pattern cs /res%d scn "
"/a%d gs\r\n",
@@ -1316,22 +1303,22 @@ emit_pattern (cairo_pdf_surface_t *surfa
static cairo_status_t
_cairo_pdf_path_move_to (void *closure, cairo_point_t *point)
{
- cairo_output_stream_t *output_stream = closure;
+ cairo_output_stream_t *output = closure;
- _cairo_output_stream_printf (output_stream,
+ _cairo_output_stream_printf (output,
"%f %f m ",
_cairo_fixed_to_double (point->x),
_cairo_fixed_to_double (point->y));
-
+
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_pdf_path_line_to (void *closure, cairo_point_t *point)
{
- cairo_output_stream_t *output_stream = closure;
-
- _cairo_output_stream_printf (output_stream,
+ cairo_output_stream_t *output = closure;
+
+ _cairo_output_stream_printf (output,
"%f %f l ",
_cairo_fixed_to_double (point->x),
_cairo_fixed_to_double (point->y));
@@ -1345,9 +1332,9 @@ _cairo_pdf_path_curve_to (void
cairo_point_t *c,
cairo_point_t *d)
{
- cairo_output_stream_t *output_stream = closure;
+ cairo_output_stream_t *output = closure;
- _cairo_output_stream_printf (output_stream,
+ _cairo_output_stream_printf (output,
"%f %f %f %f %f %f c ",
_cairo_fixed_to_double (b->x),
_cairo_fixed_to_double (b->y),
@@ -1355,16 +1342,16 @@ _cairo_pdf_path_curve_to (void
_cairo_fixed_to_double (c->y),
_cairo_fixed_to_double (d->x),
_cairo_fixed_to_double (d->y));
-
+
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_pdf_path_close_path (void *closure)
{
- cairo_output_stream_t *output_stream = closure;
-
- _cairo_output_stream_printf (output_stream,
+ cairo_output_stream_t *output = closure;
+
+ _cairo_output_stream_printf (output,
"h\r\n");
return CAIRO_STATUS_SUCCESS;
@@ -1374,19 +1361,17 @@ static cairo_int_status_t
_cairo_pdf_surface_copy_page (void *abstract_surface)
{
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
- return _cairo_pdf_document_add_page (document, surface);
+ return _cairo_pdf_surface_write_page (surface);
}
static cairo_int_status_t
_cairo_pdf_surface_show_page (void *abstract_surface)
{
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
cairo_int_status_t status;
- status = _cairo_pdf_document_add_page (document, surface);
+ status = _cairo_pdf_surface_write_page (surface);
if (status)
return status;
@@ -1415,7 +1400,7 @@ _cairo_pdf_surface_get_extents (void
}
typedef struct _pdf_stroke {
- cairo_output_stream_t *output_stream;
+ cairo_output_stream_t *output;
cairo_matrix_t *ctm_inverse;
} pdf_stroke_t;
@@ -1428,7 +1413,7 @@ _cairo_pdf_stroke_move_to (void *closure
cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y);
- _cairo_output_stream_printf (stroke->output_stream,
+ _cairo_output_stream_printf (stroke->output,
"%f %f m ", x, y);
return CAIRO_STATUS_SUCCESS;
@@ -1443,7 +1428,7 @@ _cairo_pdf_stroke_line_to (void *closure
cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y);
- _cairo_output_stream_printf (stroke->output_stream,
+ _cairo_output_stream_printf (stroke->output,
"%f %f l ", x, y);
return CAIRO_STATUS_SUCCESS;
}
@@ -1466,7 +1451,7 @@ _cairo_pdf_stroke_curve_to (void
cairo_matrix_transform_point (stroke->ctm_inverse, &cx, &cy);
cairo_matrix_transform_point (stroke->ctm_inverse, &dx, &dy);
- _cairo_output_stream_printf (stroke->output_stream,
+ _cairo_output_stream_printf (stroke->output,
"%f %f %f %f %f %f c ",
bx, by, cx, cy, dx, dy);
return CAIRO_STATUS_SUCCESS;
@@ -1477,34 +1462,32 @@ _cairo_pdf_stroke_close_path (void *clos
{
pdf_stroke_t *stroke = closure;
- _cairo_output_stream_printf (stroke->output_stream,
+ _cairo_output_stream_printf (stroke->output,
"h\r\n");
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
-_cairo_pdf_surface_intersect_clip_path (void *dst,
+_cairo_pdf_surface_intersect_clip_path (void *abstract_surface,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias)
{
- cairo_pdf_surface_t *surface = dst;
- cairo_pdf_document_t *document = surface->document;
- cairo_output_stream_t *output = document->output_stream;
+ cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
const char *pdf_operator;
if (path == NULL) {
if (surface->has_clip)
- _cairo_output_stream_printf (output, "Q\r\n");
+ _cairo_output_stream_printf (surface->output, "Q\r\n");
surface->has_clip = FALSE;
return CAIRO_STATUS_SUCCESS;
}
if (!surface->has_clip) {
- _cairo_output_stream_printf (output, "q ");
+ _cairo_output_stream_printf (surface->output, "q ");
surface->has_clip = TRUE;
}
@@ -1514,7 +1497,7 @@ _cairo_pdf_surface_intersect_clip_path (
_cairo_pdf_path_line_to,
_cairo_pdf_path_curve_to,
_cairo_pdf_path_close_path,
- document->output_stream);
+ surface->output);
switch (fill_rule) {
case CAIRO_FILL_RULE_WINDING:
@@ -1527,7 +1510,7 @@ _cairo_pdf_surface_intersect_clip_path (
ASSERT_NOT_REACHED;
}
- _cairo_output_stream_printf (document->output_stream,
+ _cairo_output_stream_printf (surface->output,
"%s n\r\n",
pdf_operator);
@@ -1544,51 +1527,13 @@ _cairo_pdf_surface_get_font_options (voi
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
}
-static cairo_pdf_document_t *
-_cairo_pdf_document_create (cairo_output_stream_t *output_stream,
- double width,
- double height)
-{
- cairo_pdf_document_t *document;
-
- document = malloc (sizeof (cairo_pdf_document_t));
- if (document == NULL)
- return NULL;
-
- document->output_stream = output_stream;
- document->ref_count = 1;
- document->owner = NULL;
- document->finished = FALSE;
- document->width = width;
- document->height = height;
- document->x_dpi = DEFAULT_DPI;
- document->y_dpi = DEFAULT_DPI;
-
- _cairo_array_init (&document->objects, sizeof (cairo_pdf_object_t));
- _cairo_array_init (&document->pages, sizeof (cairo_pdf_resource_t));
- document->next_available_resource.id = 1;
-
- document->current_stream.active = FALSE;
-
- document->pages_resource = _cairo_pdf_document_new_object (document);
-
- _cairo_array_init (&document->fonts, sizeof (cairo_font_subset_t *));
-
- /* Document header */
- _cairo_output_stream_printf (output_stream,
- "%%PDF-1.4\r\n");
-
- return document;
-}
-
static cairo_pdf_resource_t
-_cairo_pdf_document_write_info (cairo_pdf_document_t *document)
+_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface)
{
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t info;
- info = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ info = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Creator (cairographics.org)\r\n"
" /Producer (cairographics.org)\r\n"
@@ -1600,42 +1545,41 @@ _cairo_pdf_document_write_info (cairo_pd
}
static void
-_cairo_pdf_document_write_pages (cairo_pdf_document_t *document)
+_cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
{
- cairo_output_stream_t *stream = document->output_stream;
cairo_pdf_resource_t page;
int num_pages, i;
- _cairo_pdf_document_update_object (document, document->pages_resource);
- _cairo_output_stream_printf (stream,
+ _cairo_pdf_surface_update_object (surface, surface->pages_resource);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /Pages\r\n"
" /Kids [ ",
- document->pages_resource.id);
-
- num_pages = _cairo_array_num_elements (&document->pages);
+ surface->pages_resource.id);
+
+ num_pages = _cairo_array_num_elements (&surface->pages);
for (i = 0; i < num_pages; i++) {
- _cairo_array_copy_element (&document->pages, i, &page);
- _cairo_output_stream_printf (stream, "%d 0 R ", page.id);
+ _cairo_array_copy_element (&surface->pages, i, &page);
+ _cairo_output_stream_printf (surface->output, "%d 0 R ", page.id);
}
- _cairo_output_stream_printf (stream, "]\r\n");
- _cairo_output_stream_printf (stream, " /Count %d\r\n", num_pages);
+ _cairo_output_stream_printf (surface->output, "]\r\n");
+ _cairo_output_stream_printf (surface->output, " /Count %d\r\n", num_pages);
/* TODO: Figure out wich other defaults to be inherited by /Page
* objects. */
- _cairo_output_stream_printf (stream,
+ _cairo_output_stream_printf (surface->output,
" /MediaBox [ 0 0 %f %f ]\r\n"
">>\r\n"
"endobj\r\n",
- document->width,
- document->height);
+ surface->width,
+ surface->height);
}
+#if 0
static cairo_status_t
-_cairo_pdf_document_write_fonts (cairo_pdf_document_t *document)
+_cairo_pdf_surface_write_fonts (cairo_pdf_surface_t *surface)
{
- cairo_output_stream_t *output = document->output_stream;
cairo_font_subset_t *font;
cairo_pdf_resource_t font_resource;
int num_fonts, i, j;
@@ -1645,9 +1589,9 @@ _cairo_pdf_document_write_fonts (cairo_p
cairo_pdf_resource_t stream, descriptor;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
- num_fonts = _cairo_array_num_elements (&document->fonts);
+ num_fonts = _cairo_array_num_elements (&surface->fonts);
for (i = 0; i < num_fonts; i++) {
- _cairo_array_copy_element (&document->fonts, i, &font);
+ _cairo_array_copy_element (&surface->fonts, i, &font);
status = _cairo_font_subset_generate (font, &data, &data_size);
if (status)
@@ -1659,8 +1603,8 @@ _cairo_pdf_document_write_fonts (cairo_p
goto fail;
}
- stream = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ stream = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Filter /FlateDecode\r\n"
" /Length %lu\r\n"
@@ -1670,15 +1614,15 @@ _cairo_pdf_document_write_fonts (cairo_p
stream.id,
compressed_size,
data_size);
- _cairo_output_stream_write (output, compressed, compressed_size);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_write (surface->output, compressed, compressed_size);
+ _cairo_output_stream_printf (surface->output,
"\r\n"
"endstream\r\n"
"endobj\r\n");
free (compressed);
- descriptor = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ descriptor = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /FontDescriptor\r\n"
" /FontName /7%s\r\n"
@@ -1704,8 +1648,8 @@ _cairo_pdf_document_write_fonts (cairo_p
stream.id);
font_resource.id = font->font_id;
- _cairo_pdf_document_update_object (document, font_resource);
- _cairo_output_stream_printf (output,
+ _cairo_pdf_surface_update_object (surface, font_resource);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /Font\r\n"
" /Subtype /TrueType\r\n"
@@ -1719,15 +1663,15 @@ _cairo_pdf_document_write_fonts (cairo_p
font->num_glyphs,
descriptor.id);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"[");
for (j = 0; j < font->num_glyphs; j++)
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" %d",
font->widths[j]);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" ]\r\n"
">>\r\n"
"endobj\r\n");
@@ -1738,245 +1682,158 @@ _cairo_pdf_document_write_fonts (cairo_p
return status;
}
+#endif
static cairo_pdf_resource_t
-_cairo_pdf_document_write_catalog (cairo_pdf_document_t *document)
+_cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface)
{
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t catalog;
- catalog = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ catalog = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /Catalog\r\n"
- " /Pages %d 0 R\r\n"
+ " /Pages %d 0 R\r\n"
">>\r\n"
"endobj\r\n",
catalog.id,
- document->pages_resource.id);
+ surface->pages_resource.id);
return catalog;
}
static long
-_cairo_pdf_document_write_xref (cairo_pdf_document_t *document)
+_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface)
{
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_object_t *object;
int num_objects, i;
long offset;
char buffer[11];
- num_objects = _cairo_array_num_elements (&document->objects);
+ num_objects = _cairo_array_num_elements (&surface->objects);
- offset = _cairo_output_stream_get_position (output);
- _cairo_output_stream_printf (output,
+ offset = _cairo_output_stream_get_position (surface->output);
+ _cairo_output_stream_printf (surface->output,
"xref\r\n"
"%d %d\r\n",
0, num_objects + 1);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"0000000000 65535 f\r\n");
for (i = 0; i < num_objects; i++) {
- object = _cairo_array_index (&document->objects, i);
+ object = _cairo_array_index (&surface->objects, i);
snprintf (buffer, sizeof buffer, "%010ld", object->offset);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
"%s 00000 n\r\n", buffer);
}
return offset;
}
-static cairo_pdf_document_t *
-_cairo_pdf_document_reference (cairo_pdf_document_t *document)
-{
- document->ref_count++;
-
- return document;
-}
-
-static void
-_cairo_pdf_document_destroy (cairo_pdf_document_t *document)
-{
- document->ref_count--;
- if (document->ref_count > 0)
- return;
-
- _cairo_pdf_document_finish (document);
-
- free (document);
-}
-
-static cairo_status_t
-_cairo_pdf_document_finish (cairo_pdf_document_t *document)
-{
- cairo_status_t status;
- cairo_output_stream_t *output = document->output_stream;
- long offset;
- cairo_pdf_resource_t info, catalog;
-
- if (document->finished)
- return CAIRO_STATUS_SUCCESS;
-
- _cairo_pdf_document_close_stream (document);
- _cairo_pdf_document_write_pages (document);
- _cairo_pdf_document_write_fonts (document);
- info = _cairo_pdf_document_write_info (document);
- catalog = _cairo_pdf_document_write_catalog (document);
- offset = _cairo_pdf_document_write_xref (document);
-
- _cairo_output_stream_printf (output,
- "trailer\r\n"
- "<< /Size %d\r\n"
- " /Root %d 0 R\r\n"
- " /Info %d 0 R\r\n"
- ">>\r\n",
- document->next_available_resource.id,
- catalog.id,
- info.id);
-
- _cairo_output_stream_printf (output,
- "startxref\r\n"
- "%ld\r\n"
- "%%%%EOF\r\n",
- offset);
-
- status = _cairo_output_stream_get_status (output);
- _cairo_output_stream_destroy (output);
-
- _cairo_array_fini (&document->objects);
- _cairo_array_fini (&document->pages);
- _cairo_array_fini (&document->fonts);
-
- document->finished = TRUE;
-
- return status;
-}
-
static cairo_status_t
-_cairo_pdf_document_add_page (cairo_pdf_document_t *document,
- cairo_pdf_surface_t *surface)
+_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
{
cairo_status_t status;
cairo_pdf_resource_t *res;
- cairo_output_stream_t *output = document->output_stream;
cairo_pdf_resource_t page;
double alpha;
cairo_pdf_resource_t stream;
int num_streams, num_alphas, num_resources, i;
- assert (!document->finished);
-
if (surface->has_clip) {
- _cairo_output_stream_printf (output, "Q\r\n");
+ _cairo_output_stream_printf (surface->output, "Q\r\n");
surface->has_clip = FALSE;
}
- _cairo_pdf_document_close_stream (document);
+ _cairo_pdf_surface_close_stream (surface);
- page = _cairo_pdf_document_new_object (document);
- _cairo_output_stream_printf (output,
+ page = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /Page\r\n"
" /Parent %d 0 R\r\n",
page.id,
- document->pages_resource.id);
+ surface->pages_resource.id);
- if (surface->width != document->width ||
- surface->height != document->height)
+ if (surface->width != surface->width ||
+ surface->height != surface->height)
{
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /MediaBox [ 0 0 %f %f ]\r\n",
surface->width,
surface->height);
}
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /Contents [");
num_streams = _cairo_array_num_elements (&surface->streams);
for (i = 0; i < num_streams; i++) {
_cairo_array_copy_element (&surface->streams, i, &stream);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" %d 0 R",
stream.id);
}
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" ]\r\n");
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /Resources <<\r\n");
- num_resources = _cairo_array_num_elements (&surface->fonts);
- if (num_resources > 0) {
- _cairo_output_stream_printf (output,
- " /Font <<");
-
- for (i = 0; i < num_resources; i++) {
- res = _cairo_array_index (&surface->fonts, i);
- _cairo_output_stream_printf (output,
- " /res%d %d 0 R",
- res->id, res->id);
- }
-
- _cairo_output_stream_printf (output,
- " >>\r\n");
- }
-
num_alphas = _cairo_array_num_elements (&surface->alphas);
if (num_alphas > 0) {
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /ExtGState <<\r\n");
for (i = 0; i < num_alphas; i++) {
/* With some work, we could separate the stroking
* or non-stroking alpha here as actually needed. */
_cairo_array_copy_element (&surface->alphas, i, &alpha);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /a%d << /CA %f /ca %f >>\r\n",
i, alpha, alpha);
}
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" >>\r\n");
}
-
+
num_resources = _cairo_array_num_elements (&surface->patterns);
if (num_resources > 0) {
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /Pattern <<");
for (i = 0; i < num_resources; i++) {
res = _cairo_array_index (&surface->patterns, i);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /res%d %d 0 R",
res->id, res->id);
}
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" >>\r\n");
}
num_resources = _cairo_array_num_elements (&surface->xobjects);
if (num_resources > 0) {
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /XObject <<");
for (i = 0; i < num_resources; i++) {
res = _cairo_array_index (&surface->xobjects, i);
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" /res%d %d 0 R",
res->id, res->id);
}
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" >>\r\n");
}
- _cairo_output_stream_printf (output,
+ _cairo_output_stream_printf (surface->output,
" >>\r\n"
">>\r\n"
"endobj\r\n");
- status = _cairo_array_append (&document->pages, &page);
+ status = _cairo_array_append (&surface->pages, &page);
if (status)
return status;
@@ -2022,7 +1879,7 @@ _pattern_supported (cairo_pattern_t *pat
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
return _surface_pattern_supported ((cairo_surface_pattern_t *) pattern);
-
+
return FALSE;
}
@@ -2059,7 +1916,6 @@ _cairo_pdf_surface_paint (void *abstra
cairo_pattern_t *source)
{
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
cairo_status_t status;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
@@ -2079,11 +1935,11 @@ _cairo_pdf_surface_paint (void *abstra
if (status)
return status;
- _cairo_output_stream_printf (document->output_stream,
+ _cairo_output_stream_printf (surface->output,
"0 0 %f %f re f\r\n",
surface->width, surface->height);
- return _cairo_output_stream_get_status (document->output_stream);
+ return _cairo_output_stream_get_status (surface->output);
}
static cairo_int_status_t
@@ -2136,35 +1992,34 @@ _cairo_pdf_line_join (cairo_line_join_t
static cairo_status_t
_cairo_pdf_surface_emit_stroke_style (cairo_pdf_surface_t *surface,
- cairo_output_stream_t *stream,
cairo_stroke_style_t *style)
{
- _cairo_output_stream_printf (stream,
+ _cairo_output_stream_printf (surface->output,
"%f w\r\n",
style->line_width);
- _cairo_output_stream_printf (stream,
+ _cairo_output_stream_printf (surface->output,
"%d J\r\n",
_cairo_pdf_line_cap (style->line_cap));
- _cairo_output_stream_printf (stream,
+ _cairo_output_stream_printf (surface->output,
"%d j\r\n",
_cairo_pdf_line_join (style->line_join));
if (style->num_dashes) {
int d;
- _cairo_output_stream_printf (stream, "[");
+ _cairo_output_stream_printf (surface->output, "[");
for (d = 0; d < style->num_dashes; d++)
- _cairo_output_stream_printf (stream, " %f", style->dash[d]);
- _cairo_output_stream_printf (stream, "] %f d\r\n",
+ _cairo_output_stream_printf (surface->output, " %f", style->dash[d]);
+ _cairo_output_stream_printf (surface->output, "] %f d\r\n",
style->dash_offset);
}
- _cairo_output_stream_printf (stream,
+ _cairo_output_stream_printf (surface->output,
"%f M ",
style->miter_limit);
- return _cairo_output_stream_get_status (stream);
+ return _cairo_output_stream_get_status (surface->output);
}
static cairo_int_status_t
@@ -2179,7 +2034,6 @@ _cairo_pdf_surface_stroke (void *abstr
cairo_antialias_t antialias)
{
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
pdf_stroke_t stroke;
cairo_status_t status;
@@ -2198,7 +2052,7 @@ _cairo_pdf_surface_stroke (void *abstr
if (status)
return status;
- stroke.output_stream = document->output_stream;
+ stroke.output = surface->output;
stroke.ctm_inverse = ctm_inverse;
status = _cairo_path_fixed_interpret (path,
CAIRO_DIRECTION_FORWARD,
@@ -2207,19 +2061,18 @@ _cairo_pdf_surface_stroke (void *abstr
_cairo_pdf_stroke_curve_to,
_cairo_pdf_stroke_close_path,
&stroke);
-
- _cairo_output_stream_printf (document->output_stream,
+
+ _cairo_output_stream_printf (surface->output,
"q %f %f %f %f %f %f cm\r\n",
ctm->xx, ctm->yx, ctm->xy, ctm->yy,
ctm->x0, ctm->y0);
status = _cairo_pdf_surface_emit_stroke_style (surface,
- document->output_stream,
style);
if (status)
return status;
- _cairo_output_stream_printf (document->output_stream, "S Q\r\n");
+ _cairo_output_stream_printf (surface->output, "S Q\r\n");
return status;
}
@@ -2234,7 +2087,6 @@ _cairo_pdf_surface_fill (void *abstrac
cairo_antialias_t antialias)
{
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
const char *pdf_operator;
cairo_status_t status;
@@ -2259,7 +2111,7 @@ _cairo_pdf_surface_fill (void *abstrac
_cairo_pdf_path_line_to,
_cairo_pdf_path_curve_to,
_cairo_pdf_path_close_path,
- document->output_stream);
+ surface->output);
switch (fill_rule) {
case CAIRO_FILL_RULE_WINDING:
@@ -2272,7 +2124,7 @@ _cairo_pdf_surface_fill (void *abstrac
ASSERT_NOT_REACHED;
}
- _cairo_output_stream_printf (document->output_stream,
+ _cairo_output_stream_printf (surface->output,
"%s\r\n",
pdf_operator);
diff-tree d84a1cac1cc2da8a34fb6aa91c3c4f4058527207 (from b7e9506707878367493a8a45c74bb6eb048b7e88)
Author: Carl Worth <cworth at cworth.org>
Date: Fri May 12 13:31:12 2006 -0700
PDF: Use cairo_pdf_resource_t more consistently.
Eliminate the named structure cairo_pdf_stream_t. This structure was
being dynamically allocated, passed around, and leaked when only an ID
was actually needed to be passed around.
Similarly, many other uses of PDF resources were passing bare unsigned
int types rather than the safer and more legible cairo_pdf_resource_t.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 9bf1ea8..d0e5ebb 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -88,7 +88,6 @@
typedef struct cairo_pdf_object cairo_pdf_object_t;
typedef struct cairo_pdf_resource cairo_pdf_resource_t;
-typedef struct cairo_pdf_stream cairo_pdf_stream_t;
typedef struct cairo_pdf_document cairo_pdf_document_t;
typedef struct cairo_pdf_surface cairo_pdf_surface_t;
@@ -100,12 +99,6 @@ struct cairo_pdf_resource {
unsigned int id;
};
-struct cairo_pdf_stream {
- unsigned int id;
- unsigned int length_id;
- long start_offset;
-};
-
struct cairo_pdf_document {
cairo_output_stream_t *output_stream;
unsigned long ref_count;
@@ -117,10 +110,15 @@ struct cairo_pdf_document {
double x_dpi;
double y_dpi;
- unsigned int next_available_id;
- unsigned int pages_id;
+ cairo_pdf_resource_t next_available_resource;
+ cairo_pdf_resource_t pages_resource;
- cairo_pdf_stream_t *current_stream;
+ struct {
+ cairo_bool_t active;
+ cairo_pdf_resource_t self;
+ cairo_pdf_resource_t length;
+ long start_offset;
+ } current_stream;
cairo_array_t objects;
cairo_array_t pages;
@@ -135,7 +133,6 @@ struct cairo_pdf_surface {
double height;
cairo_pdf_document_t *document;
- cairo_pdf_stream_t *current_stream;
cairo_array_t patterns;
cairo_array_t xobjects;
@@ -163,7 +160,7 @@ _cairo_pdf_document_finish (cairo_pdf_do
static cairo_pdf_document_t *
_cairo_pdf_document_reference (cairo_pdf_document_t *document);
-static unsigned int
+static cairo_pdf_resource_t
_cairo_pdf_document_new_object (cairo_pdf_document_t *document);
static cairo_status_t
@@ -173,7 +170,7 @@ _cairo_pdf_document_add_page (cairo_pdf_
static void
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface);
-static cairo_pdf_stream_t *
+static cairo_pdf_resource_t
_cairo_pdf_document_open_stream (cairo_pdf_document_t *document,
const char *fmt,
...) CAIRO_PRINTF_FORMAT(2, 3);
@@ -186,73 +183,79 @@ _cairo_pdf_surface_create_for_document (
double height);
static void
_cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface,
- cairo_pdf_stream_t *stream);
-static void
-_cairo_pdf_surface_ensure_stream (cairo_pdf_surface_t *surface);
+ cairo_pdf_resource_t stream);
static const cairo_surface_backend_t cairo_pdf_surface_backend;
static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend;
-static unsigned int
+static cairo_pdf_resource_t
_cairo_pdf_document_new_object (cairo_pdf_document_t *document)
{
+ cairo_pdf_resource_t resource;
cairo_status_t status;
cairo_pdf_object_t object;
object.offset = _cairo_output_stream_get_position (document->output_stream);
status = _cairo_array_append (&document->objects, &object);
- if (status)
- return 0;
+ if (status) {
+ resource.id = 0;
+ return resource;
+ }
- return document->next_available_id++;
+ resource = document->next_available_resource;
+ document->next_available_resource.id++;
+
+ return resource;
}
static void
_cairo_pdf_document_update_object (cairo_pdf_document_t *document,
- unsigned int id)
+ cairo_pdf_resource_t resource)
{
cairo_pdf_object_t *object;
- object = _cairo_array_index (&document->objects, id - 1);
+ object = _cairo_array_index (&document->objects, resource.id - 1);
object->offset = _cairo_output_stream_get_position (document->output_stream);
}
static void
_cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface,
- cairo_pdf_stream_t *stream)
+ cairo_pdf_resource_t stream)
{
/* XXX: Should be checking the return value here. */
_cairo_array_append (&surface->streams, &stream);
- surface->current_stream = stream;
}
static void
-_cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface, unsigned int id)
+_cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface,
+ cairo_pdf_resource_t pattern)
{
- cairo_pdf_resource_t resource;
-
- resource.id = id;
/* XXX: Should be checking the return value here. */
- _cairo_array_append (&surface->patterns, &resource);
+ _cairo_array_append (&surface->patterns, &pattern);
}
-static unsigned int
+static cairo_pdf_resource_t
_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha)
{
+ cairo_pdf_resource_t resource;
int num_alphas, i;
double other;
num_alphas = _cairo_array_num_elements (&surface->alphas);
for (i = 0; i < num_alphas; i++) {
_cairo_array_copy_element (&surface->alphas, i, &other);
- if (alpha == other)
- return i;
+ if (alpha == other) {
+ resource.id = i;
+ return resource;
+ }
}
/* XXX: Should be checking the return value here. */
_cairo_array_append (&surface->alphas, &alpha);
- return _cairo_array_num_elements (&surface->alphas) - 1;
+
+ resource.id = _cairo_array_num_elements (&surface->alphas) - 1;
+ return resource;
}
static cairo_surface_t *
@@ -467,7 +470,7 @@ _cairo_pdf_surface_create_for_document (
surface->height = height;
surface->document = _cairo_pdf_document_reference (document);
- _cairo_array_init (&surface->streams, sizeof (cairo_pdf_stream_t *));
+ _cairo_array_init (&surface->streams, sizeof (cairo_pdf_resource_t));
_cairo_array_init (&surface->patterns, sizeof (cairo_pdf_resource_t));
_cairo_array_init (&surface->xobjects, sizeof (cairo_pdf_resource_t));
_cairo_array_init (&surface->alphas, sizeof (double));
@@ -482,15 +485,6 @@ _cairo_pdf_surface_create_for_document (
static void
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
{
- int num_streams, i;
- cairo_pdf_stream_t *stream;
-
- num_streams = _cairo_array_num_elements (&surface->streams);
- for (i = 0; i < num_streams; i++) {
- _cairo_array_copy_element (&surface->streams, i, &stream);
- free (stream);
- }
-
_cairo_array_truncate (&surface->streams, 0);
_cairo_array_truncate (&surface->patterns, 0);
_cairo_array_truncate (&surface->xobjects, 0);
@@ -511,28 +505,23 @@ _cairo_pdf_surface_create_similar (void
return cairo_image_surface_create (format, width, height);
}
-static cairo_pdf_stream_t *
+static cairo_pdf_resource_t
_cairo_pdf_document_open_stream (cairo_pdf_document_t *document,
const char *fmt,
...)
{
cairo_output_stream_t *output_stream = document->output_stream;
- cairo_pdf_stream_t *stream;
va_list ap;
- stream = malloc (sizeof (cairo_pdf_stream_t));
- if (stream == NULL) {
- return NULL;
- }
-
- stream->id = _cairo_pdf_document_new_object (document);
- stream->length_id = _cairo_pdf_document_new_object (document);
+ document->current_stream.active = TRUE;
+ document->current_stream.self = _cairo_pdf_document_new_object (document);
+ document->current_stream.length = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output_stream,
"%d 0 obj\r\n"
"<< /Length %d 0 R\r\n",
- stream->id,
- stream->length_id);
+ document->current_stream.self.id,
+ document->current_stream.length.id);
if (fmt != NULL) {
va_start (ap, fmt);
@@ -544,11 +533,9 @@ _cairo_pdf_document_open_stream (cairo_p
">>\r\n"
"stream\r\n");
- stream->start_offset = _cairo_output_stream_get_position (output_stream);
+ document->current_stream.start_offset = _cairo_output_stream_get_position (output_stream);
- document->current_stream = stream;
-
- return stream;
+ return document->current_stream.self;
}
static void
@@ -556,27 +543,26 @@ _cairo_pdf_document_close_stream (cairo_
{
cairo_output_stream_t *output_stream = document->output_stream;
long length;
- cairo_pdf_stream_t *stream;
- stream = document->current_stream;
- if (stream == NULL)
+ if (! document->current_stream.active)
return;
length = _cairo_output_stream_get_position (output_stream) -
- stream->start_offset;
+ document->current_stream.start_offset;
_cairo_output_stream_printf (output_stream,
"endstream\r\n"
"endobj\r\n");
- _cairo_pdf_document_update_object (document, stream->length_id);
+ _cairo_pdf_document_update_object (document,
+ document->current_stream.length);
_cairo_output_stream_printf (output_stream,
"%d 0 obj\r\n"
" %ld\r\n"
"endobj\r\n",
- stream->length_id,
+ document->current_stream.length.id,
length);
- document->current_stream = NULL;
+ document->current_stream.active = FALSE;
}
static cairo_status_t
@@ -586,8 +572,7 @@ _cairo_pdf_surface_finish (void *abstrac
cairo_pdf_surface_t *surface = abstract_surface;
cairo_pdf_document_t *document = surface->document;
- if (surface->current_stream == document->current_stream)
- _cairo_pdf_document_close_stream (document);
+ _cairo_pdf_document_close_stream (document);
if (document->owner == &surface->base)
status = _cairo_pdf_document_finish (document);
@@ -605,32 +590,52 @@ _cairo_pdf_surface_finish (void *abstrac
return status;
}
+static void
+_cairo_pdf_surface_pause_content_stream (cairo_pdf_surface_t *surface)
+{
+ cairo_pdf_document_t *document = surface->document;
+
+ _cairo_pdf_document_close_stream (document);
+}
+
static void
-_cairo_pdf_surface_ensure_stream (cairo_pdf_surface_t *surface)
+_cairo_pdf_surface_resume_content_stream (cairo_pdf_surface_t *surface)
{
cairo_pdf_document_t *document = surface->document;
- cairo_pdf_stream_t *stream;
+ cairo_pdf_resource_t stream;
+
+ stream = _cairo_pdf_document_open_stream (document,
+ " /Type /XObject\r\n"
+ " /Subtype /Form\r\n"
+ " /BBox [ 0 0 %f %f ]\r\n",
+ surface->width,
+ surface->height);
+
+ _cairo_pdf_surface_add_stream (surface, stream);
+}
+
+static cairo_int_status_t
+_cairo_pdf_surface_start_page (void *abstract_surface)
+{
+ cairo_pdf_surface_t *surface = abstract_surface;
+ cairo_pdf_document_t *document = surface->document;
cairo_output_stream_t *output = document->output_stream;
+ cairo_pdf_resource_t stream;
- if (document->current_stream == NULL ||
- document->current_stream != surface->current_stream) {
- _cairo_pdf_document_close_stream (document);
- stream = _cairo_pdf_document_open_stream (document,
- " /Type /XObject\r\n"
- " /Subtype /Form\r\n"
- " /BBox [ 0 0 %f %f ]\r\n",
- surface->width,
- surface->height);
-
- _cairo_pdf_surface_add_stream (surface, stream);
-
- /* If this is the first stream we open for this surface,
- * output the cairo to PDF transformation matrix. */
- if (_cairo_array_num_elements (&surface->streams) == 1)
- _cairo_output_stream_printf (output,
- "1 0 0 -1 0 %f cm\r\n",
- surface->height);
- }
+ stream = _cairo_pdf_document_open_stream (document,
+ " /Type /XObject\r\n"
+ " /Subtype /Form\r\n"
+ " /BBox [ 0 0 %f %f ]\r\n",
+ surface->width,
+ surface->height);
+
+ _cairo_pdf_surface_add_stream (surface, stream);
+
+ _cairo_output_stream_printf (output,
+ "1 0 0 -1 0 %f cm\r\n",
+ surface->height);
+
+ return CAIRO_STATUS_SUCCESS;
}
static void *
@@ -659,11 +664,10 @@ compress_dup (const void *data, unsigned
static cairo_status_t
emit_smask (cairo_pdf_document_t *document,
cairo_image_surface_t *image,
- unsigned int *id_ret)
+ cairo_pdf_resource_t *stream_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_output_stream_t *output = document->output_stream;
- cairo_pdf_stream_t *smask_stream;
char *alpha, *alpha_compressed;
unsigned long alpha_size, alpha_compressed_size;
pixman_bits_t *pixel;
@@ -696,7 +700,7 @@ emit_smask (cairo_pdf_document_t *docume
/* Bail out without emitting smask if it's all opaque. */
if (opaque) {
- *id_ret = 0;
+ stream_ret->id = 0;
goto CLEANUP_ALPHA;
}
@@ -707,21 +711,19 @@ emit_smask (cairo_pdf_document_t *docume
}
- smask_stream = _cairo_pdf_document_open_stream (document,
- " /Type /XObject\r\n"
- " /Subtype /Image\r\n"
- " /Width %d\r\n"
- " /Height %d\r\n"
- " /ColorSpace /DeviceGray\r\n"
- " /BitsPerComponent 8\r\n"
- " /Filter /FlateDecode\r\n",
- image->width, image->height);
+ *stream_ret = _cairo_pdf_document_open_stream (document,
+ " /Type /XObject\r\n"
+ " /Subtype /Image\r\n"
+ " /Width %d\r\n"
+ " /Height %d\r\n"
+ " /ColorSpace /DeviceGray\r\n"
+ " /BitsPerComponent 8\r\n"
+ " /Filter /FlateDecode\r\n",
+ image->width, image->height);
_cairo_output_stream_write (output, alpha_compressed, alpha_compressed_size);
_cairo_output_stream_printf (output, "\r\n");
_cairo_pdf_document_close_stream (document);
- *id_ret = smask_stream->id;
-
free (alpha_compressed);
CLEANUP_ALPHA:
free (alpha);
@@ -735,18 +737,22 @@ emit_smask (cairo_pdf_document_t *docume
static cairo_status_t
emit_image (cairo_pdf_document_t *document,
cairo_image_surface_t *image,
- unsigned int *id_ret)
+ cairo_pdf_resource_t *image_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_output_stream_t *output = document->output_stream;
- cairo_pdf_stream_t *image_stream;
char *rgb, *compressed;
unsigned long rgb_size, compressed_size;
pixman_bits_t *pixel;
int i, x, y;
- unsigned int smask_id = 0; /* just to squelch a warning */
+ cairo_pdf_resource_t smask;
cairo_bool_t need_smask;
+ /* XXX: Need to rewrite this as a pdf_surface function with
+ * pause/resume of content_stream, (currently the only caller does
+ * the pause/resume already, but that is expected to change in the
+ * future). */
+
/* These are the only image formats we currently support, (which
* makes things a lot simpler here). This is enforeced through
* _analyze_operation which only accept source surfaces of
@@ -791,8 +797,6 @@ emit_image (cairo_pdf_document_t *docume
}
}
- _cairo_pdf_document_close_stream (document);
-
compressed = compress_dup (rgb, rgb_size, &compressed_size);
if (compressed == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
@@ -801,11 +805,11 @@ emit_image (cairo_pdf_document_t *docume
need_smask = FALSE;
if (image->format == CAIRO_FORMAT_ARGB32) {
- status = emit_smask (document, image, &smask_id);
+ status = emit_smask (document, image, &smask);
if (status)
goto CLEANUP_COMPRESSED;
- if (smask_id)
+ if (smask.id)
need_smask = TRUE;
}
@@ -819,15 +823,15 @@ emit_image (cairo_pdf_document_t *docume
if (need_smask)
- image_stream = _cairo_pdf_document_open_stream (document,
- IMAGE_DICTIONARY
- " /SMask %d 0 R\r\n",
- image->width, image->height,
- smask_id);
+ *image_ret = _cairo_pdf_document_open_stream (document,
+ IMAGE_DICTIONARY
+ " /SMask %d 0 R\r\n",
+ image->width, image->height,
+ smask.id);
else
- image_stream = _cairo_pdf_document_open_stream (document,
- IMAGE_DICTIONARY,
- image->width, image->height);
+ *image_ret = _cairo_pdf_document_open_stream (document,
+ IMAGE_DICTIONARY,
+ image->width, image->height);
#undef IMAGE_DICTIONARY
@@ -835,8 +839,6 @@ emit_image (cairo_pdf_document_t *docume
_cairo_output_stream_printf (output, "\r\n");
_cairo_pdf_document_close_stream (document);
- *id_ret = image_stream->id;
-
CLEANUP_COMPRESSED:
free (compressed);
CLEANUP_RGB:
@@ -851,10 +853,10 @@ emit_solid_pattern (cairo_pdf_surface_t
{
cairo_pdf_document_t *document = surface->document;
cairo_output_stream_t *output = document->output_stream;
- unsigned int alpha;
+ cairo_pdf_resource_t alpha;
alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha);
- _cairo_pdf_surface_ensure_stream (surface);
+
/* With some work, we could separate the stroking
* or non-stroking color here as actually needed. */
_cairo_output_stream_printf (output,
@@ -867,7 +869,7 @@ emit_solid_pattern (cairo_pdf_surface_t
pattern->color.red,
pattern->color.green,
pattern->color.blue,
- alpha);
+ alpha.id);
return CAIRO_STATUS_SUCCESS;
}
@@ -878,11 +880,11 @@ emit_surface_pattern (cairo_pdf_surface_
{
cairo_pdf_document_t *document = dst->document;
cairo_output_stream_t *output = document->output_stream;
- cairo_pdf_stream_t *stream;
+ cairo_pdf_resource_t stream;
cairo_image_surface_t *image;
void *image_extra;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
- unsigned int alpha, id = 0; /* just to squelch a warning */
+ cairo_pdf_resource_t alpha, image_resource;
cairo_matrix_t cairo_p2d, pdf_p2d;
cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base);
int xstep, ystep;
@@ -890,13 +892,13 @@ emit_surface_pattern (cairo_pdf_surface_
/* XXX: Should do something clever here for PDF source surfaces ? */
+ _cairo_pdf_surface_pause_content_stream (dst);
+
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
if (status)
return status;
- _cairo_pdf_document_close_stream (document);
-
- status = emit_image (dst->document, image, &id);
+ status = emit_image (dst->document, image, &image_resource);
if (status)
goto BAIL;
@@ -974,16 +976,20 @@ emit_surface_pattern (cairo_pdf_surface_
pdf_p2d.xx, pdf_p2d.yx,
pdf_p2d.xy, pdf_p2d.yy,
pdf_p2d.x0, pdf_p2d.y0,
- id, id);
+ image_resource.id,
+ image_resource.id);
_cairo_output_stream_printf (output,
"q %d 0 0 %d 0 0 cm /res%d Do Q\r\n",
image->width, image->height,
- id);
+ image_resource.id);
- _cairo_pdf_surface_add_pattern (dst, stream->id);
+ _cairo_pdf_document_close_stream (document);
+
+ _cairo_pdf_surface_resume_content_stream (dst);
+
+ _cairo_pdf_surface_add_pattern (dst, stream);
- _cairo_pdf_surface_ensure_stream (dst);
alpha = _cairo_pdf_surface_add_alpha (dst, 1.0);
/* With some work, we could separate the stroking
* or non-stroking pattern here as actually needed. */
@@ -991,7 +997,7 @@ emit_surface_pattern (cairo_pdf_surface_
"/Pattern CS /res%d SCN "
"/Pattern cs /res%d scn "
"/a%d gs\r\n",
- stream->id, stream->id, alpha);
+ stream.id, stream.id, alpha.id);
BAIL:
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
@@ -1001,19 +1007,18 @@ emit_surface_pattern (cairo_pdf_surface_
typedef struct _cairo_pdf_color_stop {
- double offset;
- unsigned int gradient_id;
- unsigned char color_char[4];
+ double offset;
+ cairo_pdf_resource_t gradient;
+ unsigned char color_char[4];
} cairo_pdf_color_stop_t;
-
-static unsigned int
+static cairo_pdf_resource_t
emit_linear_colorgradient (cairo_pdf_document_t *document,
cairo_pdf_color_stop_t *stop1,
cairo_pdf_color_stop_t *stop2)
{
cairo_output_stream_t *output = document->output_stream;
- unsigned int function_id = _cairo_pdf_document_new_object (document);
+ cairo_pdf_resource_t function = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
@@ -1025,7 +1030,7 @@ emit_linear_colorgradient (cairo_pdf_doc
" /Length 6\r\n"
">>\r\n"
"stream\r\n",
- function_id);
+ function.id);
_cairo_output_stream_write (output, stop1->color_char, 3);
_cairo_output_stream_write (output, stop2->color_char, 3);
@@ -1034,36 +1039,35 @@ emit_linear_colorgradient (cairo_pdf_doc
"endstream\r\n"
"endobj\r\n");
- return function_id;
+ return function;
}
-
-static unsigned int
+static cairo_pdf_resource_t
emit_stiched_colorgradient (cairo_pdf_document_t *document,
unsigned int n_stops,
cairo_pdf_color_stop_t stops[])
{
cairo_output_stream_t *output = document->output_stream;
- unsigned int function_id;
+ cairo_pdf_resource_t function;
unsigned int i;
/* emit linear gradients between pairs of subsequent stops... */
for (i = 0; i < n_stops-1; i++) {
- stops[i].gradient_id = emit_linear_colorgradient (document,
- &stops[i],
- &stops[i+1]);
+ stops[i].gradient = emit_linear_colorgradient (document,
+ &stops[i],
+ &stops[i+1]);
}
/* ... and stich them together */
- function_id = _cairo_pdf_document_new_object (document);
+ function = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /FunctionType 3\r\n"
" /Domain [ 0 1 ]\r\n"
" /Functions [ ",
- function_id);
+ function.id);
for (i = 0; i < n_stops-1; i++)
- _cairo_output_stream_printf (output, "%d 0 R ", stops[i].gradient_id);
+ _cairo_output_stream_printf (output, "%d 0 R ", stops[i].gradient.id);
_cairo_output_stream_printf (output,
"]\r\n"
" /Bounds [ ");
@@ -1079,26 +1083,27 @@ emit_stiched_colorgradient (cairo_pdf_do
">>\r\n"
"endobj\r\n");
- return function_id;
+ return function;
}
#define COLOR_STOP_EPSILLON 1e-6
-static unsigned int
+static cairo_pdf_resource_t
emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern)
{
cairo_pdf_document_t *document = surface->document;
- unsigned int function_id;
+ cairo_pdf_resource_t function;
cairo_pdf_color_stop_t *allstops, *stops;
unsigned int n_stops;
unsigned int i;
- function_id = _cairo_pdf_document_new_object (document);
+ function = _cairo_pdf_document_new_object (document);
allstops = malloc ((pattern->n_stops + 2) * sizeof (cairo_pdf_color_stop_t));
if (allstops == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
- return 0;
+ function.id = 0;
+ return function;
}
stops = &allstops[1];
n_stops = pattern->n_stops;
@@ -1129,18 +1134,18 @@ emit_pattern_stops (cairo_pdf_surface_t
if (n_stops == 2) {
/* no need for stiched function */
- function_id = emit_linear_colorgradient (document, &stops[0], &stops[1]);
+ function = emit_linear_colorgradient (document, &stops[0], &stops[1]);
} else {
/* multiple stops: stich. XXX possible optimization: regulary spaced
* stops do not require stiching. XXX */
- function_id = emit_stiched_colorgradient (document,
- n_stops,
- stops);
+ function = emit_stiched_colorgradient (document,
+ n_stops,
+ stops);
}
free (allstops);
- return function_id;
+ return function;
}
static cairo_status_t
@@ -1148,14 +1153,14 @@ emit_linear_pattern (cairo_pdf_surface_t
{
cairo_pdf_document_t *document = surface->document;
cairo_output_stream_t *output = document->output_stream;
- unsigned int function_id, pattern_id, alpha;
+ cairo_pdf_resource_t function, pattern_resource, alpha;
double x0, y0, x1, y1;
cairo_matrix_t p2u;
- _cairo_pdf_document_close_stream (document);
+ _cairo_pdf_surface_pause_content_stream (surface);
- function_id = emit_pattern_stops (surface, &pattern->base);
- if (function_id == 0)
+ function = emit_pattern_stops (surface, &pattern->base);
+ if (function.id == 0)
return CAIRO_STATUS_NO_MEMORY;
p2u = pattern->base.base.matrix;
@@ -1168,7 +1173,7 @@ emit_linear_pattern (cairo_pdf_surface_t
y1 = _cairo_fixed_to_double (pattern->gradient.p2.y);
cairo_matrix_transform_point (&p2u, &x1, &y1);
- pattern_id = _cairo_pdf_document_new_object (document);
+ pattern_resource = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Type /Pattern\r\n"
@@ -1183,14 +1188,13 @@ emit_linear_pattern (cairo_pdf_surface_t
" >>\r\n"
">>\r\n"
"endobj\r\n",
- pattern_id,
+ pattern_resource.id,
document->height,
x0, y0, x1, y1,
- function_id);
+ function.id);
- _cairo_pdf_surface_add_pattern (surface, pattern_id);
+ _cairo_pdf_surface_add_pattern (surface, pattern_resource);
- _cairo_pdf_surface_ensure_stream (surface);
alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
/* Use pattern */
@@ -1200,7 +1204,11 @@ emit_linear_pattern (cairo_pdf_surface_t
"/Pattern CS /res%d SCN "
"/Pattern cs /res%d scn "
"/a%d gs\r\n",
- pattern_id, pattern_id, alpha);
+ pattern_resource.id,
+ pattern_resource.id,
+ alpha.id);
+
+ _cairo_pdf_surface_resume_content_stream (surface);
return CAIRO_STATUS_SUCCESS;
}
@@ -1210,14 +1218,14 @@ emit_radial_pattern (cairo_pdf_surface_t
{
cairo_pdf_document_t *document = surface->document;
cairo_output_stream_t *output = document->output_stream;
- unsigned int function_id, pattern_id, alpha;
+ cairo_pdf_resource_t function, pattern_resource, alpha;
double x0, y0, x1, y1, r0, r1;
cairo_matrix_t p2u;
- _cairo_pdf_document_close_stream (document);
+ _cairo_pdf_surface_pause_content_stream (surface);
- function_id = emit_pattern_stops (surface, &pattern->base);
- if (function_id == 0)
+ function = emit_pattern_stops (surface, &pattern->base);
+ if (function.id == 0)
return CAIRO_STATUS_NO_MEMORY;
p2u = pattern->base.base.matrix;
@@ -1243,7 +1251,7 @@ emit_radial_pattern (cairo_pdf_surface_t
* to infinity. Setting extend=true in PDF gives the cairo default
* behavoir, not yet sure how to implement the cairo mirror and
* repeat behaviour. */
- pattern_id = _cairo_pdf_document_new_object (document);
+ pattern_resource = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Type /Pattern\r\n"
@@ -1258,14 +1266,13 @@ emit_radial_pattern (cairo_pdf_surface_t
" >>\r\n"
">>\r\n"
"endobj\r\n",
- pattern_id,
+ pattern_resource.id,
document->height,
x0, y0, r0, x1, y1, r1,
- function_id);
+ function.id);
- _cairo_pdf_surface_add_pattern (surface, pattern_id);
+ _cairo_pdf_surface_add_pattern (surface, pattern_resource);
- _cairo_pdf_surface_ensure_stream (surface);
alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
/* Use pattern */
@@ -1275,7 +1282,11 @@ emit_radial_pattern (cairo_pdf_surface_t
"/Pattern CS /res%d SCN "
"/Pattern cs /res%d scn "
"/a%d gs\r\n",
- pattern_id, pattern_id, alpha);
+ pattern_resource.id,
+ pattern_resource.id,
+ alpha.id);
+
+ _cairo_pdf_surface_resume_content_stream (surface);
return CAIRO_STATUS_SUCCESS;
}
@@ -1295,6 +1306,7 @@ emit_pattern (cairo_pdf_surface_t *surfa
case CAIRO_PATTERN_TYPE_RADIAL:
return emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
+
}
ASSERT_NOT_REACHED;
@@ -1484,8 +1496,6 @@ _cairo_pdf_surface_intersect_clip_path (
cairo_status_t status;
const char *pdf_operator;
- _cairo_pdf_surface_ensure_stream (surface);
-
if (path == NULL) {
if (surface->has_clip)
_cairo_output_stream_printf (output, "Q\r\n");
@@ -1555,12 +1565,12 @@ _cairo_pdf_document_create (cairo_output
document->y_dpi = DEFAULT_DPI;
_cairo_array_init (&document->objects, sizeof (cairo_pdf_object_t));
- _cairo_array_init (&document->pages, sizeof (unsigned int));
- document->next_available_id = 1;
+ _cairo_array_init (&document->pages, sizeof (cairo_pdf_resource_t));
+ document->next_available_resource.id = 1;
- document->current_stream = NULL;
+ document->current_stream.active = FALSE;
- document->pages_id = _cairo_pdf_document_new_object (document);
+ document->pages_resource = _cairo_pdf_document_new_object (document);
_cairo_array_init (&document->fonts, sizeof (cairo_font_subset_t *));
@@ -1571,42 +1581,42 @@ _cairo_pdf_document_create (cairo_output
return document;
}
-static unsigned int
+static cairo_pdf_resource_t
_cairo_pdf_document_write_info (cairo_pdf_document_t *document)
{
cairo_output_stream_t *output = document->output_stream;
- unsigned int id;
+ cairo_pdf_resource_t info;
- id = _cairo_pdf_document_new_object (document);
+ info = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Creator (cairographics.org)\r\n"
" /Producer (cairographics.org)\r\n"
">>\r\n"
"endobj\r\n",
- id);
+ info.id);
- return id;
+ return info;
}
static void
_cairo_pdf_document_write_pages (cairo_pdf_document_t *document)
{
cairo_output_stream_t *stream = document->output_stream;
- unsigned int page_id;
+ cairo_pdf_resource_t page;
int num_pages, i;
- _cairo_pdf_document_update_object (document, document->pages_id);
+ _cairo_pdf_document_update_object (document, document->pages_resource);
_cairo_output_stream_printf (stream,
"%d 0 obj\r\n"
"<< /Type /Pages\r\n"
" /Kids [ ",
- document->pages_id);
+ document->pages_resource.id);
num_pages = _cairo_array_num_elements (&document->pages);
for (i = 0; i < num_pages; i++) {
- _cairo_array_copy_element (&document->pages, i, &page_id);
- _cairo_output_stream_printf (stream, "%d 0 R ", page_id);
+ _cairo_array_copy_element (&document->pages, i, &page);
+ _cairo_output_stream_printf (stream, "%d 0 R ", page.id);
}
_cairo_output_stream_printf (stream, "]\r\n");
@@ -1627,11 +1637,12 @@ _cairo_pdf_document_write_fonts (cairo_p
{
cairo_output_stream_t *output = document->output_stream;
cairo_font_subset_t *font;
+ cairo_pdf_resource_t font_resource;
int num_fonts, i, j;
const char *data;
char *compressed;
unsigned long data_size, compressed_size;
- unsigned int stream_id, descriptor_id;
+ cairo_pdf_resource_t stream, descriptor;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
num_fonts = _cairo_array_num_elements (&document->fonts);
@@ -1648,7 +1659,7 @@ _cairo_pdf_document_write_fonts (cairo_p
goto fail;
}
- stream_id = _cairo_pdf_document_new_object (document);
+ stream = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Filter /FlateDecode\r\n"
@@ -1656,7 +1667,7 @@ _cairo_pdf_document_write_fonts (cairo_p
" /Length1 %lu\r\n"
">>\r\n"
"stream\r\n",
- stream_id,
+ stream.id,
compressed_size,
data_size);
_cairo_output_stream_write (output, compressed, compressed_size);
@@ -1666,7 +1677,7 @@ _cairo_pdf_document_write_fonts (cairo_p
"endobj\r\n");
free (compressed);
- descriptor_id = _cairo_pdf_document_new_object (document);
+ descriptor = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Type /FontDescriptor\r\n"
@@ -1682,7 +1693,7 @@ _cairo_pdf_document_write_fonts (cairo_p
" /FontFile2 %u 0 R\r\n"
">>\r\n"
"endobj\r\n",
- descriptor_id,
+ descriptor.id,
font->base_font,
font->x_min,
font->y_min,
@@ -1690,9 +1701,10 @@ _cairo_pdf_document_write_fonts (cairo_p
font->y_max,
font->ascent,
font->descent,
- stream_id);
+ stream.id);
- _cairo_pdf_document_update_object (document, font->font_id);
+ font_resource.id = font->font_id;
+ _cairo_pdf_document_update_object (document, font_resource);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Type /Font\r\n"
@@ -1705,7 +1717,7 @@ _cairo_pdf_document_write_fonts (cairo_p
font->font_id,
font->base_font,
font->num_glyphs,
- descriptor_id);
+ descriptor.id);
_cairo_output_stream_printf (output,
"[");
@@ -1727,22 +1739,23 @@ _cairo_pdf_document_write_fonts (cairo_p
return status;
}
-static unsigned int
+static cairo_pdf_resource_t
_cairo_pdf_document_write_catalog (cairo_pdf_document_t *document)
{
cairo_output_stream_t *output = document->output_stream;
- unsigned int id;
+ cairo_pdf_resource_t catalog;
- id = _cairo_pdf_document_new_object (document);
+ catalog = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Type /Catalog\r\n"
" /Pages %d 0 R\r\n"
">>\r\n"
"endobj\r\n",
- id, document->pages_id);
+ catalog.id,
+ document->pages_resource.id);
- return id;
+ return catalog;
}
static long
@@ -1800,7 +1813,7 @@ _cairo_pdf_document_finish (cairo_pdf_do
cairo_status_t status;
cairo_output_stream_t *output = document->output_stream;
long offset;
- unsigned int info_id, catalog_id;
+ cairo_pdf_resource_t info, catalog;
if (document->finished)
return CAIRO_STATUS_SUCCESS;
@@ -1808,8 +1821,8 @@ _cairo_pdf_document_finish (cairo_pdf_do
_cairo_pdf_document_close_stream (document);
_cairo_pdf_document_write_pages (document);
_cairo_pdf_document_write_fonts (document);
- info_id = _cairo_pdf_document_write_info (document);
- catalog_id = _cairo_pdf_document_write_catalog (document);
+ info = _cairo_pdf_document_write_info (document);
+ catalog = _cairo_pdf_document_write_catalog (document);
offset = _cairo_pdf_document_write_xref (document);
_cairo_output_stream_printf (output,
@@ -1818,9 +1831,9 @@ _cairo_pdf_document_finish (cairo_pdf_do
" /Root %d 0 R\r\n"
" /Info %d 0 R\r\n"
">>\r\n",
- document->next_available_id,
- catalog_id,
- info_id);
+ document->next_available_resource.id,
+ catalog.id,
+ info.id);
_cairo_output_stream_printf (output,
"startxref\r\n"
@@ -1845,17 +1858,15 @@ _cairo_pdf_document_add_page (cairo_pdf_
cairo_pdf_surface_t *surface)
{
cairo_status_t status;
- cairo_pdf_stream_t *stream;
cairo_pdf_resource_t *res;
cairo_output_stream_t *output = document->output_stream;
- unsigned int page_id;
+ cairo_pdf_resource_t page;
double alpha;
+ cairo_pdf_resource_t stream;
int num_streams, num_alphas, num_resources, i;
assert (!document->finished);
- _cairo_pdf_surface_ensure_stream (surface);
-
if (surface->has_clip) {
_cairo_output_stream_printf (output, "Q\r\n");
surface->has_clip = FALSE;
@@ -1863,13 +1874,13 @@ _cairo_pdf_document_add_page (cairo_pdf_
_cairo_pdf_document_close_stream (document);
- page_id = _cairo_pdf_document_new_object (document);
+ page = _cairo_pdf_document_new_object (document);
_cairo_output_stream_printf (output,
"%d 0 obj\r\n"
"<< /Type /Page\r\n"
" /Parent %d 0 R\r\n",
- page_id,
- document->pages_id);
+ page.id,
+ document->pages_resource.id);
if (surface->width != document->width ||
surface->height != document->height)
@@ -1884,15 +1895,14 @@ _cairo_pdf_document_add_page (cairo_pdf_
" /Contents [");
num_streams = _cairo_array_num_elements (&surface->streams);
for (i = 0; i < num_streams; i++) {
- _cairo_array_copy_element (&surface->streams, i, &stream);
+ _cairo_array_copy_element (&surface->streams, i, &stream);
_cairo_output_stream_printf (output,
" %d 0 R",
- stream->id);
+ stream.id);
}
_cairo_output_stream_printf (output,
" ]\r\n");
-
_cairo_output_stream_printf (output,
" /Resources <<\r\n");
@@ -1966,7 +1976,7 @@ _cairo_pdf_document_add_page (cairo_pdf_
">>\r\n"
"endobj\r\n");
- status = _cairo_array_append (&document->pages, &page_id);
+ status = _cairo_array_append (&document->pages, &page);
if (status)
return status;
@@ -2069,12 +2079,6 @@ _cairo_pdf_surface_paint (void *abstra
if (status)
return status;
- /* After emitting the pattern the current stream should belong to
- * this surface, so no need to _cairo_pdf_surface_ensure_stream()
- */
- assert (document->current_stream != NULL &&
- document->current_stream == surface->current_stream);
-
_cairo_output_stream_printf (document->output_stream,
"0 0 %f %f re f\r\n",
surface->width, surface->height);
@@ -2194,12 +2198,6 @@ _cairo_pdf_surface_stroke (void *abstr
if (status)
return status;
- /* After emitting the pattern the current stream should belong to
- * this surface, so no need to _cairo_pdf_surface_ensure_stream()
- */
- assert (document->current_stream != NULL &&
- document->current_stream == surface->current_stream);
-
stroke.output_stream = document->output_stream;
stroke.ctm_inverse = ctm_inverse;
status = _cairo_path_fixed_interpret (path,
@@ -2255,12 +2253,6 @@ _cairo_pdf_surface_fill (void *abstrac
if (status)
return status;
- /* After emitting the pattern the current stream should belong to
- * this surface, so no need to _cairo_pdf_surface_ensure_stream()
- */
- assert (document->current_stream != NULL &&
- document->current_stream == surface->current_stream);
-
status = _cairo_path_fixed_interpret (path,
CAIRO_DIRECTION_FORWARD,
_cairo_pdf_path_move_to,
@@ -2296,7 +2288,6 @@ _cairo_pdf_surface_show_glyphs (void *
cairo_scaled_font_t *scaled_font)
{
cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_document_t *document = surface->document;
cairo_path_fixed_t path;
cairo_status_t status;
@@ -2309,12 +2300,6 @@ _cairo_pdf_surface_show_glyphs (void *
if (status)
return status;
- /* After emitting the pattern the current stream should belong to
- * this surface, so no need to _cairo_pdf_surface_ensure_stream()
- */
- assert (document->current_stream != NULL &&
- document->current_stream == surface->current_stream);
-
_cairo_path_fixed_init (&path);
_cairo_scaled_font_glyph_path (scaled_font, glyphs, num_glyphs, &path);
status = _cairo_pdf_surface_fill (surface, op, source,
@@ -2369,6 +2354,6 @@ static const cairo_surface_backend_t cai
};
static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend = {
- NULL, /* start_page */
+ _cairo_pdf_surface_start_page,
_cairo_pdf_surface_set_paginated_mode
};
More information about the cairo-commit
mailing list