summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2005-05-03 08:33:32 +0000
committerCarl Worth <cworth@cworth.org>2005-05-03 08:33:32 +0000
commit05ccd7685420be7c7213e68462e1fcc4c01bad3c (patch)
tree1a78808e9128fc08b6424c537899ba98e3048a3c /src
parent8283381f120c0d5a4d3d770a541a576974cfdf89 (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.c188
-rw-r--r--src/cairo-png.c11
-rw-r--r--src/cairo.c49
-rw-r--r--src/cairo.h20
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