summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2005-07-13 12:32:51 +0000
committerKristian Høgsberg <krh@redhat.com>2005-07-13 12:32:51 +0000
commit3a469446376eb23bd4a852417b0a319b914805b9 (patch)
treeb29b928aeb1669cc1649b4c0a13eadb29f2f6e41
parentaafc2e749725fab0684cce6e36b130f838696912 (diff)
Use the _cairo_surface_*() functions when replaying.
Fold the "locate fallbacks" pass into the postscript output pass, and add a simple, first implementation of image fallbacks.
-rw-r--r--ChangeLog9
-rw-r--r--src/cairo-meta-surface-private.h1
-rw-r--r--src/cairo-meta-surface.c35
-rw-r--r--src/cairo-ps-surface.c286
4 files changed, 163 insertions, 168 deletions
diff --git a/ChangeLog b/ChangeLog
index 81ee0a562..497386c16 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-13 Kristian Høgsberg <krh@redhat.com>
+
+ * src/cairo-meta-surface.c: (_cairo_meta_surface_replay): Use
+ the _cairo_surface_*() functions when replaying.
+
+ * src/cairo-ps-surface.c: Fold the "locate fallbacks" pass into
+ the postscript output pass, and add a simple, first implementation
+ of image fallbacks.
+
2005-07-13 Carl Worth <cworth@cworth.org>
* src/cairoint.h:
diff --git a/src/cairo-meta-surface-private.h b/src/cairo-meta-surface-private.h
index 49cc45617..234c6ccfc 100644
--- a/src/cairo-meta-surface-private.h
+++ b/src/cairo-meta-surface-private.h
@@ -90,6 +90,7 @@ typedef struct _cairo_command_composite_trapezoids {
typedef struct _cairo_command_set_clip_region {
cairo_command_type_t type;
pixman_region16_t *region;
+ unsigned int serial;
} cairo_command_set_clip_region_t;
typedef struct _cairo_command_intersect_clip_path {
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index 182bb13f1..ae869f0ed 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -293,6 +293,8 @@ _cairo_meta_surface_set_clip_region (void *abstract_surface,
command->region = NULL;
}
+ command->serial = meta->base.current_clip_serial;
+
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
if (command->region)
pixman_region_destroy (command->region);
@@ -490,9 +492,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
command = elements[i];
switch (command->type) {
case CAIRO_COMMAND_COMPOSITE:
- if (target->backend->composite == NULL)
- break;
- status = target->backend->composite
+ status = _cairo_surface_composite
(command->composite.operator,
&command->composite.src_pattern.base,
command->composite.mask_pattern_pointer,
@@ -508,9 +508,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
break;
case CAIRO_COMMAND_FILL_RECTANGLES:
- if (target->backend->fill_rectangles == NULL)
- break;
- status = target->backend->fill_rectangles
+ status = _cairo_surface_fill_rectangles
(target,
command->fill_rectangles.operator,
&command->fill_rectangles.color,
@@ -519,9 +517,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
break;
case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS:
- if (target->backend->composite_trapezoids == NULL)
- break;
- status = target->backend->composite_trapezoids
+ status = _cairo_surface_composite_trapezoids
(command->composite_trapezoids.operator,
&command->composite_trapezoids.pattern.base,
target,
@@ -536,17 +532,19 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
break;
case CAIRO_COMMAND_SET_CLIP_REGION:
- if (target->backend->set_clip_region == NULL)
- break;
- status = target->backend->set_clip_region
+ status = _cairo_surface_set_clip_region
(target,
- command->set_clip_region.region);
+ command->set_clip_region.region,
+ command->set_clip_region.serial);
break;
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
+ /* XXX Meta surface clipping is broken and requires some
+ * cairo-gstate.c rewriting. Work around it for now. */
if (target->backend->intersect_clip_path == NULL)
break;
- status = target->backend->intersect_clip_path
+
+ status = _cairo_surface_intersect_clip_path
(target,
command->intersect_clip_path.path_pointer,
command->intersect_clip_path.fill_rule,
@@ -554,9 +552,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
break;
case CAIRO_COMMAND_SHOW_GLYPHS:
- if (target->backend->show_glyphs == NULL)
- break;
- status = target->backend->show_glyphs
+ status = _cairo_surface_show_glyphs
(command->show_glyphs.scaled_font,
command->show_glyphs.operator,
&command->show_glyphs.pattern.base,
@@ -572,9 +568,12 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
break;
case CAIRO_COMMAND_FILL_PATH:
+ /* XXX Meta surface fill_path is broken and requires some
+ * cairo-gstate.c rewriting. Work around it for now. */
if (target->backend->fill_path == NULL)
break;
- status = target->backend->fill_path
+
+ status = _cairo_surface_fill_path
(command->fill_path.operator,
&command->fill_path.pattern.base,
target,
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 140469323..5e26e9418 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -81,11 +81,6 @@ static cairo_int_status_t
_cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
cairo_surface_t *page, int page_number);
-static cairo_int_status_t
-_cairo_ps_surface_render_fallbacks (cairo_ps_surface_t *surface,
- cairo_surface_t *page);
-
-
static cairo_surface_t *
_cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
double width,
@@ -550,11 +545,60 @@ _cairo_ps_surface_write_font_subsets (cairo_ps_surface_t *surface)
return CAIRO_STATUS_SUCCESS;
}
+typedef struct _cairo_ps_fallback_area cairo_ps_fallback_area_t;
+struct _cairo_ps_fallback_area {
+ int x, y;
+ unsigned int width, height;
+ cairo_ps_fallback_area_t *next;
+};
+
typedef struct _ps_output_surface {
cairo_surface_t base;
cairo_ps_surface_t *parent;
+ cairo_ps_fallback_area_t *fallback_areas;
} ps_output_surface_t;
+static cairo_int_status_t
+_ps_output_add_fallback_area (ps_output_surface_t *surface,
+ int x, int y,
+ unsigned int width,
+ unsigned int height)
+{
+ cairo_ps_fallback_area_t *area;
+
+ /* FIXME: Do a better job here. Ideally, we would use a 32 bit
+ * region type, but probably just computing bounding boxes would
+ * also work fine. */
+
+ area = malloc (sizeof (cairo_ps_fallback_area_t));
+ if (area == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ area->x = x;
+ area->y = y;
+ area->width = width;
+ area->height = height;
+ area->next = surface->fallback_areas;
+
+ surface->fallback_areas = area;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_ps_output_finish (void *abstract_surface)
+{
+ ps_output_surface_t *surface = abstract_surface;
+ cairo_ps_fallback_area_t *area, *next;
+
+ for (area = surface->fallback_areas; area != NULL; area = next) {
+ next = area->next;
+ free (area);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
static cairo_bool_t
color_is_gray (cairo_color_t *color)
{
@@ -564,6 +608,24 @@ color_is_gray (cairo_color_t *color)
fabs (color->red - color->blue) < epsilon);
}
+static cairo_bool_t
+pattern_is_translucent (cairo_pattern_t *abstract_pattern)
+{
+ cairo_pattern_union_t *pattern;
+
+ pattern = (cairo_pattern_union_t *) abstract_pattern;
+ switch (pattern->base.type) {
+ case CAIRO_PATTERN_SOLID:
+ return pattern->solid.color.alpha < 0.9;
+ case CAIRO_PATTERN_SURFACE:
+ case CAIRO_PATTERN_LINEAR:
+ case CAIRO_PATTERN_RADIAL:
+ return FALSE;
+ }
+
+ ASSERT_NOT_REACHED;
+}
+
/* PS Output - this section handles output of the parts of the meta
* surface we can render natively in PS. */
@@ -872,6 +934,9 @@ _ps_output_composite_trapezoids (cairo_operator_t operator,
cairo_output_stream_t *stream = surface->parent->stream;
int i;
+ if (pattern_is_translucent (pattern))
+ return _ps_output_add_fallback_area (surface, x_dst, y_dst, width, height);
+
_cairo_output_stream_printf (stream,
"%% _ps_output_composite_trapezoids\n");
@@ -1051,6 +1116,9 @@ _ps_output_show_glyphs (cairo_scaled_font_t *scaled_font,
if (! _cairo_scaled_font_is_ft (scaled_font))
return CAIRO_INT_STATUS_UNSUPPORTED;
+ if (pattern_is_translucent (pattern))
+ return _ps_output_add_fallback_area (surface, dest_x, dest_y, width, height);
+
_cairo_output_stream_printf (stream,
"%% _ps_output_show_glyphs\n");
@@ -1137,7 +1205,7 @@ _ps_output_fill_path (cairo_operator_t operator,
static const cairo_surface_backend_t ps_output_backend = {
NULL, /* create_similar */
- NULL, /* finish */
+ _ps_output_finish,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* acquire_dest_image */
@@ -1156,177 +1224,95 @@ static const cairo_surface_backend_t ps_output_backend = {
};
static cairo_int_status_t
-_cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
- cairo_surface_t *page, int page_number)
+_ps_output_render_fallbacks (cairo_surface_t *surface,
+ cairo_surface_t *page)
{
ps_output_surface_t *ps_output;
+ cairo_surface_t *image;
cairo_int_status_t status;
+ cairo_matrix_t matrix;
+ int width, height;
- _cairo_output_stream_printf (surface->stream,
- "%%%%Page: %d\n"
- "gsave\n",
- page_number);
+ ps_output = (ps_output_surface_t *) surface;
+ if (ps_output->fallback_areas == NULL)
+ return CAIRO_STATUS_SUCCESS;
- ps_output = malloc (sizeof (ps_output_surface_t));
- if (ps_output == NULL)
+ width = ps_output->parent->width * ps_output->parent->x_dpi / 72;
+ height = ps_output->parent->height * ps_output->parent->y_dpi / 72;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ if (image == NULL)
return CAIRO_STATUS_NO_MEMORY;
- _cairo_surface_init (&ps_output->base, &ps_output_backend);
- ps_output->parent = surface;
- status = _cairo_meta_surface_replay (page, &ps_output->base);
- cairo_surface_destroy (&ps_output->base);
+ status = _cairo_surface_fill_rectangle (image,
+ CAIRO_OPERATOR_SOURCE,
+ CAIRO_COLOR_WHITE,
+ 0, 0, width, height);
+ if (status)
+ goto bail;
- _cairo_ps_surface_render_fallbacks (surface, page);
+ status = _cairo_meta_surface_replay (page, image);
+ if (status)
+ goto bail;
- _cairo_output_stream_printf (surface->stream,
- "showpage\n"
- "grestore\n"
- "%%%%EndPage\n");
-
- return status;
-}
+ matrix.xx = 1;
+ matrix.xy = 0;
+ matrix.yx = 0;
+ matrix.yy = 1;
+ matrix.x0 = 0;
+ matrix.y0 = 0;
-typedef struct _cairo_ps_fallback_area cairo_ps_fallback_area_t;
-struct _cairo_ps_fallback_area {
- /* area */
- cairo_ps_fallback_area_t *next;
-};
+ status = emit_image (ps_output->parent,
+ (cairo_image_surface_t *) image, &matrix);
-typedef struct _cairo_ps_fallback_info cairo_ps_fallback_info_t;
-struct _cairo_ps_fallback_info {
- cairo_ps_fallback_area_t *fallback_areas;
-};
+ bail:
+ cairo_surface_destroy (image);
-/* XXX: This code is not compiling correctly (missing return values),
- * but also appears to not be used currently. I'm turning it off for
- * now. */
-#if 0
-static cairo_int_status_t
-_cairo_ps_fallback_info_add_area (cairo_ps_fallback_info_t *info,
- int x, int y,
- unsigned int width,
- unsigned int height)
-{
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
-static cairo_bool_t
-_pattern_is_translucent (cairo_pattern_t *abstract_pattern)
+static cairo_surface_t *
+_ps_output_surface_create (cairo_ps_surface_t *parent)
{
- cairo_pattern_union_t *pattern;
+ ps_output_surface_t *ps_output;
- pattern = (cairo_pattern_union_t *) abstract_pattern;
- switch (pattern->base.type) {
- case CAIRO_PATTERN_SOLID:
- return pattern->solid.color.alpha < 0.999;
- case CAIRO_PATTERN_SURFACE:
- case CAIRO_PATTERN_LINEAR:
- case CAIRO_PATTERN_RADIAL:
- return FALSE;
- }
+ ps_output = malloc (sizeof (ps_output_surface_t));
+ if (ps_output == NULL)
+ return NULL;
- ASSERT_NOT_REACHED;
- return FALSE;
-}
+ _cairo_surface_init (&ps_output->base, &ps_output_backend);
+ ps_output->parent = parent;
+ ps_output->fallback_areas = NULL;
-static cairo_int_status_t
-_ps_locate_fallbacks_composite (cairo_operator_t operator,
- 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)
-{
+ return &ps_output->base;
}
static cairo_int_status_t
-_ps_locate_fallbacks_fill_rectangles (void *abstract_surface,
- cairo_operator_t operator,
- const cairo_color_t *color,
- cairo_rectangle_t *rects,
- int num_rects)
+_cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
+ cairo_surface_t *page, int page_number)
{
-}
+ cairo_surface_t *ps_output;
+ cairo_int_status_t status;
-static cairo_int_status_t
-_ps_locate_fallbacks_composite_trapezoids (cairo_operator_t operator,
- 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_ps_fallback_info_t *info;
+ _cairo_output_stream_printf (surface->stream,
+ "%%%%Page: %d\n"
+ "gsave\n",
+ page_number);
- info = abstract_dst;
+ ps_output = _ps_output_surface_create (surface);
+ if (ps_output == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
- if (_pattern_is_translucent (pattern))
- _cairo_ps_fallback_info_add_area (info, x_dst, y_dst, width, height);
-}
+ status = _cairo_meta_surface_replay (page, ps_output);
-static cairo_int_status_t
-_ps_locate_fallbacks_show_glyphs (cairo_scaled_font_t *scaled_font,
- cairo_operator_t operator,
- 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)
-{
- return CAIRO_STATUS_SUCCESS;
-}
+ _ps_output_render_fallbacks (ps_output, page);
-static cairo_int_status_t
-_ps_locate_fallbacks_fill_path (cairo_operator_t operator,
- cairo_pattern_t *pattern,
- void *abstract_dst,
- cairo_path_fixed_t *path,
- cairo_fill_rule_t fill_rule,
- double tolerance)
-{
- return CAIRO_STATUS_SUCCESS;
-}
+ cairo_surface_destroy (ps_output);
-static const cairo_surface_backend_t ps_locate_fallbacks_backend = {
- NULL, /* create_similar */
- NULL, /* finish */
- NULL, /* acquire_source_image */
- NULL, /* release_source_image */
- NULL, /* acquire_dest_image */
- NULL, /* release_dest_image */
- NULL, /* clone_similar */
- _ps_locate_fallbacks_composite,
- _ps_locate_fallbacks_fill_rectangles,
- _ps_locate_fallbacks_composite_trapezoids,
- NULL, /* copy_page */
- NULL, /* show_page */
- NULL, /* set_clip_region */
- NULL, /* intersect_clip_path */
- NULL, /* get_extents */
- _ps_locate_fallbacks_show_glyphs,
- _ps_locate_fallbacks_fill_path
-};
-#endif
+ _cairo_output_stream_printf (surface->stream,
+ "showpage\n"
+ "grestore\n"
+ "%%%%EndPage\n");
-static cairo_int_status_t
-_cairo_ps_surface_render_fallbacks (cairo_ps_surface_t *surface,
- cairo_surface_t *page)
-{
- return CAIRO_STATUS_SUCCESS;
+ return status;
}