cairo_status_t _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper, cairo_operator_t op, const cairo_pattern_t *source, const cairo_clip_t *clip) { cairo_status_t status; cairo_clip_t *dev_clip; cairo_pattern_union_t source_copy; if (unlikely (wrapper->target->status)) return wrapper->target->status; dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); if (_cairo_clip_is_all_clipped (dev_clip)) return (cairo_status_t)CAIRO_INT_STATUS_NOTHING_TO_DO; if (wrapper->needs_transform) { cairo_matrix_t m; _cairo_surface_wrapper_get_transform (wrapper, &m); status = cairo_matrix_invert (&m); assert (status == CAIRO_STATUS_SUCCESS); _copy_transformed_pattern (&source_copy.base, source, &m); source = &source_copy.base; } status = _cairo_surface_paint (wrapper->target, op, source, dev_clip); _cairo_clip_destroy (dev_clip); return status; }
cairo_status_t _cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper, cairo_operator_t op, const cairo_pattern_t *source, const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, const cairo_clip_t *clip) { cairo_status_t status; cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path; cairo_pattern_union_t source_copy; cairo_clip_t *dev_clip; if (unlikely (wrapper->target->status)) return wrapper->target->status; dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); if (_cairo_clip_is_all_clipped (dev_clip)) return CAIRO_INT_STATUS_NOTHING_TO_DO; if (wrapper->needs_transform) { cairo_matrix_t m; _cairo_surface_wrapper_get_transform (wrapper, &m); status = _cairo_path_fixed_init_copy (&path_copy, dev_path); if (unlikely (status)) goto FINISH; _cairo_path_fixed_transform (&path_copy, &m); dev_path = &path_copy; status = cairo_matrix_invert (&m); assert (status == CAIRO_STATUS_SUCCESS); _copy_transformed_pattern (&source_copy.base, source, &m); source = &source_copy.base; } status = _cairo_surface_fill (wrapper->target, op, source, dev_path, fill_rule, tolerance, antialias, dev_clip); FINISH: if (dev_path != path) _cairo_path_fixed_fini (dev_path); _cairo_clip_destroy (dev_clip); return status; }
cairo_status_t _cairo_surface_wrapper_tag (cairo_surface_wrapper_t *wrapper, cairo_bool_t begin, const char *tag_name, const char *attributes, const cairo_pattern_t *source, const cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, const cairo_clip_t *clip) { cairo_status_t status; cairo_clip_t *dev_clip; cairo_matrix_t dev_ctm = *ctm; cairo_matrix_t dev_ctm_inverse = *ctm_inverse; cairo_pattern_union_t source_copy; if (unlikely (wrapper->target->status)) return wrapper->target->status; dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); if (wrapper->needs_transform) { cairo_matrix_t m; _cairo_surface_wrapper_get_transform (wrapper, &m); cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m); status = cairo_matrix_invert (&m); assert (status == CAIRO_STATUS_SUCCESS); cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse); _copy_transformed_pattern (&source_copy.base, source, &m); source = &source_copy.base; } status = _cairo_surface_tag (wrapper->target, begin, tag_name, attributes, source, stroke_style, &dev_ctm, &dev_ctm_inverse, dev_clip); _cairo_clip_destroy (dev_clip); return status; }
cairo_status_t _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper, cairo_operator_t op, const cairo_pattern_t *source, const char *utf8, int utf8_len, const cairo_glyph_t *glyphs, int num_glyphs, const cairo_text_cluster_t *clusters, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, const cairo_clip_t *clip) { cairo_status_t status; cairo_clip_t *dev_clip; cairo_glyph_t stack_glyphs [CAIRO_STACK_ARRAY_LENGTH(cairo_glyph_t)]; cairo_glyph_t *dev_glyphs = stack_glyphs; cairo_scaled_font_t *dev_scaled_font = scaled_font; cairo_pattern_union_t source_copy; cairo_font_options_t options; if (unlikely (wrapper->target->status)) return wrapper->target->status; dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); if (_cairo_clip_is_all_clipped (dev_clip)) return CAIRO_INT_STATUS_NOTHING_TO_DO; cairo_surface_get_font_options (wrapper->target, &options); cairo_font_options_merge (&options, &scaled_font->options); if (wrapper->needs_transform) { cairo_matrix_t m; int i; _cairo_surface_wrapper_get_transform (wrapper, &m); if (! _cairo_matrix_is_translation (&wrapper->transform)) { cairo_matrix_t ctm; /* XXX No device-transform? A bug in the tangle of layers? */ _cairo_matrix_multiply (&ctm, &wrapper->transform, &scaled_font->ctm); dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face, &scaled_font->font_matrix, &ctm, &options); } if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) { dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); if (unlikely (dev_glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto FINISH; } } for (i = 0; i < num_glyphs; i++) { dev_glyphs[i] = glyphs[i]; cairo_matrix_transform_point (&m, &dev_glyphs[i].x, &dev_glyphs[i].y); } status = cairo_matrix_invert (&m); assert (status == CAIRO_STATUS_SUCCESS); _copy_transformed_pattern (&source_copy.base, source, &m); source = &source_copy.base; } else { if (! cairo_font_options_equal (&options, &scaled_font->options)) { dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face, &scaled_font->font_matrix, &scaled_font->ctm, &options); } /* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed * to modify the glyph array that's passed in. We must always * copy the array before handing it to the backend. */ if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) { dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); if (unlikely (dev_glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto FINISH; } } memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); } status = _cairo_surface_show_text_glyphs (wrapper->target, op, source, utf8, utf8_len, dev_glyphs, num_glyphs, clusters, num_clusters, cluster_flags, dev_scaled_font, dev_clip); FINISH: _cairo_clip_destroy (dev_clip); if (dev_glyphs != stack_glyphs) free (dev_glyphs); if (dev_scaled_font != scaled_font) cairo_scaled_font_destroy (dev_scaled_font); return status; }