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

Carl Worth cworth at kemper.freedesktop.org
Tue Apr 25 03:49:51 PDT 2006


 src/cairo-pdf-surface.c |  629 ++++++++++++++----------------------------------
 1 files changed, 190 insertions(+), 439 deletions(-)

New commits:
diff-tree 134c508bf04d8674af632644095b78256f2e350d (from c0721190438826d7222ed87c36b4e48e57ad0323)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 25 03:45:37 2006 -0700

    PDF: Add SMask output and simplify analysis to support all OVER operations.
    
    With this SMask support, the PDF backend is now able to handle a very
    large subset of the things that are likely to be thrown at it in
    common operation, (for example, when handling images and text from web
    pages).

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 984967b..d752a23 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -601,108 +601,199 @@ compress_dup (const void *data, unsigned
     return compressed;
 }
 
+/* Emit alpha channel from the image into the given data, providing
+ * and id that can be used to reference the resulting SMask object.
+ *
+ * In the case that the alpha channel happens to be all opaque, then
+ * 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,
+	    cairo_image_surface_t	*image,
+	    unsigned int		*id_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;
+    int i, x, y;
+    cairo_bool_t opaque;
+    uint8_t a;
+
+    /* This is the only image format we support, which simplfies things. */
+    assert (image->format == CAIRO_FORMAT_ARGB32);
+
+    alpha_size = image->height * image->width;
+    alpha = malloc (alpha_size);
+    if (alpha == NULL) {
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto CLEANUP;
+    }
+
+    opaque = TRUE;
+    i = 0;
+    for (y = 0; y < image->height; y++) {
+	pixel = (pixman_bits_t *) (image->data + y * image->stride);
+
+	for (x = 0; x < image->width; x++, pixel++) {
+	    a = (*pixel & 0xff000000) >> 24;
+	    alpha[i++] = a;
+	    if (a != 0xff)
+		opaque = FALSE;
+	}
+    }
+
+    /* Bail out without emitting smask if it's all opaque. */
+    if (opaque) {
+	*id_ret = 0;
+	goto CLEANUP_ALPHA;
+    }
+
+    alpha_compressed = compress_dup (alpha, alpha_size, &alpha_compressed_size);
+    if (alpha_compressed == NULL) {
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto CLEANUP_ALPHA;
+	
+    }
+
+    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);
+    _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);
+ CLEANUP:
+    return status;
+}
+
+
 /* Emit image data into the given document, providing an id that can
  * be used to reference the data in id_ret. */
 static cairo_status_t
