cairo_status_t
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
			      cairo_operator_t	 op,
			      const cairo_pattern_t *source,
			      cairo_clip_t	    *clip)
{
    cairo_status_t status;
    cairo_matrix_t device_transform;
    cairo_clip_t clip_copy, *dev_clip = clip;

    if (unlikely (wrapper->target->status))
	return wrapper->target->status;

    if (clip && clip->all_clipped)
	return CAIRO_STATUS_SUCCESS;

    if (clip != NULL) {
	if (_cairo_surface_wrapper_needs_device_transform (wrapper,
							   &device_transform))
	{
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
							&device_transform);
	    if (unlikely (status))
		goto FINISH;

	} else {
	    _cairo_clip_init_copy (&clip_copy, clip);
	}

	dev_clip = &clip_copy;
    }

    status = _cairo_surface_paint (wrapper->target, op, source, dev_clip);

  FINISH:
    if (dev_clip != clip)
	_cairo_clip_reset (dev_clip);
    return status;
}
cairo_status_t
_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
				    cairo_operator_t	     fill_op,
				    const cairo_pattern_t   *fill_source,
				    cairo_fill_rule_t	     fill_rule,
				    double		     fill_tolerance,
				    cairo_antialias_t	     fill_antialias,
				    cairo_path_fixed_t	    *path,
				    cairo_operator_t	     stroke_op,
				    const cairo_pattern_t   *stroke_source,
				    cairo_stroke_style_t    *stroke_style,
				    cairo_matrix_t	    *stroke_ctm,
				    cairo_matrix_t	    *stroke_ctm_inverse,
				    double		     stroke_tolerance,
				    cairo_antialias_t	     stroke_antialias,
				    cairo_clip_t	    *clip)
{
    cairo_status_t status;
    cairo_matrix_t device_transform;
    cairo_path_fixed_t path_copy, *dev_path = path;
    cairo_clip_t clip_copy, *dev_clip = clip;
    cairo_matrix_t dev_ctm = *stroke_ctm;
    cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;

    if (unlikely (wrapper->target->status))
	return wrapper->target->status;

    if (clip && clip->all_clipped)
	return CAIRO_STATUS_SUCCESS;

    if (_cairo_surface_wrapper_needs_device_transform (wrapper,
						       &device_transform))
    {
	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
	if (unlikely (status))
	    goto FINISH;

	_cairo_path_fixed_transform (&path_copy, &device_transform);
	dev_path = &path_copy;

	if (clip != NULL) {
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
							&device_transform);
	    if (unlikely (status))
		goto FINISH;

	    dev_clip = &clip_copy;
	}

	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &device_transform);
	status = cairo_matrix_invert (&device_transform);
	assert (status == CAIRO_STATUS_SUCCESS);
	cairo_matrix_multiply (&dev_ctm_inverse,
			       &device_transform,
			       &dev_ctm_inverse);
    } else {
	if (clip != NULL) {
	    dev_clip = &clip_copy;
	    _cairo_clip_init_copy (&clip_copy, clip);
	}
    }

    status = _cairo_surface_fill_stroke (wrapper->target,
					 fill_op, fill_source, fill_rule,
					 fill_tolerance, fill_antialias,
					 dev_path,
					 stroke_op, stroke_source,
					 stroke_style,
					 &dev_ctm, &dev_ctm_inverse,
					 stroke_tolerance, stroke_antialias,
					 dev_clip);

  FINISH:
    if (dev_path != path)
	_cairo_path_fixed_fini (dev_path);
    if (dev_clip != clip)
	_cairo_clip_reset (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,
					 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,
					 cairo_clip_t		    *clip)
{
    cairo_status_t status;
    cairo_matrix_t device_transform;
    cairo_clip_t clip_copy, *dev_clip = clip;
    cairo_glyph_t *dev_glyphs = glyphs;

    if (unlikely (wrapper->target->status))
	return wrapper->target->status;

    if (glyphs == NULL || num_glyphs == 0)
	return CAIRO_STATUS_SUCCESS;

    if (clip && clip->all_clipped)
	return CAIRO_STATUS_SUCCESS;

    if (_cairo_surface_wrapper_needs_device_transform (wrapper,
						       &device_transform))
    {
	int i;

	if (clip != NULL) {
	    dev_clip = &clip_copy;
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
							&device_transform);
	    if (unlikely (status))
		goto FINISH;
	}

	dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
	if (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 (&device_transform,
					  &dev_glyphs[i].x,
					  &dev_glyphs[i].y);
	}
    } else {
	if (clip != NULL) {
	    dev_clip = &clip_copy;
	    _cairo_clip_init_copy (&clip_copy, clip);
	}
    }

    status = _cairo_surface_show_text_glyphs (wrapper->target, op, source,
					      utf8, utf8_len,
					      dev_glyphs, num_glyphs,
					      clusters, num_clusters,
					      cluster_flags,
					      scaled_font,
					      dev_clip);
 FINISH:
    if (dev_clip != clip)
	_cairo_clip_reset (dev_clip);
    if (dev_glyphs != glyphs)
	free (dev_glyphs);
    return status;
}
Exemple #4
0
cairo_status_t
_cairo_surface_offset_glyphs (cairo_surface_t		*surface,
			      int x, int y,
			      cairo_operator_t		 op,
			      const cairo_pattern_t	*source,
			      cairo_scaled_font_t	*scaled_font,
			      cairo_glyph_t		*glyphs,
			      int			 num_glyphs,
			      cairo_clip_t		*clip)
{
    cairo_status_t status;
    cairo_clip_t clip_copy, *dev_clip = clip;
    cairo_pattern_union_t source_copy;
    cairo_glyph_t *dev_glyphs;
    int i;

    if (unlikely (surface->status))
	return surface->status;

    if (clip && clip->all_clipped)
	return CAIRO_STATUS_SUCCESS;

    dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
    if (dev_glyphs == NULL)
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);

    if (x | y) {
	cairo_matrix_t m;

	if (clip != NULL) {
	    cairo_matrix_init_translate (&m, -x, -y);
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
	    if (unlikely (status))
		goto FINISH;

	    dev_clip = &clip_copy;
	}

	cairo_matrix_init_translate (&m, x, y);
	_copy_transformed_pattern (&source_copy.base, source, &m);
	source = &source_copy.base;

	for (i = 0; i < num_glyphs; i++) {
	    dev_glyphs[i].x -= x;
	    dev_glyphs[i].y -= y;
	}
    }

    status = _cairo_surface_show_text_glyphs (surface, op, source,
					      NULL, 0,
					      dev_glyphs, num_glyphs,
					      NULL, 0, 0,
					      scaled_font,
					      dev_clip);

 FINISH:
    if (dev_clip != clip)
	_cairo_clip_reset (dev_clip);
    free (dev_glyphs);

    return status;
}
Exemple #5
0
cairo_status_t
_cairo_surface_offset_fill (cairo_surface_t	*surface,
			    int x, int y,
			    cairo_operator_t	 op,
			    const cairo_pattern_t*source,
			    cairo_path_fixed_t	*path,
			    cairo_fill_rule_t	 fill_rule,
			    double		 tolerance,
			    cairo_antialias_t	 antialias,
			    cairo_clip_t	*clip)
{
    cairo_status_t status;
    cairo_path_fixed_t path_copy, *dev_path = path;
    cairo_clip_t clip_copy, *dev_clip = clip;
    cairo_pattern_union_t source_copy;

    if (unlikely (surface->status))
	return surface->status;

    if (clip && clip->all_clipped)
	return CAIRO_STATUS_SUCCESS;

    if (x | y) {
	cairo_matrix_t m;

	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
	if (unlikely (status))
	    goto FINISH;

	_cairo_path_fixed_translate (&path_copy,
				     _cairo_fixed_from_int (-x),
				     _cairo_fixed_from_int (-y));
	dev_path = &path_copy;

	if (clip != NULL) {
	    cairo_matrix_init_translate (&m, -x, -y);
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
	    if (unlikely (status))
		goto FINISH;

	    dev_clip = &clip_copy;
	}

	cairo_matrix_init_translate (&m, x, y);
	_copy_transformed_pattern (&source_copy.base, source, &m);
	source = &source_copy.base;
    }

    status = _cairo_surface_fill (surface, op, source,
				  dev_path, fill_rule,
				  tolerance, antialias,
				  dev_clip);

 FINISH:
    if (dev_path != path)
	_cairo_path_fixed_fini (dev_path);
    if (dev_clip != clip)
	_cairo_clip_reset (dev_clip);

    return status;
}
cairo_status_t
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
                              cairo_operator_t	 op,
                              const cairo_pattern_t *source,
                              cairo_clip_t	    *clip)
{
    cairo_status_t status;
    cairo_clip_t clip_copy, *dev_clip = clip;
    cairo_pattern_union_t source_copy;
    cairo_clip_t target_clip;

    if (unlikely (wrapper->target->status))
        return wrapper->target->status;

    if (wrapper->has_extents) {
        _cairo_clip_init_copy (&target_clip, clip);
        status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
        if (unlikely (status))
            goto FINISH;

        dev_clip = clip = &target_clip;
    }

    if (clip && clip->all_clipped) {
        status = CAIRO_STATUS_SUCCESS;
        goto FINISH;
    }

    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
            _cairo_surface_wrapper_needs_extents_transform (wrapper))
    {
        cairo_matrix_t m;

        cairo_matrix_init_identity (&m);

        if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
            cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);

        if (_cairo_surface_wrapper_needs_device_transform (wrapper))
            cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);

        if (clip != NULL) {
            status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
            if (unlikely (status))
                goto FINISH;

            dev_clip = &clip_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_paint (wrapper->target, op, source, dev_clip);

FINISH:
    if (wrapper->has_extents)
        _cairo_clip_reset (&target_clip);
    if (dev_clip != clip)
        _cairo_clip_reset (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,
        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,
        cairo_clip_t		    *clip)
{
    cairo_status_t status;
    cairo_clip_t clip_copy, *dev_clip = clip;
    cairo_glyph_t *dev_glyphs = glyphs;
    cairo_pattern_union_t source_copy;
    cairo_clip_t target_clip;

    if (unlikely (wrapper->target->status))
        return wrapper->target->status;

    if (glyphs == NULL || num_glyphs == 0)
        return CAIRO_STATUS_SUCCESS;

    if (wrapper->has_extents) {
        _cairo_clip_init_copy (&target_clip, clip);
        status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
        if (unlikely (status))
            goto FINISH;

        dev_clip = clip = &target_clip;
    }

    if (clip && clip->all_clipped) {
        status = CAIRO_STATUS_SUCCESS;
        goto FINISH;
    }

    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
            _cairo_surface_wrapper_needs_extents_transform (wrapper))
    {
        cairo_matrix_t m;
        int i;

        cairo_matrix_init_identity (&m);

        if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
            cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);

        if (_cairo_surface_wrapper_needs_device_transform (wrapper))
            cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);

        if (clip != NULL) {
            status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
            if (unlikely (status))
                goto FINISH;

            dev_clip = &clip_copy;
        }

        dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
        if (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 (clip != NULL) {
            dev_clip = &clip_copy;
            _cairo_clip_init_copy (&clip_copy, clip);
        }
    }

    status = _cairo_surface_show_text_glyphs (wrapper->target, op, source,
             utf8, utf8_len,
             dev_glyphs, num_glyphs,
             clusters, num_clusters,
             cluster_flags,
             scaled_font,
             dev_clip);

