diff options
author | Kristian Høgsberg <krh@redhat.com> | 2005-07-13 12:32:51 +0000 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2005-07-13 12:32:51 +0000 |
commit | 3a469446376eb23bd4a852417b0a319b914805b9 (patch) | |
tree | b29b928aeb1669cc1649b4c0a13eadb29f2f6e41 | |
parent | aafc2e749725fab0684cce6e36b130f838696912 (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-- | ChangeLog | 9 | ||||
-rw-r--r-- | src/cairo-meta-surface-private.h | 1 | ||||
-rw-r--r-- | src/cairo-meta-surface.c | 35 | ||||
-rw-r--r-- | src/cairo-ps-surface.c | 286 |
4 files changed, 163 insertions, 168 deletions
@@ -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; } |