Ejemplo n.º 1
0
cairo_status_t
_cairo_clip_clip (cairo_clip_t       *clip,
		  cairo_path_fixed_t *path,
		  cairo_fill_rule_t   fill_rule,
		  double              tolerance,
		  cairo_antialias_t   antialias,
		  cairo_surface_t    *target)
{
    cairo_status_t status;
    cairo_traps_t traps;
    cairo_path_fixed_t path_transformed;

    if (_cairo_surface_has_device_offset_or_scale (target)) {
	_cairo_path_fixed_init_copy (&path_transformed, path);
	_cairo_path_fixed_offset (&path_transformed,
				  _cairo_fixed_from_double (target->device_x_offset),
				  _cairo_fixed_from_double (target->device_y_offset));
	path = &path_transformed;
    }
    
    status = _cairo_clip_intersect_path (clip,
					 path, fill_rule, tolerance,
					 antialias);
    if (status == CAIRO_STATUS_SUCCESS)
        clip->serial = _cairo_surface_allocate_clip_serial (target);

    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	return status;


    _cairo_traps_init (&traps);
    status = _cairo_path_fixed_fill_to_traps (path,
					      fill_rule,
					      tolerance,
					      &traps);
    if (status)
	goto bail;

    status = _cairo_clip_intersect_region (clip, &traps, target);
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	goto bail;

    status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);
	
 bail:
    _cairo_traps_fini (&traps);
    if (path == &path_transformed)
	_cairo_path_fixed_fini (&path_transformed);

    return status;
}
Ejemplo n.º 2
0
cairo_status_t
_cairo_clip_clip (cairo_clip_t       *clip,
		  cairo_path_fixed_t *path,
		  cairo_fill_rule_t   fill_rule,
		  double              tolerance,
		  cairo_antialias_t   antialias,
		  cairo_surface_t    *target)
{
    cairo_status_t status;
    cairo_traps_t traps;

    if (clip->all_clipped)
	return CAIRO_STATUS_SUCCESS;

    /* catch the empty clip path */
    if (! path->has_current_point) {
	_cairo_clip_set_all_clipped (clip, target);
	return CAIRO_STATUS_SUCCESS;
    }

    status = _cairo_clip_intersect_path (clip,
					 path, fill_rule, tolerance,
					 antialias);
    if (status == CAIRO_STATUS_SUCCESS)
        clip->serial = _cairo_surface_allocate_clip_serial (target);

    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	return status;

    _cairo_traps_init (&traps);
    status = _cairo_path_fixed_fill_to_traps (path,
					      fill_rule,
					      tolerance,
					      &traps);
    if (status)
	goto bail;

    status = _cairo_clip_intersect_region (clip, &traps, target);
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	goto bail;

    status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);

 bail:
    _cairo_traps_fini (&traps);

    return status;
}
Ejemplo n.º 3
0
cairo_status_t
_cairo_clip_clip (cairo_clip_t       *clip,
		  cairo_path_fixed_t *path,
		  cairo_fill_rule_t   fill_rule,
		  double              tolerance,
		  cairo_antialias_t   antialias,
		  cairo_surface_t    *target)
{
    cairo_status_t status;
    cairo_rectangle_int_t rectangle;
    cairo_traps_t traps;
    cairo_box_t ignored_box;

    if (clip->all_clipped)
	return CAIRO_STATUS_SUCCESS;

    /* catch the empty clip path */
    if (! path->has_current_point) {
	_cairo_clip_set_all_clipped (clip, target);
	return CAIRO_STATUS_SUCCESS;
    }

    status = _cairo_clip_intersect_path (clip,
					 path, fill_rule, tolerance,
					 antialias);
    if (status == CAIRO_STATUS_SUCCESS)
        clip->serial = _cairo_surface_allocate_clip_serial (target);

    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	return status;

    /* TODO: allow ANTIALIAS_NONE when we have a mono scan converter
     * again. */
    if (antialias != CAIRO_ANTIALIAS_NONE &&
	!_cairo_path_fixed_is_box (path, &ignored_box) &&
	!_cairo_path_fixed_is_region (path))
    {
	status = _cairo_clip_intersect_mask_using_spans (
	    clip, path, fill_rule, tolerance, antialias, target);
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	    return status;
    }

    _cairo_traps_init (&traps);

    /* Limit the traps to the target surface
     * - so we don't add more traps than needed. */
    status = _cairo_surface_get_extents (target, &rectangle);
    if (status == CAIRO_STATUS_SUCCESS) {
	cairo_box_t box;

	_cairo_box_from_rectangle (&box, &rectangle);
	_cairo_traps_limit (&traps, &box);
    }

    status = _cairo_path_fixed_fill_to_traps (path,
					      fill_rule,
					      tolerance,
					      &traps);
    if (unlikely (status))
	goto bail;

    status = _cairo_clip_intersect_region (clip, &traps, target);
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	goto bail;

    status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);

 bail:
    _cairo_traps_fini (&traps);

    return status;
}