diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c index 3d6d4a555..489573aa3 100644 --- a/src/cairo-surface-subsurface.c +++ b/src/cairo-surface-subsurface.c @@ -422,10 +422,34 @@ static const cairo_surface_backend_t _cairo_surface_subsurface_backend = { _cairo_surface_subsurface_snapshot, }; +/** + * cairo_surface_create_for_rectangle: + * @target: an existing surface for which the sub-surface will point to + * @x: the x-origin of the sub-surface from the top-left of the target surface (in device-space units) + * @y: the y-origin of the sub-surface from the top-left of the target surface (in device-space units) + * @width: width of the sub-surface (in device-space units) + * @height: height of the sub-surface (in device-space units) + * + * Create a new surface that is a rectangle within the target surface. + * All operations drawn to this surface are then clipped and translated + * onto the target surface. Nothing drawn via this sub-surface outside of + * its bounds is drawn onto the target surface, making this a useful method + * for passing constrained child surfaces to library routines that draw + * directly onto the parent surface, i.e. with no further backend allocations, + * double buffering or copies. + * + * Return value: a pointer to the newly allocated surface. The caller + * owns the surface and should call cairo_surface_destroy() when done + * with it. + * + * This function always returns a valid pointer, but it will return a + * pointer to a "nil" surface if @other is already in an error state + * or any other error occurs. + **/ cairo_surface_t * -cairo_surface_create_for_region (cairo_surface_t *target, - int x, int y, - int width, int height) +cairo_surface_create_for_rectangle (cairo_surface_t *target, + double x, double y, + double width, double height) { cairo_surface_subsurface_t *surface; cairo_rectangle_int_t target_extents; @@ -444,10 +468,11 @@ cairo_surface_create_for_region (cairo_surface_t *target, target->content); surface->base.type = target->type; - surface->extents.x = x; - surface->extents.y = y; - surface->extents.width = width; - surface->extents.height = height; + /* XXX forced integer alignment */ + surface->extents.x = ceil (x); + surface->extents.y = ceil (y); + surface->extents.width = floor (x + width) - surface->extents.x; + surface->extents.height = floor (y + height) - surface->extents.y; if (_cairo_surface_get_extents (target, &target_extents)) is_empty = _cairo_rectangle_intersect (&surface->extents, &target_extents); diff --git a/src/cairo.h b/src/cairo.h index 529a6f500..a2d37f9ce 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2049,11 +2049,11 @@ cairo_surface_create_similar (cairo_surface_t *other, int height); cairo_public cairo_surface_t * -cairo_surface_create_for_region (cairo_surface_t *target, - int x, - int y, - int width, - int height); +cairo_surface_create_for_rectangle (cairo_surface_t *target, + double x, + double y, + double width, + double height); cairo_public cairo_surface_t * cairo_surface_reference (cairo_surface_t *surface); diff --git a/test/subsurface-repeat.c b/test/subsurface-repeat.c index 59c3c5440..849c0dfd2 100644 --- a/test/subsurface-repeat.c +++ b/test/subsurface-repeat.c @@ -35,8 +35,8 @@ draw (cairo_t *cr, int width, int height) cairo_paint (cr); /* fill the centre */ - region = cairo_surface_create_for_region (cairo_get_target (cr), - 0, 0, 20, 20); + region = cairo_surface_create_for_rectangle (cairo_get_target (cr), + 0, 0, 20, 20); cr_region = cairo_create (region); cairo_surface_destroy (region); diff --git a/test/subsurface-similar-repeat.c b/test/subsurface-similar-repeat.c index ad63cc8de..492bc7744 100644 --- a/test/subsurface-similar-repeat.c +++ b/test/subsurface-similar-repeat.c @@ -46,7 +46,7 @@ draw (cairo_t *cr, int width, int height) cairo_destroy (cr_region); /* fill the centre */ - region = cairo_surface_create_for_region (similar, 20, 20, 20, 20); + region = cairo_surface_create_for_rectangle (similar, 20, 20, 20, 20); cairo_surface_destroy (similar); cr_region = cairo_create (region); cairo_surface_destroy (region); diff --git a/test/subsurface.c b/test/subsurface.c index f32588859..3ccc4692d 100644 --- a/test/subsurface.c +++ b/test/subsurface.c @@ -41,8 +41,8 @@ draw (cairo_t *cr, int width, int height) cairo_text_extents_t extents; char buf[2] = { text[i], '\0' }; - region[i] = cairo_surface_create_for_region (cairo_get_target (cr), - 20 * i, 0, 20, 20); + region[i] = cairo_surface_create_for_rectangle (cairo_get_target (cr), + 20 * i, 0, 20, 20); cr_region = cairo_create (region[i]); cairo_surface_destroy (region[i]); diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index d1685e58b..754a27e08 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -5277,22 +5277,22 @@ static csi_status_t _subsurface (csi_t *ctx) { csi_object_t obj; - long x, y, width, height; + double x, y, width, height; cairo_surface_t *target; csi_status_t status; check (5); - status = _csi_ostack_get_integer (ctx, 0, &height); + status = _csi_ostack_get_number (ctx, 0, &height); if (_csi_unlikely (status)) return status; - status = _csi_ostack_get_integer (ctx, 1, &width); + status = _csi_ostack_get_number (ctx, 1, &width); if (_csi_unlikely (status)) return status; - status = _csi_ostack_get_integer (ctx, 2, &y); + status = _csi_ostack_get_number (ctx, 2, &y); if (_csi_unlikely (status)) return status; - status = _csi_ostack_get_integer (ctx, 3, &x); + status = _csi_ostack_get_number (ctx, 3, &x); if (_csi_unlikely (status)) return status; status = _csi_ostack_get_surface (ctx, 4, &target); @@ -5300,7 +5300,7 @@ _subsurface (csi_t *ctx) return status; obj.type = CSI_OBJECT_TYPE_SURFACE; - obj.datum.surface = cairo_surface_create_for_region (target, x, y, width, height); + obj.datum.surface = cairo_surface_create_for_rectangle (target, x, y, width, height); pop (5); return push (&obj); } diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c index 01eadf4d7..5a0a44a8d 100644 --- a/util/cairo-trace/trace.c +++ b/util/cairo-trace/trace.c @@ -3495,16 +3495,16 @@ cairo_surface_create_similar (cairo_surface_t *other, } cairo_surface_t * -cairo_surface_create_for_region (cairo_surface_t *target, - int x, int y, - int width, int height) +cairo_surface_create_for_rectangle (cairo_surface_t *target, + double x, double y, + double width, double height) { cairo_surface_t *ret; long surface_id; _enter_trace (); - ret = DLCALL (cairo_surface_create_for_region, target, x, y, width, height); + ret = DLCALL (cairo_surface_create_for_rectangle, target, x, y, width, height); surface_id = _create_surface_id (ret); _emit_line_info (); @@ -3518,7 +3518,7 @@ cairo_surface_create_for_region (cairo_surface_t *target, _trace_printf ("dup "); else _trace_printf ("%d index ", current_stack_depth - obj->operand - 1); - _trace_printf ("%d %d %d %d subsurface %% s%ld\n", + _trace_printf ("%f %f %f %f subsurface %% s%ld\n", x, y, width, height, surface_id);