cairo_status_t
_cairo_surface_wrapper_fill (cairo_surface_wrapper_t	*wrapper,
			     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_matrix_t device_transform;
    cairo_path_fixed_t path_copy, *dev_path = path;
    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 (_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;
	}
    } else {
	if (clip != NULL) {
	    dev_clip = &clip_copy;
	    _cairo_clip_init_copy (&clip_copy, clip);
	}
    }

    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);
    if (dev_clip != clip)
	_cairo_clip_reset (dev_clip);
    return status;
}
Exemplo n.º 2
0
void
_cairo_surface_wrapper_intersect_extents (cairo_surface_wrapper_t *wrapper,
					  const cairo_rectangle_int_t *extents)
{
    if (! wrapper->has_extents) {
	wrapper->extents = *extents;
	wrapper->has_extents = TRUE;
    } else
	_cairo_rectangle_intersect (&wrapper->extents, extents);

    wrapper->needs_transform =
	_cairo_surface_wrapper_needs_device_transform (wrapper);
}
Exemplo n.º 3
0
void
_cairo_surface_wrapper_set_inverse_transform (cairo_surface_wrapper_t *wrapper,
					      const cairo_matrix_t *transform)
{
    cairo_status_t status;

    if (transform == NULL || _cairo_matrix_is_identity (transform)) {
	cairo_matrix_init_identity (&wrapper->transform);

	wrapper->needs_transform =
	    _cairo_surface_wrapper_needs_device_transform (wrapper);
    } else {
	wrapper->transform = *transform;
	status = cairo_matrix_invert (&wrapper->transform);
	/* should always be invertible unless given pathological input */
	assert (status == CAIRO_STATUS_SUCCESS);

	wrapper->needs_transform = TRUE;
    }
}
cairo_status_t
_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
			     cairo_operator_t	 op,
			     const cairo_pattern_t *source,
			     const cairo_pattern_t *mask,
			     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_mask (wrapper->target, op, source, mask, dev_clip);

  FINISH:
    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;
}
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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;
}