FINISH:
    if (dev_clip != clip)
        _cairo_clip_reset (dev_clip);
    if (wrapper->has_extents)
        _cairo_clip_reset (&target_clip);
    if (dev_glyphs != glyphs)
        free (dev_glyphs);
    return status;
}
cairo_status_t
_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
                                    cairo_operator_t	     fill_op,
                                    const cairo_pattern_t   *fill_source,
                                    cairo_fill_rule_t	     fill_rule,
                                    double		     fill_tolerance,
                                    cairo_antialias_t	     fill_antialias,
                                    cairo_path_fixed_t	    *path,
                                    cairo_operator_t	     stroke_op,
                                    const cairo_pattern_t   *stroke_source,
                                    const cairo_stroke_style_t    *stroke_style,
                                    const cairo_matrix_t	    *stroke_ctm,
                                    const cairo_matrix_t	    *stroke_ctm_inverse,
                                    double		     stroke_tolerance,
                                    cairo_antialias_t	     stroke_antialias,
                                    cairo_clip_t	    *clip)
{
    cairo_status_t status;
    cairo_path_fixed_t path_copy, *dev_path = path;
    cairo_clip_t clip_copy, *dev_clip = clip;
    cairo_matrix_t dev_ctm = *stroke_ctm;
    cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
    cairo_pattern_union_t stroke_source_copy;
    cairo_pattern_union_t fill_source_copy;
    cairo_clip_t target_clip;

    if (unlikely (wrapper->target->status))
        return wrapper->target->status;

    if (wrapper->has_extents) {
        _cairo_clip_init_copy (&target_clip, clip);
        status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
        if (unlikely (status))
            goto FINISH;

        dev_clip = clip = &target_clip;
    }

    if (clip && clip->all_clipped) {
        status = CAIRO_STATUS_SUCCESS;
        goto FINISH;
    }

    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
            _cairo_surface_wrapper_needs_extents_transform (wrapper))
    {
        cairo_matrix_t m;

        cairo_matrix_init_identity (&m);

        if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
            cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);

        if (_cairo_surface_wrapper_needs_device_transform (wrapper))
            cairo_matrix_multiply (&m, &wrapper->target->device_transform, &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;

        if (clip != NULL) {
            status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
            if (unlikely (status))
                goto FINISH;

            dev_clip = &clip_copy;
        }

        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 (&stroke_source_copy.base, stroke_source, &m);
        stroke_source = &stroke_source_copy.base;

        _copy_transformed_pattern (&fill_source_copy.base, fill_source, &m);
        fill_source = &fill_source_copy.base;
    }
    else
    {
        if (clip != NULL) {
            dev_clip = &clip_copy;
            _cairo_clip_init_copy (&clip_copy, clip);
        }
    }

    status = _cairo_surface_fill_stroke (wrapper->target,
                                         fill_op, fill_source, fill_rule,
                                         fill_tolerance, fill_antialias,
                                         dev_path,
                                         stroke_op, stroke_source,
                                         stroke_style,
                                         &dev_ctm, &dev_ctm_inverse,
                                         stroke_tolerance, stroke_antialias,
                                         dev_clip);

FINISH:
    if (dev_path != path)
        _cairo_path_fixed_fini (dev_path);
    if (wrapper->has_extents)
        _cairo_clip_reset (&target_clip);
    if (dev_clip != clip)
        _cairo_clip_reset (dev_clip);
    return status;
}