diff options
author | Carl Worth <cworth@cworth.org> | 2005-05-03 08:33:32 +0000 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2005-05-03 08:33:32 +0000 |
commit | 05ccd7685420be7c7213e68462e1fcc4c01bad3c (patch) | |
tree | 1a78808e9128fc08b6424c537899ba98e3048a3c /src | |
parent | 8283381f120c0d5a4d3d770a541a576974cfdf89 (diff) |
Originally 2005-04-20 Carl Worth <cworth@cworth.org>
Remove cairo_show_surface. Add new cairo_set_source_surface.
Remove _cairo_gstate_show_surface.
Replace calls to cairo_show_surface with cairo_set_source_surface; cairo_paint.
Fix messages to prefer - over _.
Fix documentation.
Three new tests to exercise set_source_surface more completely, (two of these are expected failures dues to outstanding bugs).
Diffstat (limited to 'src')
-rw-r--r-- | src/cairo-gstate.c | 188 | ||||
-rw-r--r-- | src/cairo-png.c | 11 | ||||
-rw-r--r-- | src/cairo.c | 49 | ||||
-rw-r--r-- | src/cairo.h | 20 |
4 files changed, 41 insertions, 227 deletions
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 017b41d24..e0304a722 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -393,7 +393,7 @@ _cairo_gstate_get_target_surface (cairo_gstate_t *gstate) } cairo_status_t -_cairo_gstate_set_source (cairo_gstate_t *gstate, +_cairo_gstate_set_source (cairo_gstate_t *gstate, cairo_pattern_t *source) { if (source == NULL) @@ -1693,192 +1693,6 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path) return CAIRO_STATUS_SUCCESS; } -cairo_status_t -_cairo_gstate_show_surface (cairo_gstate_t *gstate, - cairo_surface_t *surface, - double x, - double y, - double width, - double height) -{ - - /* We are dealing with 6 coordinate spaces in this function. this makes - * it ugly. - * - * - "Image" space is the space of the surface we're reading pixels from. - * it is the surface argument to this function. The surface has a - * matrix attached to it which maps "user" space (see below) into - * image space. - * - * - "Device" space is the space of the surface we're ultimately writing - * pixels to. It is the current surface of the gstate argument to - * this function. - * - * - "User" space is an arbitrary space defined by the user, defined - * implicitly by the gstate's CTM. The CTM maps from user space to - * device space. The CTM inverse (which is also kept at all times) - * maps from device space to user space. - * - * - "Clip" space is the space of the surface being used to clip pixels - * during compositing. Space-wise, it is a bounding box (offset+size) - * within device space. This surface is usually smaller than the device - * surface (and possibly the image surface too) and logically occupies - * a bounding box around the "clip path", situated somewhere in device - * space. The clip path is already painted on the clip surface. - * - * - "Intermediate" space is the subset of the Clip space that the - * drawing will affect, and we allocate an intermediate surface - * of this size so that we can paint in it. - * - * - "Pattern" space is another arbitrary space defined in the pattern - * element of gstate. As pixels are read from image space, they are - * combined with pixels being read from pattern space and pixels - * already existing in device space. User coordinates are converted - * to pattern space, similarly, using a matrix attached to the pattern. - * (in fact, there is a 7th space in here, which is the space of the - * surface acting as a source for the pattern) - * - * To composite these spaces, we temporarily change the image surface - * so that it can be read and written in device coordinates; in a sense - * this makes it "spatially compatible" with the clip and device spaces. - * - * - * There is also some confusion about the interaction between a clip and - * a pattern; it is assumed that in this "show surface" operation a pattern - * is to be used as an auxiliary alpha mask. this might be wrong, but it's - * what we're doing now. - * - * so, to follow the operations below, remember that in the compositing - * model, each operation is always of the form ((src IN mask) OP dst). - * that's the basic operation. - * - * so the compositing we are trying to do here, in general, involves 2 - * steps, going via a temporary surface: - * - * - combining clip and pattern pixels together into a mask channel. - * this will be ((pattern IN clip) SRC temporary). it ignores the - * pixels already in the temporary, overwriting it with the - * pattern, clipped to the clip mask. - * - * - combining temporary and "image" pixels with "device" pixels, - * with a user-provided porter/duff operator. this will be - * ((image IN temporary) OP device). - * - * if there is no clip, the degenerate case is just the second step - * with pattern standing in for temporary. - * - */ - - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_matrix_t image_to_user, image_to_device, image_to_backend; - double backend_x, backend_y; - double backend_width, backend_height; - cairo_surface_pattern_t pattern; - cairo_box_t pattern_extents; - cairo_rectangle_t extents; - double origin_x, origin_y; - int src_x, src_y; - - cairo_surface_get_matrix (surface, &image_to_user); - cairo_matrix_invert (&image_to_user); - cairo_matrix_multiply (&image_to_device, &image_to_user, &gstate->ctm); - if (gstate->surface) { - cairo_matrix_t device_to_backend; - - cairo_matrix_init_translate (&device_to_backend, - gstate->surface->device_x_offset, - gstate->surface->device_y_offset); - cairo_matrix_multiply (&image_to_backend, &image_to_device, &device_to_backend); - } else { - image_to_backend = image_to_device; - } - - backend_x = x; - backend_y = y; - backend_width = width; - backend_height = height; - _cairo_matrix_transform_bounding_box (&image_to_backend, - &backend_x, &backend_y, - &backend_width, &backend_height); - - _cairo_pattern_init_for_surface (&pattern, surface); - - /* inherit surface attributes while surface attribute functions still - exist */ - pattern.base.matrix = surface->matrix; - pattern.base.filter = surface->filter; - if (surface->repeat) - pattern.base.extend = CAIRO_EXTEND_REPEAT; - else - pattern.base.extend = CAIRO_EXTEND_NONE; - - _cairo_gstate_pattern_transform (gstate, &pattern.base); - - pattern_extents.p1.x = _cairo_fixed_from_double (backend_x); - pattern_extents.p1.y = _cairo_fixed_from_double (backend_y); - pattern_extents.p2.x = _cairo_fixed_from_double (backend_x + backend_width); - pattern_extents.p2.y = _cairo_fixed_from_double (backend_y + backend_height); - _cairo_box_round_to_rectangle (&pattern_extents, &extents); - - /* XXX: This offset here isn't very clean, and it isn't even doing - * a perfect job, (there are some rounding issues with - * cairo_show_surface under the influence of cairo_scale). But it - * does address the bug demonstrated in test/translate-show-surface. - * And, this whole cairo_show_surface thing is going to be - * disappearing soon anyway. */ - origin_x = origin_y = 0.0; - _cairo_gstate_user_to_device (gstate, &origin_x, &origin_y); - src_x = (int) (origin_x + 0.5); - src_y = (int) (origin_y + 0.5); - - if (gstate->clip.surface) - { - _cairo_rectangle_intersect (&extents, &gstate->clip.rect); - - /* We only need to composite if the rectangle is not empty. */ - if (!_cairo_rectangle_empty (&extents)) { - cairo_surface_pattern_t clip_pattern; - - _cairo_pattern_init_for_surface (&clip_pattern, - gstate->clip.surface); - - status = _cairo_surface_composite (gstate->operator, - &pattern.base, - &clip_pattern.base, - gstate->surface, - src_x, src_y, - 0, 0, - extents.x, extents.y, - extents.width, extents.height); - - _cairo_pattern_fini (&clip_pattern.base); - } - } - else - { - /* XXX: The rendered size is sometimes 1 or 2 pixels short - * from what I expect. Need to fix this. - * KRH: I'm guessing this was due to rounding error when - * passing double coordinates for integer arguments. Using - * the extents rectangle should fix this, since it's properly - * rounded. Is this still the case? - */ - status = _cairo_surface_composite (gstate->operator, - &pattern.base, - NULL, - gstate->surface, - src_x, src_y, - 0, 0, - extents.x, extents.y, - extents.width, extents.height); - - } - - _cairo_pattern_fini (&pattern.base); - - return status; -} - static void _cairo_gstate_unset_font (cairo_gstate_t *gstate) { diff --git a/src/cairo-png.c b/src/cairo-png.c index 97310497f..8d1c44454 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -189,14 +189,15 @@ stdio_write_func (png_structp png, png_bytep data, png_size_t size) * @surface: a #cairo_surface_t with pixel contents * @filename: the name of a file to write to * - * Writes the image surface to the given #FILE pointer. The file - * should be opened in write mode and binary mode if applicable. + * Writes the contents of @surface to a new file @filename as a PNG + * image. * * Return value: CAIRO_STATUS_SUCCESS if the PNG file was written - * successfully. Otherwise, CAIRO_STATUS_NO_MEMORY is returned if - * memory could not be allocated for the operation, + * successfully. Otherwise, CAIRO_STATUS_NO_MEMORY if memory could not + * be allocated for the operation or * CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have - * pixel contents. + * pixel contents, or CAIRO_STATUS_WRITE_ERROR if an I/O error occurs + * while attempting to write the file. **/ cairo_status_t cairo_surface_write_to_png (cairo_surface_t *surface, diff --git a/src/cairo.c b/src/cairo.c index 301f3246e..5bda4124d 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -749,6 +749,34 @@ cairo_set_source_rgba (cairo_t *cr, } DEPRECATE(cairo_set_rgb_color, cairo_set_source_rgb); +void +cairo_set_source_surface (cairo_t *cr, + cairo_surface_t *surface, + double x, + double y) +{ + cairo_pattern_t *pattern; + cairo_matrix_t matrix; + + CAIRO_CHECK_SANITY (cr); + if (cr->status) + return; + + pattern = cairo_pattern_create_for_surface (surface); + if (!pattern) { + cr->status = CAIRO_STATUS_NO_MEMORY; + return; + } + + cairo_matrix_init_translate (&matrix, -x, -y); + cairo_pattern_set_matrix (pattern, &matrix); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + CAIRO_CHECK_SANITY (cr); +} + /** * cairo_set_source * @cr: a cairo context @@ -2181,27 +2209,6 @@ cairo_glyph_path (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs) CAIRO_CHECK_SANITY (cr); } -void -cairo_show_surface (cairo_t *cr, - cairo_surface_t *surface, - int width, - int height) -{ - double x, y; - - CAIRO_CHECK_SANITY (cr); - if (cr->status) - return; - - cairo_get_current_point (cr, &x, &y); - - cr->status = _cairo_gstate_show_surface (cr->gstate, - surface, - x, y, - width, height); - CAIRO_CHECK_SANITY (cr); -} - /** * cairo_get_operator: * @cr: a cairo context diff --git a/src/cairo.h b/src/cairo.h index 229a1dcdc..654e6d220 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -300,11 +300,6 @@ cairo_set_operator (cairo_t *cr, cairo_operator_t op); void cairo_set_source (cairo_t *cr, cairo_pattern_t *source); -/* XXX: NYI: -void -cairo_set_source_surface (cairo_t *cr, cairo_surface_t *surface); -*/ - void cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue); @@ -313,6 +308,12 @@ cairo_set_source_rgba (cairo_t *cr, double red, double green, double blue, double alpha); +void +cairo_set_source_surface (cairo_t *cr, + cairo_surface_t *surface, + double x, + double y); + /* XXX: Currently, the tolerance value is specified by the user in terms of device-space units. If I'm not mistaken, this is the only value in this API that is not expressed in user-space units. I @@ -788,15 +789,6 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font, int num_glyphs, cairo_text_extents_t *extents); -/* Image functions */ - -/* XXX: Eliminate width/height here */ -void -cairo_show_surface (cairo_t *cr, - cairo_surface_t *surface, - int width, - int height); - /* Query functions */ /* XXX: It would be nice if I could find a simpler way to make the |