summaryrefslogtreecommitdiff
path: root/src/cairo-pdf-surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-pdf-surface.c')
-rw-r--r--src/cairo-pdf-surface.c402
1 files changed, 208 insertions, 194 deletions
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 23230aa74..fee918355 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -36,9 +36,8 @@
#include "cairoint.h"
#include "cairo-pdf.h"
-/* XXX: This seems broken to me. What about users without freetype
- * that want to use a cairo PDF surface? */
-#include "cairo-ft.h"
+/* XXX: Eventually, we need to handle other font backends */
+#include "cairo-ft-private.h"
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -54,10 +53,6 @@
* - Why doesn't pages inherit /alpha%d GS dictionaries from the Pages
* object?
*
- * - Why isn't the pattern passed to composite traps instead of
- * pattern->source? If composite traps needs an image or a surface it
- * can call create_pattern().
- *
* - We embed an image in the stream each time it's composited. We
* could add generation counters to surfaces and remember the stream
* ID for a particular generation for a particular surface.
@@ -183,9 +178,6 @@ struct cairo_pdf_surface {
double width_inches;
double height_inches;
- /* HACK: Non-null if this surface was created for a pattern. */
- cairo_pattern_t *pattern;
-
cairo_pdf_document_t *document;
cairo_pdf_stream_t *current_stream;
@@ -240,8 +232,6 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend;
#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
#define SFNT_VERSION 0x00010000
-#define OFFSET_TABLE_SIZE 12
-#define TABLE_DIRECTORY_ENTRY_SIZE 16
#ifdef WORDS_BIGENDIAN
@@ -300,19 +290,15 @@ cairo_pdf_font_destroy (cairo_pdf_font_t *font)
}
static cairo_pdf_font_t *
-cairo_pdf_ft_font_create (cairo_pdf_document_t *document,
- cairo_unscaled_font_t *unscaled_font,
- cairo_font_scale_t *scale)
+cairo_pdf_ft_font_create (cairo_pdf_document_t *document,
+ cairo_unscaled_font_t *unscaled_font)
{
- cairo_font_t scaled_font;
FT_Face face;
cairo_pdf_ft_font_t *font;
unsigned long size;
int i, j;
- /* FIXME: Why do I have to pass a scaled font to get the FT_Face? */
- _cairo_font_init (&scaled_font, scale, unscaled_font);
- face = cairo_ft_font_face (&scaled_font);
+ face = _cairo_ft_unscaled_font_lock_face (unscaled_font);
/* We currently only support freetype truetype fonts. */
size = 0;
@@ -333,7 +319,8 @@ cairo_pdf_ft_font_create (cairo_pdf_document_t *document,
if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
goto fail1;
- font->face = face;
+ font->base.unscaled_font = unscaled_font;
+ _cairo_unscaled_font_reference (unscaled_font);
font->glyphs = calloc (face->num_glyphs + 1, sizeof (ft_subset_glyph_t));
if (font->glyphs == NULL)
goto fail2;
@@ -364,6 +351,8 @@ cairo_pdf_ft_font_create (cairo_pdf_document_t *document,
if (font->base.widths == NULL)
goto fail5;
+ _cairo_ft_unscaled_font_unlock_face (unscaled_font);
+
font->status = CAIRO_STATUS_SUCCESS;
return &font->base;
@@ -447,7 +436,7 @@ cairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be16 (font, 1);
- cairo_pdf_ft_font_write_be16 (font, 0);
+ cairo_pdf_ft_font_write_be16 (font, 1);
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be32 (font, 12);
@@ -764,12 +753,15 @@ cairo_pdf_ft_font_generate (void *abstract_font,
unsigned long start, end, next, checksum;
int i;
+ font->face = _cairo_ft_unscaled_font_lock_face (font->base.unscaled_font);
+
if (cairo_pdf_ft_font_write_offset_table (font))
- return font->status;
+ goto fail;
start = cairo_pdf_ft_font_align_output (font);
end = start;
+ end = 0;
for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
if (truetype_tables[i].write (font, truetype_tables[i].tag))
goto fail;
@@ -789,6 +781,9 @@ cairo_pdf_ft_font_generate (void *abstract_font,
*length = _cairo_array_num_elements (&font->output);
fail:
+ _cairo_ft_unscaled_font_unlock_face (font->base.unscaled_font);
+ font->face = NULL;
+
return font->status;
}
@@ -947,14 +942,13 @@ _cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document,
surface->width_inches = width_inches;
surface->height_inches = height_inches;
- surface->pattern = NULL;
_cairo_pdf_document_reference (document);
surface->document = document;
_cairo_array_init (&surface->streams, sizeof (cairo_pdf_stream_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_font_t));
+ _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_resource_t));
return &surface->base;
}
@@ -1102,38 +1096,46 @@ _cairo_pdf_surface_ensure_stream (cairo_pdf_surface_t *surface)
}
}
-static cairo_image_surface_t *
-_cairo_pdf_surface_get_image (void *abstract_surface)
+static cairo_status_t
+_cairo_pdf_surface_acquire_source_image (void *abstract_surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra)
{
- return NULL;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
-static cairo_status_t
-_cairo_pdf_surface_set_image (void *abstract_surface,
- cairo_image_surface_t *image)
+static void
+_cairo_pdf_surface_release_source_image (void *abstract_surface,
+ cairo_image_surface_t *image,
+ void *image_extra)
{
- return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_status_t
-_cairo_pdf_surface_set_matrix (void *abstract_surface,
- cairo_matrix_t *matrix)
+_cairo_pdf_surface_acquire_dest_image (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect,
+ void **image_extra)
{
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
-static cairo_status_t
-_cairo_pdf_surface_set_filter (void *abstract_surface,
- cairo_filter_t filter)
+static void
+_cairo_pdf_surface_release_dest_image (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t *image,
+ cairo_rectangle_t *image_rect,
+ void *image_extra)
{
- return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
-_cairo_pdf_surface_set_repeat (void *abstract_surface,
- int repeat)
+_cairo_pdf_surface_clone_similar (void *abstract_surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out)
{
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
static void *
@@ -1210,23 +1212,34 @@ emit_image_data (cairo_pdf_document_t *document,
}
static cairo_int_status_t
-_cairo_pdf_surface_composite_image (cairo_pdf_surface_t *dst,
- cairo_image_surface_t *image)
+_cairo_pdf_surface_composite_image (cairo_pdf_surface_t *dst,
+ cairo_surface_pattern_t *pattern)
{
cairo_pdf_document_t *document = dst->document;
FILE *file = document->file;
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 (!CAIRO_OK (status))
+ return status;
id = emit_image_data (dst->document, image);
- if (id == 0)
- return CAIRO_STATUS_NO_MEMORY;
+ if (id == 0) {
+ status = CAIRO_STATUS_NO_MEMORY;
+ goto bail;
+ }
_cairo_pdf_surface_add_xobject (dst, id);
_cairo_pdf_surface_ensure_stream (dst);
- cairo_matrix_copy (&i2u, &image->base.matrix);
+ cairo_matrix_copy (&i2u, &pattern->base.matrix);
cairo_matrix_invert (&i2u);
cairo_matrix_translate (&i2u, 0, image->height);
cairo_matrix_scale (&i2u, image->width, -image->height);
@@ -1238,7 +1251,10 @@ _cairo_pdf_surface_composite_image (cairo_pdf_surface_t *dst,
i2u.m[2][0], i2u.m[2][1],
id);
- return CAIRO_STATUS_SUCCESS;
+ bail:
+ _cairo_surface_release_source_image (src, image, image_extra);
+
+ return status;
}
/* The contents of the surface is already transformed into PDF units,
@@ -1253,20 +1269,19 @@ _cairo_pdf_surface_composite_image (cairo_pdf_surface_t *dst,
static cairo_int_status_t
_cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst,
- cairo_pdf_surface_t *src,
- int width, int height)
+ cairo_surface_pattern_t *pattern)
{
cairo_pdf_document_t *document = dst->document;
FILE *file = document->file;
cairo_matrix_t i2u;
cairo_pdf_stream_t *stream;
int num_streams, i;
-
- if (src->pattern != NULL)
- return CAIRO_STATUS_SUCCESS;
+ cairo_pdf_surface_t *src;
_cairo_pdf_surface_ensure_stream (dst);
+ src = (cairo_pdf_surface_t *) pattern->surface;
+
cairo_matrix_copy (&i2u, &src->base.matrix);
cairo_matrix_invert (&i2u);
cairo_matrix_scale (&i2u,
@@ -1297,8 +1312,8 @@ _cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst,
static cairo_int_status_t
_cairo_pdf_surface_composite (cairo_operator_t operator,
- cairo_surface_t *generic_src,
- cairo_surface_t *generic_mask,
+ cairo_pattern_t *src_pattern,
+ cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
@@ -1310,17 +1325,18 @@ _cairo_pdf_surface_composite (cairo_operator_t operator,
unsigned int height)
{
cairo_pdf_surface_t *dst = abstract_dst;
- cairo_pdf_surface_t *src;
- cairo_image_surface_t *image;
+ cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
- if (generic_src->backend == &cairo_pdf_surface_backend) {
- src = (cairo_pdf_surface_t *) generic_src;
- return _cairo_pdf_surface_composite_pdf (dst, src, width, height);
- }
- else {
- image = _cairo_surface_get_image (generic_src);
- return _cairo_pdf_surface_composite_image (dst, image);
- }
+ if (mask_pattern)
+ return CAIRO_STATUS_SUCCESS;
+
+ if (src_pattern->type != CAIRO_PATTERN_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
@@ -1335,9 +1351,6 @@ _cairo_pdf_surface_fill_rectangles (void *abstract_surface,
FILE *file = document->file;
int i;
- if (surface->pattern != NULL)
- return CAIRO_STATUS_SUCCESS;
-
_cairo_pdf_surface_ensure_stream (surface);
fprintf (file,
@@ -1355,23 +1368,44 @@ _cairo_pdf_surface_fill_rectangles (void *abstract_surface,
}
static void
-emit_tiling_pattern (cairo_operator_t operator,
- cairo_pdf_surface_t *dst,
- cairo_pattern_t *pattern)
+emit_solid_pattern (cairo_pdf_surface_t *surface,
+ cairo_solid_pattern_t *pattern)
+{
+ cairo_pdf_document_t *document = surface->document;
+ FILE *file = document->file;
+ unsigned int alpha;
+
+ alpha = _cairo_pdf_surface_add_alpha (surface, pattern->base.alpha);
+ _cairo_pdf_surface_ensure_stream (surface);
+ fprintf (file,
+ "%f %f %f rg /a%d gs\r\n",
+ pattern->red,
+ pattern->green,
+ pattern->blue,
+ alpha);
+}
+
+static void
+emit_surface_pattern (cairo_pdf_surface_t *dst,
+ cairo_surface_pattern_t *pattern)
{
cairo_pdf_document_t *document = dst->document;
FILE *file = document->file;
cairo_pdf_stream_t *stream;
cairo_image_surface_t *image;
+ void *image_extra;
+ cairo_status_t status;
char entries[250];
unsigned int id, alpha;
cairo_matrix_t pm;
- if (pattern->u.surface.surface->backend == &cairo_pdf_surface_backend) {
+ if (pattern->surface->backend == &cairo_pdf_surface_backend) {
return;
}
-
- image = _cairo_surface_get_image (pattern->u.surface.surface);
+
+ status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
+ if (!CAIRO_OK (status))
+ return;
_cairo_pdf_document_close_stream (document);
@@ -1382,7 +1416,7 @@ emit_tiling_pattern (cairo_operator_t operator,
cairo_matrix_set_identity (&pm);
cairo_matrix_scale (&pm, image->width, image->height);
- cairo_matrix_copy (&pm, &pattern->matrix);
+ cairo_matrix_copy (&pm, &pattern->base.matrix);
cairo_matrix_invert (&pm);
snprintf (entries, sizeof entries,
@@ -1401,6 +1435,8 @@ emit_tiling_pattern (cairo_operator_t operator,
stream = _cairo_pdf_document_open_stream (document, entries);
+ /* FIXME: emit code to show surface here. */
+
_cairo_pdf_surface_add_pattern (dst, stream->id);
_cairo_pdf_surface_ensure_stream (dst);
@@ -1408,10 +1444,12 @@ emit_tiling_pattern (cairo_operator_t operator,
fprintf (file,
"/Pattern cs /res%d scn /a%d gs\r\n",
stream->id, alpha);
+
+ _cairo_surface_release_source_image (pattern->surface, image, image_extra);
}
static unsigned int
-emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
+emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern)
{
cairo_pdf_document_t *document = surface->document;
FILE *file = document->file;
@@ -1430,12 +1468,12 @@ emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
"stream\r\n",
function_id);
- fputc (pattern->stops[0].color_char[0], file);
- fputc (pattern->stops[0].color_char[1], file);
- fputc (pattern->stops[0].color_char[2], file);
- fputc (pattern->stops[1].color_char[0], file);
- fputc (pattern->stops[1].color_char[1], file);
- fputc (pattern->stops[1].color_char[2], file);
+ fputc (pattern->stops[0].color.red * 0xff, file);
+ fputc (pattern->stops[0].color.green * 0xff, file);
+ fputc (pattern->stops[0].color.blue * 0xff, file);
+ fputc (pattern->stops[1].color.red * 0xff, file);
+ fputc (pattern->stops[1].color.green * 0xff, file);
+ fputc (pattern->stops[1].color.blue * 0xff, file);
fprintf (file,
"\r\n"
@@ -1446,7 +1484,7 @@ emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
}
static void
-emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
+emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *pattern)
{
cairo_pdf_document_t *document = surface->document;
FILE *file = document->file;
@@ -1456,16 +1494,16 @@ emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
_cairo_pdf_document_close_stream (document);
- function_id = emit_pattern_stops (surface, pattern);
+ function_id = emit_pattern_stops (surface, &pattern->base);
- cairo_matrix_copy (&p2u, &pattern->matrix);
+ cairo_matrix_copy (&p2u, &pattern->base.base.matrix);
cairo_matrix_invert (&p2u);
- x0 = pattern->u.linear.point0.x;
- y0 = pattern->u.linear.point0.y;
+ x0 = pattern->point0.x;
+ y0 = pattern->point0.y;
cairo_matrix_transform_point (&p2u, &x0, &y0);
- x1 = pattern->u.linear.point1.x;
- y1 = pattern->u.linear.point1.y;
+ x1 = pattern->point1.x;
+ y1 = pattern->point1.y;
cairo_matrix_transform_point (&p2u, &x1, &y1);
pattern_id = _cairo_pdf_document_new_object (document);
@@ -1479,16 +1517,14 @@ emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
" /ColorSpace /DeviceRGB\r\n"
" /Coords [ %f %f %f %f ]\r\n"
" /Function %d 0 R\r\n"
- " /Extend [ %s %s ]\r\n"
+ " /Extend [ true true ]\r\n"
" >>\r\n"
">>\r\n"
"endobj\r\n",
pattern_id,
document->height_inches * document->y_ppi,
x0, y0, x1, y1,
- function_id,
- (1 || pattern->extend) ? "true" : "false",
- (1 || pattern->extend) ? "true" : "false");
+ function_id);
_cairo_pdf_surface_add_pattern (surface, pattern_id);
@@ -1502,7 +1538,7 @@ emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
}
static void
-emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
+emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *pattern)
{
cairo_pdf_document_t *document = surface->document;
FILE *file = document->file;
@@ -1512,24 +1548,31 @@ emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
_cairo_pdf_document_close_stream (document);
- function_id = emit_pattern_stops (surface, pattern);
+ function_id = emit_pattern_stops (surface, &pattern->base);
- cairo_matrix_copy (&p2u, &pattern->matrix);
+ cairo_matrix_copy (&p2u, &pattern->base.base.matrix);
cairo_matrix_invert (&p2u);
- x0 = pattern->u.radial.center0.x;
- y0 = pattern->u.radial.center0.y;
- r0 = pattern->u.radial.radius0;
+ x0 = pattern->center0.x;
+ y0 = pattern->center0.y;
+ r0 = pattern->radius0;
cairo_matrix_transform_point (&p2u, &x0, &y0);
- x1 = pattern->u.radial.center1.x;
- y1 = pattern->u.radial.center1.y;
- r1 = pattern->u.radial.radius1;
+ x1 = pattern->center1.x;
+ y1 = pattern->center1.y;
+ r1 = pattern->radius1;
cairo_matrix_transform_point (&p2u, &x1, &y1);
/* FIXME: This is surely crack, but how should you scale a radius
* in a non-orthogonal coordinate system? */
cairo_matrix_transform_distance (&p2u, &r0, &r1);
+ /* FIXME: There is a difference between the cairo gradient extend
+ * semantics and PDF extend semantics. PDFs extend=false means
+ * that nothing is painted outside the gradient boundaries,
+ * whereas cairo takes this to mean that the end color is padded
+ * 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);
fprintf (file,
"%d 0 obj\r\n"
@@ -1541,16 +1584,14 @@ emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
" /ColorSpace /DeviceRGB\r\n"
" /Coords [ %f %f %f %f %f %f ]\r\n"
" /Function %d 0 R\r\n"
- " /Extend [ %s %s ]\r\n"
+ " /Extend [ true true ]\r\n"
" >>\r\n"
">>\r\n"
"endobj\r\n",
pattern_id,
document->height_inches * document->y_ppi,
x0, y0, r0, x1, y1, r1,
- function_id,
- (1 || pattern->extend) ? "true" : "false",
- (1 || pattern->extend) ? "true" : "false");
+ function_id);
_cairo_pdf_surface_add_pattern (surface, pattern_id);
@@ -1563,6 +1604,28 @@ emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
pattern_id, alpha);
}
+static void
+emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
+{
+ switch (pattern->type) {
+ case CAIRO_PATTERN_SOLID:
+ emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
+ break;
+
+ case CAIRO_PATTERN_SURFACE:
+ emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
+ break;
+
+ case CAIRO_PATTERN_LINEAR:
+ emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
+ break;
+
+ case CAIRO_PATTERN_RADIAL:
+ emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
+ break;
+ }
+}
+
static double
intersect (cairo_line_t *line, cairo_fixed_t y)
{
@@ -1574,60 +1637,23 @@ intersect (cairo_line_t *line, cairo_fixed_t y)
static cairo_int_status_t
_cairo_pdf_surface_composite_trapezoids (cairo_operator_t operator,
- cairo_surface_t *generic_src,
+ cairo_pattern_t *pattern,
void *abstract_dst,
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_surface_t *source = (cairo_pdf_surface_t *) generic_src;
cairo_pdf_document_t *document = surface->document;
- cairo_pattern_t *pattern;
FILE *file = document->file;
int i;
- unsigned int alpha;
- /* FIXME: we really just want the original pattern here, not a
- * source surface. */
- pattern = source->pattern;
-
- if (source->base.backend != &cairo_pdf_surface_backend) {
- printf ("_cairo_pdf_surface_composite_trapezoids: not a pdf source\r");
- return CAIRO_STATUS_SUCCESS;
- }
-
- if (pattern == NULL) {
- printf ("_cairo_pdf_surface_composite_trapezoids: "
- "non-pattern pdf source\r");
- return CAIRO_STATUS_SUCCESS;
- }
-
- switch (pattern->type) {
- case CAIRO_PATTERN_SOLID:
- alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha);
- _cairo_pdf_surface_ensure_stream (surface);
- fprintf (file,
- "%f %f %f rg /a%d gs\r\n",
- pattern->color.red,
- pattern->color.green,
- pattern->color.blue,
- alpha);
- break;
-
- case CAIRO_PATTERN_SURFACE:
- emit_tiling_pattern (operator, surface, pattern);
- break;
-
- case CAIRO_PATTERN_LINEAR:
- emit_linear_pattern (surface, pattern);
- break;
-
- case CAIRO_PATTERN_RADIAL:
- emit_radial_pattern (surface, pattern );
- break;
- }
+ emit_pattern (surface, pattern);
/* After the above switch the current stream should belong to this
* surface, so no need to _cairo_pdf_surface_ensure_stream() */
@@ -1686,59 +1712,48 @@ _cairo_pdf_surface_set_clip_region (void *abstract_surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
-static cairo_int_status_t
-_cairo_pdf_surface_create_pattern (void *abstract_surface,
- cairo_pattern_t *pattern,
- cairo_box_t *extents)
-{
- cairo_pdf_surface_t *surface = abstract_surface;
- cairo_pdf_surface_t *source;
-
- source = (cairo_pdf_surface_t *)
- _cairo_pdf_surface_create_for_document (surface->document, 0, 0);
- source->pattern = pattern;
- pattern->source = &source->base;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
static cairo_pdf_font_t *
_cairo_pdf_document_get_font (cairo_pdf_document_t *document,
- cairo_unscaled_font_t *unscaled_font,
- cairo_font_scale_t *scale)
+ cairo_font_t *font)
{
- cairo_pdf_font_t *font;
+ cairo_unscaled_font_t *unscaled_font;
+ cairo_pdf_font_t *pdf_font;
unsigned int num_fonts, i;
+ unscaled_font = _cairo_ft_font_get_unscaled_font (font);
+
num_fonts = _cairo_array_num_elements (&document->fonts);
for (i = 0; i < num_fonts; i++) {
- _cairo_array_copy_element (&document->fonts, i, &font);
- if (font->unscaled_font == unscaled_font)
- return font;
+ _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. */
- font = cairo_pdf_ft_font_create (document, unscaled_font, scale);
- if (font == NULL)
+ pdf_font = cairo_pdf_ft_font_create (document, unscaled_font);
+ if (pdf_font == NULL)
return NULL;
- if (_cairo_array_append (&document->fonts, &font, 1) == NULL) {
- cairo_pdf_font_destroy (font);
+ if (_cairo_array_append (&document->fonts, &pdf_font, 1) == NULL) {
+ cairo_pdf_font_destroy (pdf_font);
return NULL;
}
- return font;
+ return pdf_font;
}
static cairo_status_t
-_cairo_pdf_surface_show_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+_cairo_pdf_surface_show_glyphs (cairo_font_t *font,
cairo_operator_t operator,
- cairo_surface_t *source,
+ 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)
{
@@ -1748,23 +1763,23 @@ _cairo_pdf_surface_show_glyphs (cairo_unscaled_font_t *font,
cairo_pdf_font_t *pdf_font;
int i, index;
- pdf_font = _cairo_pdf_document_get_font (document, font, scale);
+ pdf_font = _cairo_pdf_document_get_font (document, font);
if (pdf_font == NULL)
return CAIRO_STATUS_NO_MEMORY;
- _cairo_pdf_surface_ensure_stream (surface);
+ emit_pattern (surface, pattern);
- fprintf (file, "0 0 0 rg BT /res%u 1 Tf", pdf_font->font_id);
+ fprintf (file, "BT /res%u 1 Tf", pdf_font->font_id);
for (i = 0; i < num_glyphs; i++) {
index = cairo_pdf_font_use_glyph (pdf_font, glyphs[i].index);
fprintf (file,
- " %f %f %f %f %f %f Tm (%c) Tj",
- scale->matrix[0][0],
- scale->matrix[0][1],
- scale->matrix[1][0],
- -scale->matrix[1][1],
+ " %f %f %f %f %f %f Tm (\\%o) Tj",
+ font->scale.matrix[0][0],
+ font->scale.matrix[0][1],
+ font->scale.matrix[1][0],
+ -font->scale.matrix[1][1],
glyphs[i].x,
glyphs[i].y,
index);
@@ -1780,18 +1795,17 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
_cairo_pdf_surface_create_similar,
_cairo_pdf_surface_destroy,
_cairo_pdf_surface_pixels_per_inch,
- _cairo_pdf_surface_get_image,
- _cairo_pdf_surface_set_image,
- _cairo_pdf_surface_set_matrix,
- _cairo_pdf_surface_set_filter,
- _cairo_pdf_surface_set_repeat,
+ _cairo_pdf_surface_acquire_source_image,
+ _cairo_pdf_surface_release_source_image,
+ _cairo_pdf_surface_acquire_dest_image,
+ _cairo_pdf_surface_release_dest_image,
+ _cairo_pdf_surface_clone_similar,
_cairo_pdf_surface_composite,
_cairo_pdf_surface_fill_rectangles,
_cairo_pdf_surface_composite_trapezoids,
_cairo_pdf_surface_copy_page,
_cairo_pdf_surface_show_page,
_cairo_pdf_surface_set_clip_region,
- _cairo_pdf_surface_create_pattern,
_cairo_pdf_surface_show_glyphs
};
@@ -1930,8 +1944,8 @@ _cairo_pdf_document_write_fonts (cairo_pdf_document_t *document)
fprintf (file,
"%d 0 obj\r\n"
"<< /Type /FontDescriptor\r\n"
- " /FontName /%s\r\n"
- " /Flags 32\r\n"
+ " /FontName /7%s\r\n"
+ " /Flags 4\r\n"
" /FontBBox [ %ld %ld %ld %ld ]\r\n"
" /ItalicAngle 0\r\n"
" /Ascent %ld\r\n"