diff options
Diffstat (limited to 'gfx/cairo/tee-surfaces-pointwise.patch')
-rw-r--r-- | gfx/cairo/tee-surfaces-pointwise.patch | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/gfx/cairo/tee-surfaces-pointwise.patch b/gfx/cairo/tee-surfaces-pointwise.patch new file mode 100644 index 0000000000..180005fa62 --- /dev/null +++ b/gfx/cairo/tee-surfaces-pointwise.patch @@ -0,0 +1,278 @@ +# HG changeset patch +# User Robert O'Callahan <robert@ocallahan.org> +# Date 1294019288 -46800 +# Node ID bacc54d452a9fddb5a0d6a1442ec7be4de81ffa7 +# Parent ccba8826be1451d0e61d0df38363dadffb20ba48 +Bug 593604. Part 2: When compositing a tee surface into another tee surface, try to compose the subsurfaces pointwise. r=jrmuizel,a=blocking + +diff --git a/gfx/cairo/cairo/src/cairo-tee-surface.c b/gfx/cairo/cairo/src/cairo-tee-surface.c +--- a/gfx/cairo/cairo/src/cairo-tee-surface.c ++++ b/gfx/cairo/cairo/src/cairo-tee-surface.c +@@ -186,35 +186,72 @@ static void + _cairo_tee_surface_get_font_options (void *abstract_surface, + cairo_font_options_t *options) + { + cairo_tee_surface_t *surface = abstract_surface; + + _cairo_surface_wrapper_get_font_options (&surface->master, options); + } + ++static const cairo_pattern_t * ++_cairo_tee_surface_match_source (cairo_tee_surface_t *surface, ++ const cairo_pattern_t *source, ++ int index, ++ cairo_surface_wrapper_t *dest, ++ cairo_surface_pattern_t *temp) ++{ ++ cairo_surface_t *s; ++ cairo_status_t status = cairo_pattern_get_surface ((cairo_pattern_t *)source, &s); ++ if (status == CAIRO_STATUS_SUCCESS && ++ cairo_surface_get_type (s) == CAIRO_SURFACE_TYPE_TEE) { ++ cairo_surface_t *tee_surf = cairo_tee_surface_index (s, index); ++ if (tee_surf->status == CAIRO_STATUS_SUCCESS && ++ tee_surf->backend == dest->target->backend) { ++ status = _cairo_pattern_init_copy (&temp->base, source); ++ if (status == CAIRO_STATUS_SUCCESS) { ++ cairo_surface_destroy (temp->surface); ++ temp->surface = tee_surf; ++ cairo_surface_reference (temp->surface); ++ return &temp->base; ++ } ++ } ++ } ++ ++ return source; ++} ++ + static cairo_int_status_t + _cairo_tee_surface_paint (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_clip_t *clip) + { + cairo_tee_surface_t *surface = abstract_surface; + cairo_surface_wrapper_t *slaves; + int n, num_slaves; + cairo_status_t status; ++ const cairo_pattern_t *matched_source; ++ cairo_surface_pattern_t temp; + +- status = _cairo_surface_wrapper_paint (&surface->master, op, source, clip); ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); ++ status = _cairo_surface_wrapper_paint (&surface->master, op, matched_source, clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + + num_slaves = _cairo_array_num_elements (&surface->slaves); + slaves = _cairo_array_index (&surface->slaves, 0); + for (n = 0; n < num_slaves; n++) { +- status = _cairo_surface_wrapper_paint (&slaves[n], op, source, clip); ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); ++ status = _cairo_surface_wrapper_paint (&slaves[n], op, matched_source, clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + } + + return CAIRO_STATUS_SUCCESS; + } + + static cairo_int_status_t +@@ -223,27 +260,37 @@ _cairo_tee_surface_mask (void *abstrac + const cairo_pattern_t *source, + const cairo_pattern_t *mask, + cairo_clip_t *clip) + { + cairo_tee_surface_t *surface = abstract_surface; + cairo_surface_wrapper_t *slaves; + int n, num_slaves; + cairo_status_t status; ++ const cairo_pattern_t *matched_source; ++ cairo_surface_pattern_t temp; + ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); + status = _cairo_surface_wrapper_mask (&surface->master, +- op, source, mask, clip); ++ op, matched_source, mask, clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + + num_slaves = _cairo_array_num_elements (&surface->slaves); + slaves = _cairo_array_index (&surface->slaves, 0); + for (n = 0; n < num_slaves; n++) { ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); + status = _cairo_surface_wrapper_mask (&slaves[n], +- op, source, mask, clip); ++ op, matched_source, mask, clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + } + + return CAIRO_STATUS_SUCCESS; + } + + static cairo_int_status_t +@@ -257,35 +304,45 @@ _cairo_tee_surface_stroke (void *abst + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip) + { + cairo_tee_surface_t *surface = abstract_surface; + cairo_surface_wrapper_t *slaves; + int n, num_slaves; + cairo_status_t status; ++ const cairo_pattern_t *matched_source; ++ cairo_surface_pattern_t temp; + ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); + status = _cairo_surface_wrapper_stroke (&surface->master, +- op, source, ++ op, matched_source, + path, style, + ctm, ctm_inverse, + tolerance, antialias, + clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + + num_slaves = _cairo_array_num_elements (&surface->slaves); + slaves = _cairo_array_index (&surface->slaves, 0); + for (n = 0; n < num_slaves; n++) { ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); + status = _cairo_surface_wrapper_stroke (&slaves[n], +- op, source, ++ op, matched_source, + path, style, + ctm, ctm_inverse, + tolerance, antialias, + clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + } + + return CAIRO_STATUS_SUCCESS; + } + + static cairo_int_status_t +@@ -297,33 +354,43 @@ _cairo_tee_surface_fill (void *abstra + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip) + { + cairo_tee_surface_t *surface = abstract_surface; + cairo_surface_wrapper_t *slaves; + int n, num_slaves; + cairo_status_t status; ++ const cairo_pattern_t *matched_source; ++ cairo_surface_pattern_t temp; + ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); + status = _cairo_surface_wrapper_fill (&surface->master, +- op, source, ++ op, matched_source, + path, fill_rule, + tolerance, antialias, + clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + + num_slaves = _cairo_array_num_elements (&surface->slaves); + slaves = _cairo_array_index (&surface->slaves, 0); + for (n = 0; n < num_slaves; n++) { ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); + status = _cairo_surface_wrapper_fill (&slaves[n], +- op, source, ++ op, matched_source, + path, fill_rule, + tolerance, antialias, + clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + return status; + } + + return CAIRO_STATUS_SUCCESS; + } + + static cairo_bool_t +@@ -346,46 +413,56 @@ _cairo_tee_surface_show_text_glyphs (voi + cairo_scaled_font_t *scaled_font, + cairo_clip_t *clip) + { + cairo_tee_surface_t *surface = abstract_surface; + cairo_surface_wrapper_t *slaves; + int n, num_slaves; + cairo_status_t status; + cairo_glyph_t *glyphs_copy; ++ const cairo_pattern_t *matched_source; ++ cairo_surface_pattern_t temp; + + /* XXX: This copying is ugly. */ + glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); + if (unlikely (glyphs_copy == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); ++ matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); + status = _cairo_surface_wrapper_show_text_glyphs (&surface->master, op, +- source, ++ matched_source, + utf8, utf8_len, + glyphs_copy, num_glyphs, + clusters, num_clusters, + cluster_flags, + scaled_font, + clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + goto CLEANUP; + + num_slaves = _cairo_array_num_elements (&surface->slaves); + slaves = _cairo_array_index (&surface->slaves, 0); + for (n = 0; n < num_slaves; n++) { + memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); ++ matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); + status = _cairo_surface_wrapper_show_text_glyphs (&slaves[n], op, +- source, ++ matched_source, + utf8, utf8_len, + glyphs_copy, num_glyphs, + clusters, num_clusters, + cluster_flags, + scaled_font, + clip); ++ if (matched_source == &temp.base) { ++ _cairo_pattern_fini (&temp.base); ++ } + if (unlikely (status)) + goto CLEANUP; + } + + CLEANUP: + free (glyphs_copy); + return status; + } |