[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