1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/tee-surfaces-pointwise.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,278 @@ 1.4 +# HG changeset patch 1.5 +# User Robert O'Callahan <robert@ocallahan.org> 1.6 +# Date 1294019288 -46800 1.7 +# Node ID bacc54d452a9fddb5a0d6a1442ec7be4de81ffa7 1.8 +# Parent ccba8826be1451d0e61d0df38363dadffb20ba48 1.9 +Bug 593604. Part 2: When compositing a tee surface into another tee surface, try to compose the subsurfaces pointwise. r=jrmuizel,a=blocking 1.10 + 1.11 +diff --git a/gfx/cairo/cairo/src/cairo-tee-surface.c b/gfx/cairo/cairo/src/cairo-tee-surface.c 1.12 +--- a/gfx/cairo/cairo/src/cairo-tee-surface.c 1.13 ++++ b/gfx/cairo/cairo/src/cairo-tee-surface.c 1.14 +@@ -186,35 +186,72 @@ static void 1.15 + _cairo_tee_surface_get_font_options (void *abstract_surface, 1.16 + cairo_font_options_t *options) 1.17 + { 1.18 + cairo_tee_surface_t *surface = abstract_surface; 1.19 + 1.20 + _cairo_surface_wrapper_get_font_options (&surface->master, options); 1.21 + } 1.22 + 1.23 ++static const cairo_pattern_t * 1.24 ++_cairo_tee_surface_match_source (cairo_tee_surface_t *surface, 1.25 ++ const cairo_pattern_t *source, 1.26 ++ int index, 1.27 ++ cairo_surface_wrapper_t *dest, 1.28 ++ cairo_surface_pattern_t *temp) 1.29 ++{ 1.30 ++ cairo_surface_t *s; 1.31 ++ cairo_status_t status = cairo_pattern_get_surface ((cairo_pattern_t *)source, &s); 1.32 ++ if (status == CAIRO_STATUS_SUCCESS && 1.33 ++ cairo_surface_get_type (s) == CAIRO_SURFACE_TYPE_TEE) { 1.34 ++ cairo_surface_t *tee_surf = cairo_tee_surface_index (s, index); 1.35 ++ if (tee_surf->status == CAIRO_STATUS_SUCCESS && 1.36 ++ tee_surf->backend == dest->target->backend) { 1.37 ++ status = _cairo_pattern_init_copy (&temp->base, source); 1.38 ++ if (status == CAIRO_STATUS_SUCCESS) { 1.39 ++ cairo_surface_destroy (temp->surface); 1.40 ++ temp->surface = tee_surf; 1.41 ++ cairo_surface_reference (temp->surface); 1.42 ++ return &temp->base; 1.43 ++ } 1.44 ++ } 1.45 ++ } 1.46 ++ 1.47 ++ return source; 1.48 ++} 1.49 ++ 1.50 + static cairo_int_status_t 1.51 + _cairo_tee_surface_paint (void *abstract_surface, 1.52 + cairo_operator_t op, 1.53 + const cairo_pattern_t *source, 1.54 + cairo_clip_t *clip) 1.55 + { 1.56 + cairo_tee_surface_t *surface = abstract_surface; 1.57 + cairo_surface_wrapper_t *slaves; 1.58 + int n, num_slaves; 1.59 + cairo_status_t status; 1.60 ++ const cairo_pattern_t *matched_source; 1.61 ++ cairo_surface_pattern_t temp; 1.62 + 1.63 +- status = _cairo_surface_wrapper_paint (&surface->master, op, source, clip); 1.64 ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); 1.65 ++ status = _cairo_surface_wrapper_paint (&surface->master, op, matched_source, clip); 1.66 ++ if (matched_source == &temp.base) { 1.67 ++ _cairo_pattern_fini (&temp.base); 1.68 ++ } 1.69 + if (unlikely (status)) 1.70 + return status; 1.71 + 1.72 + num_slaves = _cairo_array_num_elements (&surface->slaves); 1.73 + slaves = _cairo_array_index (&surface->slaves, 0); 1.74 + for (n = 0; n < num_slaves; n++) { 1.75 +- status = _cairo_surface_wrapper_paint (&slaves[n], op, source, clip); 1.76 ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); 1.77 ++ status = _cairo_surface_wrapper_paint (&slaves[n], op, matched_source, clip); 1.78 ++ if (matched_source == &temp.base) { 1.79 ++ _cairo_pattern_fini (&temp.base); 1.80 ++ } 1.81 + if (unlikely (status)) 1.82 + return status; 1.83 + } 1.84 + 1.85 + return CAIRO_STATUS_SUCCESS; 1.86 + } 1.87 + 1.88 + static cairo_int_status_t 1.89 +@@ -223,27 +260,37 @@ _cairo_tee_surface_mask (void *abstrac 1.90 + const cairo_pattern_t *source, 1.91 + const cairo_pattern_t *mask, 1.92 + cairo_clip_t *clip) 1.93 + { 1.94 + cairo_tee_surface_t *surface = abstract_surface; 1.95 + cairo_surface_wrapper_t *slaves; 1.96 + int n, num_slaves; 1.97 + cairo_status_t status; 1.98 ++ const cairo_pattern_t *matched_source; 1.99 ++ cairo_surface_pattern_t temp; 1.100 + 1.101 ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); 1.102 + status = _cairo_surface_wrapper_mask (&surface->master, 1.103 +- op, source, mask, clip); 1.104 ++ op, matched_source, mask, clip); 1.105 ++ if (matched_source == &temp.base) { 1.106 ++ _cairo_pattern_fini (&temp.base); 1.107 ++ } 1.108 + if (unlikely (status)) 1.109 + return status; 1.110 + 1.111 + num_slaves = _cairo_array_num_elements (&surface->slaves); 1.112 + slaves = _cairo_array_index (&surface->slaves, 0); 1.113 + for (n = 0; n < num_slaves; n++) { 1.114 ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); 1.115 + status = _cairo_surface_wrapper_mask (&slaves[n], 1.116 +- op, source, mask, clip); 1.117 ++ op, matched_source, mask, clip); 1.118 ++ if (matched_source == &temp.base) { 1.119 ++ _cairo_pattern_fini (&temp.base); 1.120 ++ } 1.121 + if (unlikely (status)) 1.122 + return status; 1.123 + } 1.124 + 1.125 + return CAIRO_STATUS_SUCCESS; 1.126 + } 1.127 + 1.128 + static cairo_int_status_t 1.129 +@@ -257,35 +304,45 @@ _cairo_tee_surface_stroke (void *abst 1.130 + double tolerance, 1.131 + cairo_antialias_t antialias, 1.132 + cairo_clip_t *clip) 1.133 + { 1.134 + cairo_tee_surface_t *surface = abstract_surface; 1.135 + cairo_surface_wrapper_t *slaves; 1.136 + int n, num_slaves; 1.137 + cairo_status_t status; 1.138 ++ const cairo_pattern_t *matched_source; 1.139 ++ cairo_surface_pattern_t temp; 1.140 + 1.141 ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); 1.142 + status = _cairo_surface_wrapper_stroke (&surface->master, 1.143 +- op, source, 1.144 ++ op, matched_source, 1.145 + path, style, 1.146 + ctm, ctm_inverse, 1.147 + tolerance, antialias, 1.148 + clip); 1.149 ++ if (matched_source == &temp.base) { 1.150 ++ _cairo_pattern_fini (&temp.base); 1.151 ++ } 1.152 + if (unlikely (status)) 1.153 + return status; 1.154 + 1.155 + num_slaves = _cairo_array_num_elements (&surface->slaves); 1.156 + slaves = _cairo_array_index (&surface->slaves, 0); 1.157 + for (n = 0; n < num_slaves; n++) { 1.158 ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); 1.159 + status = _cairo_surface_wrapper_stroke (&slaves[n], 1.160 +- op, source, 1.161 ++ op, matched_source, 1.162 + path, style, 1.163 + ctm, ctm_inverse, 1.164 + tolerance, antialias, 1.165 + clip); 1.166 ++ if (matched_source == &temp.base) { 1.167 ++ _cairo_pattern_fini (&temp.base); 1.168 ++ } 1.169 + if (unlikely (status)) 1.170 + return status; 1.171 + } 1.172 + 1.173 + return CAIRO_STATUS_SUCCESS; 1.174 + } 1.175 + 1.176 + static cairo_int_status_t 1.177 +@@ -297,33 +354,43 @@ _cairo_tee_surface_fill (void *abstra 1.178 + double tolerance, 1.179 + cairo_antialias_t antialias, 1.180 + cairo_clip_t *clip) 1.181 + { 1.182 + cairo_tee_surface_t *surface = abstract_surface; 1.183 + cairo_surface_wrapper_t *slaves; 1.184 + int n, num_slaves; 1.185 + cairo_status_t status; 1.186 ++ const cairo_pattern_t *matched_source; 1.187 ++ cairo_surface_pattern_t temp; 1.188 + 1.189 ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); 1.190 + status = _cairo_surface_wrapper_fill (&surface->master, 1.191 +- op, source, 1.192 ++ op, matched_source, 1.193 + path, fill_rule, 1.194 + tolerance, antialias, 1.195 + clip); 1.196 ++ if (matched_source == &temp.base) { 1.197 ++ _cairo_pattern_fini (&temp.base); 1.198 ++ } 1.199 + if (unlikely (status)) 1.200 + return status; 1.201 + 1.202 + num_slaves = _cairo_array_num_elements (&surface->slaves); 1.203 + slaves = _cairo_array_index (&surface->slaves, 0); 1.204 + for (n = 0; n < num_slaves; n++) { 1.205 ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); 1.206 + status = _cairo_surface_wrapper_fill (&slaves[n], 1.207 +- op, source, 1.208 ++ op, matched_source, 1.209 + path, fill_rule, 1.210 + tolerance, antialias, 1.211 + clip); 1.212 ++ if (matched_source == &temp.base) { 1.213 ++ _cairo_pattern_fini (&temp.base); 1.214 ++ } 1.215 + if (unlikely (status)) 1.216 + return status; 1.217 + } 1.218 + 1.219 + return CAIRO_STATUS_SUCCESS; 1.220 + } 1.221 + 1.222 + static cairo_bool_t 1.223 +@@ -346,46 +413,56 @@ _cairo_tee_surface_show_text_glyphs (voi 1.224 + cairo_scaled_font_t *scaled_font, 1.225 + cairo_clip_t *clip) 1.226 + { 1.227 + cairo_tee_surface_t *surface = abstract_surface; 1.228 + cairo_surface_wrapper_t *slaves; 1.229 + int n, num_slaves; 1.230 + cairo_status_t status; 1.231 + cairo_glyph_t *glyphs_copy; 1.232 ++ const cairo_pattern_t *matched_source; 1.233 ++ cairo_surface_pattern_t temp; 1.234 + 1.235 + /* XXX: This copying is ugly. */ 1.236 + glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); 1.237 + if (unlikely (glyphs_copy == NULL)) 1.238 + return _cairo_error (CAIRO_STATUS_NO_MEMORY); 1.239 + 1.240 + memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); 1.241 ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); 1.242 + status = _cairo_surface_wrapper_show_text_glyphs (&surface->master, op, 1.243 +- source, 1.244 ++ matched_source, 1.245 + utf8, utf8_len, 1.246 + glyphs_copy, num_glyphs, 1.247 + clusters, num_clusters, 1.248 + cluster_flags, 1.249 + scaled_font, 1.250 + clip); 1.251 ++ if (matched_source == &temp.base) { 1.252 ++ _cairo_pattern_fini (&temp.base); 1.253 ++ } 1.254 + if (unlikely (status)) 1.255 + goto CLEANUP; 1.256 + 1.257 + num_slaves = _cairo_array_num_elements (&surface->slaves); 1.258 + slaves = _cairo_array_index (&surface->slaves, 0); 1.259 + for (n = 0; n < num_slaves; n++) { 1.260 + memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); 1.261 ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); 1.262 + status = _cairo_surface_wrapper_show_text_glyphs (&slaves[n], op, 1.263 +- source, 1.264 ++ matched_source, 1.265 + utf8, utf8_len, 1.266 + glyphs_copy, num_glyphs, 1.267 + clusters, num_clusters, 1.268 + cluster_flags, 1.269 + scaled_font, 1.270 + clip); 1.271 ++ if (matched_source == &temp.base) { 1.272 ++ _cairo_pattern_fini (&temp.base); 1.273 ++ } 1.274 + if (unlikely (status)) 1.275 + goto CLEANUP; 1.276 + } 1.277 + 1.278 + CLEANUP: 1.279 + free (glyphs_copy); 1.280 + return status; 1.281 + }