gfx/cairo/tee-surfaces-pointwise.patch

changeset 0
6474c204b198
     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 + }

mercurial