-emit_image_rgb_data (cairo_pdf_document_t	*document,
-		     cairo_image_surface_t	*image,
-		     unsigned int		*id_ret)
+emit_image (cairo_pdf_document_t	*document,
+	    cairo_image_surface_t	*image,
+	    unsigned int		*id_ret)
 {
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_output_stream_t *output = document->output_stream;
-    cairo_pdf_stream_t *stream;
+    cairo_pdf_stream_t *image_stream;
     char *rgb, *compressed;
-    int i, x, y;
     unsigned long rgb_size, compressed_size;
     pixman_bits_t *pixel;
-    cairo_surface_t *opaque;
-    cairo_image_surface_t *opaque_image;
-    cairo_pattern_union_t pattern;
+    int i, x, y;
+    unsigned int smask_id;
+    cairo_bool_t need_smask;
+
+    /* 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. 
+     */
+    assert (image->format == CAIRO_FORMAT_RGB24 || image->format == CAIRO_FORMAT_ARGB32);
 
     rgb_size = image->height * image->width * 3;
     rgb = malloc (rgb_size);
-    if (rgb == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    /* XXX: We could actually output the alpha channels through PDF
-     * 1.4's SMask. But for now, all we support is opaque image data,
-     * so we must flatten any ARGB image by blending over white
-     * first. */
-    if (image->format != CAIRO_FORMAT_RGB24) {
-	opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
-					     image->width,
-					     image->height);
-	if (opaque->status) {
-	    free (rgb);
-	    return opaque->status;
-	}
-    
-	_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
-    
-	_cairo_surface_fill_rectangle (opaque,
-				       CAIRO_OPERATOR_SOURCE,
-				       CAIRO_COLOR_WHITE,
-				       0, 0, image->width, image->height);
-
-	_cairo_surface_composite (CAIRO_OPERATOR_OVER,
-				  &pattern.base,
-				  NULL,
-				  opaque,
-				  0, 0,
-				  0, 0,
-				  0, 0,
-				  image->width,
-				  image->height);
-    
-	_cairo_pattern_fini (&pattern.base);
-	opaque_image = (cairo_image_surface_t *) opaque;
-    } else {
-	opaque = &image->base;
-	opaque_image = image;
+    if (rgb == NULL) {
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto CLEANUP;
     }
 
     i = 0;
     for (y = 0; y < image->height; y++) {
-	pixel = (pixman_bits_t *) (opaque_image->data + y * opaque_image->stride);
+	pixel = (pixman_bits_t *) (image->data + y * image->stride);
 
-	for (x = 0; x < opaque_image->width; x++, pixel++) {
-	    rgb[i++] = (*pixel & 0x00ff0000) >> 16;
-	    rgb[i++] = (*pixel & 0x0000ff00) >>  8;
-	    rgb[i++] = (*pixel & 0x000000ff) >>  0;
+	for (x = 0; x < image->width; x++, pixel++) {
+	    /* XXX: We're un-premultiplying alpha here. My reading of the PDF
+	     * specification suggests that we should be able to avoid having
+	     * to do this by filling in the SMask's Matte dictionary
+	     * appropriately, but my attempts to do that so far have
+	     * failed. */
+	    if (image->format == CAIRO_FORMAT_ARGB32) {
+		uint8_t a;
+		a = (*pixel & 0xff000000) >> 24;
+		if (a == 0) {
+		    rgb[i++] = 0;
+		    rgb[i++] = 0;
+		    rgb[i++] = 0;
+		} else {
+		    rgb[i++] = (((*pixel & 0xff0000) >> 16) * 255 + a / 2) / a;
+		    rgb[i++] = (((*pixel & 0x00ff00) >>  8) * 255 + a / 2) / a;
+		    rgb[i++] = (((*pixel & 0x0000ff) >>  0) * 255 + a / 2) / a;
+		}
+	    } else {
+		rgb[i++] = (*pixel & 0x00ff0000) >> 16;
+		rgb[i++] = (*pixel & 0x0000ff00) >>  8;
+		rgb[i++] = (*pixel & 0x000000ff) >>  0;
+	    }
 	}
     }
 
+    _cairo_pdf_document_close_stream (document);
+
     compressed = compress_dup (rgb, rgb_size, &compressed_size);
     if (compressed == NULL) {
-	free (rgb);
-	return CAIRO_STATUS_NO_MEMORY;
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto CLEANUP_RGB;
     }
 
-    _cairo_pdf_document_close_stream (document);
+    need_smask = FALSE;
+    if (image->format == CAIRO_FORMAT_ARGB32) {
+	status = emit_smask (document, image, &smask_id);
+	if (status)
+	    goto CLEANUP_COMPRESSED;
 
-    stream = _cairo_pdf_document_open_stream (document, 
-					      "   /Type /XObject\r\n"
-					      "   /Subtype /Image\r\n"
-					      "   /Width %d\r\n"
-					      "   /Height %d\r\n"
-					      "   /ColorSpace /DeviceRGB\r\n"
-					      "   /BitsPerComponent 8\r\n"
-					      "   /Filter /FlateDecode\r\n",
-					      image->width, image->height);
+	if (smask_id)
+	    need_smask = TRUE;
+    }
 
-    _cairo_output_stream_write (output, compressed, compressed_size);
-    _cairo_output_stream_printf (output,
-				 "\r\n");
-    _cairo_pdf_document_close_stream (document);
+#define IMAGE_DICTIONARY	"   /Type /XObject\r\n"		\
+				"   /Subtype /Image\r\n"	\
+				"   /Width %d\r\n"		\
+				"   /Height %d\r\n"		\
+				"   /ColorSpace /DeviceRGB\r\n"	\
+				"   /BitsPerComponent 8\r\n"	\
+				"   /Filter /FlateDecode\r\n"
+
+
+    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);
+    else
+	image_stream = _cairo_pdf_document_open_stream (document,
+							IMAGE_DICTIONARY,
+							image->width, image->height);
 
-    free (rgb);
-    free (compressed);
+#undef IMAGE_DICTIONARY
 
-    if (opaque_image != image)
-	cairo_surface_destroy (opaque);
+    _cairo_output_stream_write (output, compressed, compressed_size);
+    _cairo_output_stream_printf (output, "\r\n");
+    _cairo_pdf_document_close_stream (document);
 
-    *id_ret = stream->id;
+    *id_ret = image_stream->id;
 
-    return CAIRO_STATUS_SUCCESS;
+ CLEANUP_COMPRESSED:
+    free (compressed);
+ CLEANUP_RGB:
+    free (rgb);
+ CLEANUP:
+    return status;
 }
 
 static cairo_status_t
@@ -748,10 +839,7 @@ emit_surface_pattern (cairo_pdf_surface_
     int xstep, ystep;
     cairo_rectangle_t dst_extents;
 
-    /* XXX: This is broken. We need new code here to actually emit the
-     * PDF surface. */
-    if (pattern->surface->backend == &cairo_pdf_surface_backend)
-	return CAIRO_STATUS_SUCCESS;
+    /* XXX: Should do something clever here for PDF source surfaces ? */
 
     status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
     if (status)
@@ -759,7 +847,7 @@ emit_surface_pattern (cairo_pdf_surface_
 
     _cairo_pdf_document_close_stream (document);
 
-    status = emit_image_rgb_data (dst->document, image, &id);
+    status = emit_image (dst->document, image, &id);
     if (status)
 	goto BAIL;
 
@@ -1756,22 +1844,44 @@ _cairo_pdf_document_add_page (cairo_pdf_
 }
 
 static cairo_bool_t
-_surface_pattern_supported (const cairo_surface_pattern_t *pattern)
+_surface_pattern_supported (cairo_surface_pattern_t *pattern)
 {
-    if (pattern->surface->backend->acquire_source_image != NULL)
+    cairo_extend_t extend;
+
+    if (pattern->surface->backend->acquire_source_image == NULL)
+	return FALSE;
+
+    /* Does an ALPHA-only source surface even make sense? Maybe, but I
+     * don't think it's worth the extra code to support it. */
+
+/* XXX: Need to write this function here...
+    content = cairo_surface_get_content (pattern->surface);
+    if (content == CAIRO_CONTENT_ALPHA)
+	return FALSE;
+*/
+
+    extend = cairo_pattern_get_extend (&pattern->base);
+    switch (extend) {
+    case CAIRO_EXTEND_NONE:
+    case CAIRO_EXTEND_REPEAT:
 	return TRUE;
+    case CAIRO_EXTEND_REFLECT:
+    case CAIRO_EXTEND_PAD:
+	return FALSE;
+    }
 
+    ASSERT_NOT_REACHED;
     return FALSE;
 }
 
 static cairo_bool_t
-_pattern_supported (const cairo_pattern_t *pattern)
+_pattern_supported (cairo_pattern_t *pattern)
 {
     if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
 	return TRUE;
 
     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
-	return _surface_pattern_supported ((const cairo_surface_pattern_t *) pattern);
+	return _surface_pattern_supported ((cairo_surface_pattern_t *) pattern);
 	
     return FALSE;
 }
@@ -1779,24 +1889,23 @@ _pattern_supported (const cairo_pattern_
 static cairo_int_status_t
 _operation_supported (cairo_pdf_surface_t *surface,
 		      cairo_operator_t op,
-		      const cairo_pattern_t *pattern)
+		      cairo_pattern_t *pattern)
 {
     if (! _pattern_supported (pattern))
 	return FALSE;
 
-    if (_cairo_operator_always_opaque (op))
+    /* XXX: We can probably support a fair amount more than just OVER,
+     * but this should cover many common cases at least. */
+    if (op == CAIRO_OPERATOR_OVER)
 	return TRUE;
 
-    if (_cairo_operator_always_translucent (op))
-	return FALSE;
-
-    return _cairo_pattern_is_opaque (pattern);
+    return FALSE;
 }
 
 static cairo_int_status_t
 _analyze_operation (cairo_pdf_surface_t *surface,
 		    cairo_operator_t op,
-		    const cairo_pattern_t *pattern)
+		    cairo_pattern_t *pattern)
 {
     if (_operation_supported (surface, op, pattern))
 	return CAIRO_STATUS_SUCCESS;
diff-tree c0721190438826d7222ed87c36b4e48e57ad0323 (from bef621e870e3d4038e00ed56ad40d726d5a7ca77)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 25 02:33:18 2006 -0700

    PDF: Remove unused backend functions.
    
    Since the switch to using paginated, we have a guarantee that the following functions
    will never be called. So we drop them now:
    
    	_cairo_pdf_surface_composite
    	_cairo_pdf_surface_fill_rectangles
    	_cairo_pdf_surface_composite_trapezoids
    	_cairo_pdf_surface_old_show_glyphs

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index a2e7c95..984967b 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -237,24 +237,6 @@ _cairo_pdf_surface_add_pattern (cairo_pd
     _cairo_array_append (&surface->patterns, &resource);
 }
 
-static void
-_cairo_pdf_surface_add_xobject (cairo_pdf_surface_t *surface, unsigned int id)
-{
-    cairo_pdf_resource_t resource;
-    int i, num_resources;
-
-    num_resources = _cairo_array_num_elements (&surface->xobjects);
-    for (i = 0; i < num_resources; i++) {
-	_cairo_array_copy_element (&surface->xobjects, i, &resource);
-	if (resource.id == id)
-	    return;
-    }
-
-    resource.id = id;
-    /* XXX: Should be checking the return value here. */
-    _cairo_array_append (&surface->xobjects, &resource);
-}
-
 static unsigned int
 _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha)
 {
@@ -273,24 +255,6 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_
     return _cairo_array_num_elements (&surface->alphas) - 1;
 }
 
-static void
-_cairo_pdf_surface_add_font (cairo_pdf_surface_t *surface, unsigned int id)
-{
-    cairo_pdf_resource_t resource;
-    int i, num_fonts;
-
-    num_fonts = _cairo_array_num_elements (&surface->fonts);
-    for (i = 0; i < num_fonts; i++) {
-	_cairo_array_copy_element (&surface->fonts, i, &resource);
-	if (resource.id == id)
-	    return;
-    }
-
-    resource.id = id;
-    /* XXX: Should be checking the return value here. */
-    _cairo_array_append (&surface->fonts, &resource);
-}
-
 static cairo_surface_t *
 _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t	*stream,
 					       double			 width,
@@ -741,158 +705,6 @@ emit_image_rgb_data (cairo_pdf_document_
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_int_status_t
-_cairo_pdf_surface_composite_image (cairo_pdf_surface_t	*dst,
-				    cairo_surface_pattern_t *pattern)
-{
-    cairo_pdf_document_t *document = dst->document;
-    cairo_output_stream_t *output = document->output_stream;
-    unsigned id;
-    cairo_matrix_t i2u;
-    cairo_status_t status;
-    cairo_image_surface_t *image;
-    cairo_surface_t *src;
-    void *image_extra;
-
-    src = pattern->surface;
-    status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
-    if (status)
-	return status;
-
-    status = emit_image_rgb_data (dst->document, image, &id);
-    if (status)
-	goto bail;
-
-    _cairo_pdf_surface_add_xobject (dst, id);
-
-    _cairo_pdf_surface_ensure_stream (dst);
-
-    i2u = pattern->base.matrix;
-    cairo_matrix_invert (&i2u);
-    cairo_matrix_translate (&i2u, 0, image->height);
-    cairo_matrix_scale (&i2u, image->width, -image->height);
-
-    _cairo_output_stream_printf (output,
-				 "q %f %f %f %f %f %f cm /res%d Do Q\r\n",
-				 i2u.xx, i2u.yx,
-				 i2u.xy, i2u.yy,
-				 i2u.x0, i2u.y0,
-				 id);
-
- bail:
-    _cairo_surface_release_source_image (src, image, image_extra);
-
-    return status;
-}
-
-/* The contents of the surface is already transformed into PDF units,
- * but when we composite the surface we may want to use a different
- * space.  The problem I see now is that the show_surface snippet
- * creates a surface 1x1, which in the snippet environment is the
- * entire surface.  When compositing the surface, cairo gives us the
- * 1x1 to 256x256 matrix.  This would be fine if cairo didn't actually
- * also transform the drawing to the surface.  Should the CTM be part
- * of the current target surface?
- */
-
-static cairo_int_status_t
-_cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst,
-				  cairo_surface_pattern_t *pattern)
-{
-    cairo_pdf_document_t *document = dst->document;
-    cairo_output_stream_t *output = document->output_stream;
-    cairo_matrix_t i2u;
-    cairo_pdf_stream_t *stream;
-    int num_streams, i;
-    cairo_pdf_surface_t *src;
-
-    _cairo_pdf_surface_ensure_stream (dst);
-
-    src = (cairo_pdf_surface_t *) pattern->surface;
-
-    i2u = pattern->base.matrix;
-    cairo_matrix_invert (&i2u);
-    cairo_matrix_scale (&i2u, 1.0 / src->width, 1.0 / src->height);
-
-    _cairo_output_stream_printf (output,
-				 "q %f %f %f %f %f %f cm",
-				 i2u.xx, i2u.yx,
-				 i2u.xy, i2u.yy,
-				 i2u.x0, i2u.y0);
-
-    num_streams = _cairo_array_num_elements (&src->streams);
-    for (i = 0; i < num_streams; i++) {
-	_cairo_array_copy_element (&src->streams, i, &stream);
-	_cairo_output_stream_printf (output,
-				     " /res%d Do",
-				     stream->id);
-
-	_cairo_pdf_surface_add_xobject (dst, stream->id);
-
-    }
-	
-    _cairo_output_stream_printf (output, " Q\r\n");
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-_cairo_pdf_surface_composite (cairo_operator_t	op,
-			      cairo_pattern_t	*src_pattern,
-			      cairo_pattern_t	*mask_pattern,
-			      void		*abstract_dst,
-			      int		src_x,
-			      int		src_y,
-			      int		mask_x,
-			      int		mask_y,
-			      int		dst_x,
-			      int		dst_y,
-			      unsigned int	width,
-			      unsigned int	height)
-{
-    cairo_pdf_surface_t *dst = abstract_dst;
-    cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
-
-    if (mask_pattern)
- 	return CAIRO_STATUS_SUCCESS;
-    
-    if (src_pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
-	return CAIRO_STATUS_SUCCESS;
-
-    if (src->surface->backend == &cairo_pdf_surface_backend)
-	return _cairo_pdf_surface_composite_pdf (dst, src);
-    else
-	return _cairo_pdf_surface_composite_image (dst, src);
-}
-
-static cairo_int_status_t
-_cairo_pdf_surface_fill_rectangles (void		*abstract_surface,
-				    cairo_operator_t	op,
-				    const cairo_color_t	*color,
-				    cairo_rectangle_t	*rects,
-				    int			num_rects)
-{
-    cairo_pdf_surface_t *surface = abstract_surface;
-    cairo_pdf_document_t *document = surface->document;
-    cairo_output_stream_t *output = document->output_stream;
-    int i;
-
-    _cairo_pdf_surface_ensure_stream (surface);
-
-    _cairo_output_stream_printf (output,
-				 "%f %f %f rg\r\n",
-				 color->red, color->green, color->blue);
-
-    for (i = 0; i < num_rects; i++) {
-	_cairo_output_stream_printf (output,
-				     "%d %d %d %d re f\r\n",
-				     rects[i].x, rects[i].y,
-				     rects[i].width, rects[i].height);
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 static cairo_status_t
 emit_solid_pattern (cairo_pdf_surface_t *surface,
 		    cairo_solid_pattern_t *pattern)
@@ -1352,15 +1164,6 @@ emit_pattern (cairo_pdf_surface_t *surfa
     return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
 }
 
-static double
-intersect (cairo_line_t *line, cairo_fixed_t y)
-{
-    return _cairo_fixed_to_double (line->p1.x) +
-	_cairo_fixed_to_double (line->p2.x - line->p1.x) *
-	_cairo_fixed_to_double (y - line->p1.y) /
-	_cairo_fixed_to_double (line->p2.y - line->p1.y);
-}
-
 static cairo_status_t
 _cairo_pdf_path_move_to (void *closure, cairo_point_t *point)
 {
@@ -1419,57 +1222,6 @@ _cairo_pdf_path_close_path (void *closur
 }
 
 static cairo_int_status_t
-_cairo_pdf_surface_composite_trapezoids (cairo_operator_t	op,
-					 cairo_pattern_t	*pattern,
-					 void			*abstract_dst,
-					 cairo_antialias_t	antialias,
-					 int			x_src,
-					 int			y_src,
-					 int			x_dst,
-					 int			y_dst,
-					 unsigned int		width,
-					 unsigned int		height,
-					 cairo_trapezoid_t	*traps,
-					 int			num_traps)
-{
-    cairo_pdf_surface_t *surface = abstract_dst;
-    cairo_pdf_document_t *document = surface->document;
-    cairo_output_stream_t *output = document->output_stream;
-    cairo_int_status_t status;
-    int i;
-
-    status = emit_pattern (surface, pattern);
-    if (status)
-	return status;
-
-    /* After the above switch 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);
-
-    for (i = 0; i < num_traps; i++) {
-	double left_x1, left_x2, right_x1, right_x2;
-
-	left_x1  = intersect (&traps[i].left, traps[i].top);
-	left_x2  = intersect (&traps[i].left, traps[i].bottom);
-	right_x1 = intersect (&traps[i].right, traps[i].top);
-	right_x2 = intersect (&traps[i].right, traps[i].bottom);
-
-	_cairo_output_stream_printf (output,
-				     "%f %f m %f %f l %f %f l %f %f l h\r\n",
-				     left_x1, _cairo_fixed_to_double (traps[i].top),
-				     left_x2, _cairo_fixed_to_double (traps[i].bottom),
-				     right_x2, _cairo_fixed_to_double (traps[i].bottom),
-				     right_x1, _cairo_fixed_to_double (traps[i].top));
-    }
-
-    _cairo_output_stream_printf (output,
-				 "f\r\n");
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
 _cairo_pdf_surface_copy_page (void *abstract_surface)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
@@ -1513,111 +1265,6 @@ _cairo_pdf_surface_get_extents (void		  
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_font_subset_t *
-_cairo_pdf_document_get_font (cairo_pdf_document_t	*document,
-			      cairo_scaled_font_t	*scaled_font)
-{
-    cairo_status_t status;
-    cairo_unscaled_font_t *unscaled_font;
-    cairo_font_subset_t *pdf_font;
-    unsigned int num_fonts, i;
-
-    /* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
-    if (! _cairo_scaled_font_is_ft (scaled_font))
-	return NULL;
-
-    /* XXX Why is this an ft specific function? */
-    unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font);
-
-    num_fonts = _cairo_array_num_elements (&document->fonts);
-    for (i = 0; i < num_fonts; i++) {
-	_cairo_array_copy_element (&document->fonts, i, &pdf_font);
-	if (pdf_font->unscaled_font == unscaled_font)
-	    return pdf_font;
-    }
-
-    /* FIXME: Figure out here which font backend is in use and call
-     * the appropriate constructor. */
-    pdf_font = _cairo_font_subset_create (unscaled_font);
-    if (pdf_font == NULL)
-	return NULL;
-
-    pdf_font->font_id = _cairo_pdf_document_new_object (document);
-
-    status = _cairo_array_append (&document->fonts, &pdf_font);
-    if (status) {
-	_cairo_font_subset_destroy (pdf_font);
-	return NULL;
-    }
-
-    return pdf_font;
-}
-
-static cairo_int_status_t
-_cairo_pdf_surface_old_show_glyphs (cairo_scaled_font_t	*scaled_font,
-				    cairo_operator_t	 op,
-				    cairo_pattern_t	*pattern,
-				    void		*abstract_surface,
-				    int			 source_x,
-				    int			 source_y,
-				    int			 dest_x,
-				    int			 dest_y,
-				    unsigned int	 width,
-				    unsigned int	 height,
-				    const cairo_glyph_t	*glyphs,
-				    int			 num_glyphs)
-{
-    cairo_pdf_surface_t *surface = abstract_surface;
-    cairo_pdf_document_t *document = surface->document;
-    cairo_output_stream_t *output = document->output_stream;
-    cairo_font_subset_t *pdf_font;
-    cairo_int_status_t status;
-    int i, index;
-    double det;
-
-    /* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
-    if (! _cairo_scaled_font_is_ft (scaled_font))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    pdf_font = _cairo_pdf_document_get_font (document, scaled_font);
-    if (pdf_font == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    /* Some PDF viewers (at least older versions of xpdf) have trouble with
-     * size 0 fonts. If the font size is less than 1/1000pt, ignore the
-     * font */
-    _cairo_matrix_compute_determinant (&scaled_font->scale, &det);
-    if (fabs (det) < 0.000001)
-	return CAIRO_STATUS_SUCCESS;
-    
-    status = emit_pattern (surface, pattern);
-    if (status)
-	return status;
-
-    _cairo_output_stream_printf (output,
-				 "BT /res%u 1 Tf", pdf_font->font_id);
-    for (i = 0; i < num_glyphs; i++) {
-
-	index = _cairo_font_subset_use_glyph (pdf_font, glyphs[i].index);
-
-	_cairo_output_stream_printf (output,
-				     " %f %f %f %f %f %f Tm (\\%o) Tj",
-				     scaled_font->scale.xx,
-				     scaled_font->scale.yx,
-				     -scaled_font->scale.xy,
-				     -scaled_font->scale.yy,
-				     glyphs[i].x,
-				     glyphs[i].y,
-				     index);
-    }
-    _cairo_output_stream_printf (output,
-				 " ET\r\n");
-
-    _cairo_pdf_surface_add_font (surface, pdf_font->font_id);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 static cairo_int_status_t
 _cairo_pdf_surface_intersect_clip_path (void			*dst,
 					cairo_path_fixed_t	*path,
@@ -2179,11 +1826,6 @@ _cairo_pdf_surface_paint (void			*abstra
     assert (_operation_supported (op, source));
     */
 
-#if 0
-    if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
-	return _cairo_pdf_surface_composite_image (surface, (cairo_surface_pattern_t *) source);
-#endif
-
     status = emit_pattern (surface, source);
     if (status)
 	return status;
@@ -2454,15 +2096,15 @@ static const cairo_surface_backend_t cai
     NULL, /* acquire_dest_image */
     NULL, /* release_dest_image */
     NULL, /* clone_similar */
-    _cairo_pdf_surface_composite,
-    _cairo_pdf_surface_fill_rectangles,
-    _cairo_pdf_surface_composite_trapezoids,
+    NULL, /* composite */
+    NULL, /* fill_rectangles */
+    NULL, /* composite_trapezoids */
     _cairo_pdf_surface_copy_page,
     _cairo_pdf_surface_show_page,
     NULL, /* set_clip_region */
     _cairo_pdf_surface_intersect_clip_path,
     _cairo_pdf_surface_get_extents,
-    _cairo_pdf_surface_old_show_glyphs,
+    NULL, /* old_show_glyphs */
     _cairo_pdf_surface_get_font_options,
     NULL, /* flush */
     NULL, /* mark_dirty_rectangle */


More information about the cairo-commit mailing list