|
1 changeset: 29338:f2a10f325734 |
|
2 tag: qtip |
|
3 tag: tip |
|
4 tag: win32-raster-mask2.patch |
|
5 tag: qbase |
|
6 user: Jeff Muizelaar <jmuizelaar@mozilla.com> |
|
7 date: Mon Jun 22 14:26:07 2009 -0400 |
|
8 summary: imported patch win32-raster-mask2.patch |
|
9 |
|
10 diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c |
|
11 --- a/gfx/cairo/cairo/src/cairo-image-surface.c |
|
12 +++ b/gfx/cairo/cairo/src/cairo-image-surface.c |
|
13 @@ -1232,27 +1232,27 @@ typedef struct _cairo_image_surface_span |
|
14 cairo_composite_rectangles_t composite_rectangles; |
|
15 } cairo_image_surface_span_renderer_t; |
|
16 |
|
17 -static cairo_status_t |
|
18 -_cairo_image_surface_span_renderer_render_row ( |
|
19 - void *abstract_renderer, |
|
20 +void |
|
21 +_cairo_image_surface_span_render_row ( |
|
22 int y, |
|
23 const cairo_half_open_span_t *spans, |
|
24 - unsigned num_spans) |
|
25 + unsigned num_spans, |
|
26 + cairo_image_surface_t *mask, |
|
27 + const cairo_composite_rectangles_t *rects) |
|
28 { |
|
29 - cairo_image_surface_span_renderer_t *renderer = abstract_renderer; |
|
30 - int xmin = renderer->composite_rectangles.mask.x; |
|
31 - int xmax = xmin + renderer->composite_rectangles.width; |
|
32 + int xmin = rects->mask.x; |
|
33 + int xmax = xmin + rects->width; |
|
34 uint8_t *row; |
|
35 int prev_x = xmin; |
|
36 int prev_alpha = 0; |
|
37 unsigned i; |
|
38 |
|
39 /* Make sure we're within y-range. */ |
|
40 - y -= renderer->composite_rectangles.mask.y; |
|
41 - if (y < 0 || y >= renderer->composite_rectangles.height) |
|
42 + y -= rects->mask.y; |
|
43 + if (y < 0 || y >= rects->height) |
|
44 return CAIRO_STATUS_SUCCESS; |
|
45 |
|
46 - row = (uint8_t*)(renderer->mask->data) + y*(size_t)renderer->mask->stride - xmin; |
|
47 + row = (uint8_t*)(mask->data) + y*(size_t)mask->stride - xmin; |
|
48 |
|
49 /* Find the first span within x-range. */ |
|
50 for (i=0; i < num_spans && spans[i].x < xmin; i++) {} |
|
51 @@ -1286,7 +1286,17 @@ _cairo_image_surface_span_renderer_rende |
|
52 if (prev_alpha != 0 && prev_x < xmax) { |
|
53 memset(row + prev_x, prev_alpha, xmax - prev_x); |
|
54 } |
|
55 +} |
|
56 |
|
57 +static cairo_status_t |
|
58 +_cairo_image_surface_span_renderer_render_row ( |
|
59 + void *abstract_renderer, |
|
60 + int y, |
|
61 + const cairo_half_open_span_t *spans, |
|
62 + unsigned num_spans) |
|
63 +{ |
|
64 + cairo_image_surface_span_renderer_t *renderer = abstract_renderer; |
|
65 + _cairo_image_surface_span_render_row (y, spans, num_spans, renderer->mask, &renderer->composite_rectangles); |
|
66 return CAIRO_STATUS_SUCCESS; |
|
67 } |
|
68 |
|
69 diff --git a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c |
|
70 --- a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c |
|
71 +++ b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c |
|
72 @@ -295,9 +295,9 @@ typedef int grid_area_t; |
|
73 #elif GRID_XY == 15 |
|
74 # define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) |
|
75 #elif GRID_XY == 2*256*15 |
|
76 -# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4)) >> 9) |
|
77 +# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9) |
|
78 #else |
|
79 -# define GRID_AREA_TO_ALPHA(c) ((c)*255 / GRID_XY) /* tweak me for rounding */ |
|
80 +# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY) |
|
81 #endif |
|
82 |
|
83 #define UNROLL3(x) x x x |
|
84 diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c |
|
85 --- a/gfx/cairo/cairo/src/cairo-win32-surface.c |
|
86 +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c |
|
87 @@ -2048,6 +2048,148 @@ _cairo_win32_surface_reset (void *abstra |
|
88 return CAIRO_STATUS_SUCCESS; |
|
89 } |
|
90 |
|
91 +typedef struct _cairo_win32_surface_span_renderer { |
|
92 + cairo_span_renderer_t base; |
|
93 + |
|
94 + cairo_operator_t op; |
|
95 + const cairo_pattern_t *pattern; |
|
96 + cairo_antialias_t antialias; |
|
97 + |
|
98 + cairo_image_surface_t *mask; |
|
99 + cairo_win32_surface_t *dst; |
|
100 + |
|
101 + cairo_composite_rectangles_t composite_rectangles; |
|
102 +} cairo_win32_surface_span_renderer_t; |
|
103 + |
|
104 +static cairo_status_t |
|
105 +_cairo_win32_surface_span_renderer_render_row ( |
|
106 + void *abstract_renderer, |
|
107 + int y, |
|
108 + const cairo_half_open_span_t *spans, |
|
109 + unsigned num_spans) |
|
110 +{ |
|
111 + cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; |
|
112 + _cairo_image_surface_span_render_row (y, spans, num_spans, renderer->mask, &renderer->composite_rectangles); |
|
113 + return CAIRO_STATUS_SUCCESS; |
|
114 +} |
|
115 + |
|
116 +static void |
|
117 +_cairo_win32_surface_span_renderer_destroy (void *abstract_renderer) |
|
118 +{ |
|
119 + cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; |
|
120 + if (!renderer) return; |
|
121 + |
|
122 + if (renderer->mask != NULL) |
|
123 + cairo_surface_destroy (&renderer->mask->base); |
|
124 + |
|
125 + free (renderer); |
|
126 +} |
|
127 + |
|
128 +static cairo_status_t |
|
129 +_cairo_win32_surface_span_renderer_finish (void *abstract_renderer) |
|
130 +{ |
|
131 + cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; |
|
132 + cairo_status_t status = CAIRO_STATUS_SUCCESS; |
|
133 + |
|
134 + if (renderer->pattern == NULL || renderer->mask == NULL) |
|
135 + return CAIRO_STATUS_SUCCESS; |
|
136 + |
|
137 + status = cairo_surface_status (&renderer->mask->base); |
|
138 + if (status == CAIRO_STATUS_SUCCESS) { |
|
139 + cairo_composite_rectangles_t *rects = &renderer->composite_rectangles; |
|
140 + cairo_win32_surface_t *dst = renderer->dst; |
|
141 + cairo_pattern_t *mask_pattern = cairo_pattern_create_for_surface (&renderer->mask->base); |
|
142 + /* composite onto the image surface directly if we can */ |
|
143 + if (dst->image) { |
|
144 + GdiFlush(); |
|
145 + |
|
146 + status = dst->image->backend->composite (renderer->op, |
|
147 + renderer->pattern, mask_pattern, dst->image, |
|
148 + rects->src.x, |
|
149 + rects->src.y, |
|
150 + 0, 0, /* mask.x, mask.y */ |
|
151 + rects->dst.x, rects->dst.y, |
|
152 + rects->width, rects->height); |
|
153 + } else { |
|
154 + /* otherwise go through the fallback_composite path which |
|
155 + * will do the appropriate surface acquisition */ |
|
156 + status = _cairo_surface_fallback_composite ( |
|
157 + renderer->op, |
|
158 + renderer->pattern, mask_pattern, dst, |
|
159 + rects->src.x, |
|
160 + rects->src.y, |
|
161 + 0, 0, /* mask.x, mask.y */ |
|
162 + rects->dst.x, rects->dst.y, |
|
163 + rects->width, rects->height); |
|
164 + } |
|
165 + cairo_pattern_destroy (mask_pattern); |
|
166 + |
|
167 + } |
|
168 + if (status != CAIRO_STATUS_SUCCESS) |
|
169 + return _cairo_span_renderer_set_error (abstract_renderer, |
|
170 + status); |
|
171 + return CAIRO_STATUS_SUCCESS; |
|
172 +} |
|
173 + |
|
174 +static cairo_bool_t |
|
175 +_cairo_win32_surface_check_span_renderer (cairo_operator_t op, |
|
176 + const cairo_pattern_t *pattern, |
|
177 + void *abstract_dst, |
|
178 + cairo_antialias_t antialias, |
|
179 + const cairo_composite_rectangles_t *rects) |
|
180 +{ |
|
181 + (void) op; |
|
182 + (void) pattern; |
|
183 + (void) abstract_dst; |
|
184 + (void) antialias; |
|
185 + (void) rects; |
|
186 + return TRUE; |
|
187 +} |
|
188 + |
|
189 +static cairo_span_renderer_t * |
|
190 +_cairo_win32_surface_create_span_renderer (cairo_operator_t op, |
|
191 + const cairo_pattern_t *pattern, |
|
192 + void *abstract_dst, |
|
193 + cairo_antialias_t antialias, |
|
194 + const cairo_composite_rectangles_t *rects) |
|
195 +{ |
|
196 + cairo_win32_surface_t *dst = abstract_dst; |
|
197 + cairo_win32_surface_span_renderer_t *renderer |
|
198 + = calloc(1, sizeof(*renderer)); |
|
199 + cairo_status_t status; |
|
200 + int width = rects->width; |
|
201 + int height = rects->height; |
|
202 + |
|
203 + if (renderer == NULL) |
|
204 + return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); |
|
205 + |
|
206 + renderer->base.destroy = _cairo_win32_surface_span_renderer_destroy; |
|
207 + renderer->base.finish = _cairo_win32_surface_span_renderer_finish; |
|
208 + renderer->base.render_row = |
|
209 + _cairo_win32_surface_span_renderer_render_row; |
|
210 + renderer->op = op; |
|
211 + renderer->pattern = pattern; |
|
212 + renderer->antialias = antialias; |
|
213 + renderer->dst = dst; |
|
214 + |
|
215 + renderer->composite_rectangles = *rects; |
|
216 + |
|
217 + /* TODO: support rendering to A1 surfaces (or: go add span |
|
218 + * compositing to pixman.) */ |
|
219 + renderer->mask = (cairo_image_surface_t *) |
|
220 + cairo_image_surface_create (CAIRO_FORMAT_A8, |
|
221 + width, height); |
|
222 + |
|
223 + status = cairo_surface_status (&renderer->mask->base); |
|
224 + |
|
225 + if (status != CAIRO_STATUS_SUCCESS) { |
|
226 + _cairo_win32_surface_span_renderer_destroy (renderer); |
|
227 + return _cairo_span_renderer_create_in_error (status); |
|
228 + } |
|
229 + return &renderer->base; |
|
230 +} |
|
231 + |
|
232 + |
|
233 static const cairo_surface_backend_t cairo_win32_surface_backend = { |
|
234 CAIRO_SURFACE_TYPE_WIN32, |
|
235 _cairo_win32_surface_create_similar, |
|
236 @@ -2060,8 +2202,8 @@ static const cairo_surface_backend_t cai |
|
237 _cairo_win32_surface_composite, |
|
238 _cairo_win32_surface_fill_rectangles, |
|
239 NULL, /* composite_trapezoids */ |
|
240 - NULL, /* create_span_renderer */ |
|
241 - NULL, /* check_span_renderer */ |
|
242 + _cairo_win32_surface_create_span_renderer, |
|
243 + _cairo_win32_surface_check_span_renderer, |
|
244 NULL, /* copy_page */ |
|
245 NULL, /* show_page */ |
|
246 _cairo_win32_surface_set_clip_region, |
|
247 diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h |
|
248 --- a/gfx/cairo/cairo/src/cairoint.h |
|
249 +++ b/gfx/cairo/cairo/src/cairoint.h |
|
250 @@ -2193,6 +2193,12 @@ _cairo_image_surface_set_clip_region (vo |
|
251 cairo_private cairo_image_surface_t * |
|
252 _cairo_image_surface_coerce (cairo_image_surface_t *surface, |
|
253 cairo_format_t format); |
|
254 +cairo_private void |
|
255 +_cairo_image_surface_span_render_row (int y, |
|
256 + const cairo_half_open_span_t *spans, |
|
257 + unsigned num_spans, |
|
258 + cairo_image_surface_t *mask, |
|
259 + const cairo_composite_rectangles_t *rects); |
|
260 |
|
261 cairo_private cairo_image_transparency_t |
|
262 _cairo_image_analyze_transparency (cairo_image_surface_t *image); |