|
1 Author: Jeff Muizelaar <jmuizelaar@mozilla.com> |
|
2 diff --git a/src/cairo-surface.c b/src/cairo-surface.c |
|
3 index 8278694..12f6242 100644 |
|
4 --- a/src/cairo-surface.c |
|
5 +++ b/src/cairo-surface.c |
|
6 @@ -1530,6 +1530,70 @@ _cairo_recording_surface_clone_similar (cairo_surface_t *surface, |
|
7 return CAIRO_STATUS_SUCCESS; |
|
8 } |
|
9 |
|
10 +struct acquire_source_image_data |
|
11 +{ |
|
12 + cairo_surface_t *src; |
|
13 + cairo_image_surface_t *image; |
|
14 + void *image_extra; |
|
15 +}; |
|
16 + |
|
17 +static void |
|
18 +_wrap_release_source_image (void *data) |
|
19 +{ |
|
20 + struct acquire_source_image_data *acquire_data = data; |
|
21 + _cairo_surface_release_source_image (acquire_data->src, |
|
22 + acquire_data->image, |
|
23 + acquire_data->image_extra); |
|
24 + free(data); |
|
25 +} |
|
26 + |
|
27 +static cairo_status_t |
|
28 +_wrap_image (cairo_surface_t *src, |
|
29 + cairo_image_surface_t *image, |
|
30 + void *image_extra, |
|
31 + cairo_image_surface_t **out) |
|
32 +{ |
|
33 + static cairo_user_data_key_t wrap_image_key; |
|
34 + cairo_image_surface_t *surface; |
|
35 + cairo_status_t status; |
|
36 + |
|
37 + struct acquire_source_image_data *data = malloc (sizeof (*data)); |
|
38 + if (unlikely (data == NULL)) |
|
39 + return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
|
40 + data->src = src; |
|
41 + data->image = image; |
|
42 + data->image_extra = image_extra; |
|
43 + |
|
44 + surface = (cairo_image_surface_t *) |
|
45 + _cairo_image_surface_create_with_pixman_format (image->data, |
|
46 + image->pixman_format, |
|
47 + image->width, |
|
48 + image->height, |
|
49 + image->stride); |
|
50 + status = surface->base.status; |
|
51 + if (status) { |
|
52 + free (data); |
|
53 + return status; |
|
54 + } |
|
55 + |
|
56 + status = _cairo_user_data_array_set_data (&surface->base.user_data, |
|
57 + &wrap_image_key, |
|
58 + data, |
|
59 + _wrap_release_source_image); |
|
60 + if (status) { |
|
61 + cairo_surface_destroy (&surface->base); |
|
62 + free (data); |
|
63 + return status; |
|
64 + } |
|
65 + |
|
66 + pixman_image_set_component_alpha ( |
|
67 + surface->pixman_image, |
|
68 + pixman_image_get_component_alpha (surface->pixman_image)); |
|
69 + |
|
70 + *out = surface; |
|
71 + return CAIRO_STATUS_SUCCESS; |
|
72 +} |
|
73 + |
|
74 /** |
|
75 * _cairo_surface_clone_similar: |
|
76 * @surface: a #cairo_surface_t |
|
77 @@ -1606,15 +1670,19 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, |
|
78 /* If we failed, try again with an image surface */ |
|
79 status = _cairo_surface_acquire_source_image (src, &image, &image_extra); |
|
80 if (status == CAIRO_STATUS_SUCCESS) { |
|
81 - status = |
|
82 - surface->backend->clone_similar (surface, &image->base, |
|
83 - src_x, src_y, |
|
84 - width, height, |
|
85 - clone_offset_x, |
|
86 - clone_offset_y, |
|
87 - clone_out); |
|
88 - |
|
89 - _cairo_surface_release_source_image (src, image, image_extra); |
|
90 + status = _wrap_image(src, image, image_extra, &image); |
|
91 + if (status != CAIRO_STATUS_SUCCESS) { |
|
92 + _cairo_surface_release_source_image (src, image, image_extra); |
|
93 + } else { |
|
94 + status = |
|
95 + surface->backend->clone_similar (surface, &image->base, |
|
96 + src_x, src_y, |
|
97 + width, height, |
|
98 + clone_offset_x, |
|
99 + clone_offset_y, |
|
100 + clone_out); |
|
101 + cairo_surface_destroy(&image->base); |
|
102 + } |
|
103 } |
|
104 } |
|
105 } |