Exemplo n.º 1
0
static cairo_int_status_t
clip_and_composite_polygon (const cairo_spans_compositor_t	*compositor,
			    cairo_composite_rectangles_t	 *extents,
			    cairo_polygon_t			*polygon,
			    cairo_fill_rule_t			 fill_rule,
			    cairo_antialias_t			 antialias)
{
    cairo_int_status_t status;

    /* XXX simply uses polygon limits.point extemities, tessellation? */
    status = trim_extents_to_polygon (extents, polygon);
    if (unlikely (status))
	return status;

    if (_cairo_polygon_is_empty (polygon)) {
	cairo_boxes_t boxes;

	if (extents->is_bounded)
	    return CAIRO_STATUS_SUCCESS;

	_cairo_boxes_init (&boxes);
	extents->bounded.width = extents->bounded.height = 0;
	return fixup_unbounded_boxes (compositor, extents, &boxes);
    }

    if (extents->is_bounded && extents->clip->path) {
	cairo_polygon_t clipper;
	cairo_antialias_t clip_antialias;
	cairo_fill_rule_t clip_fill_rule;

	status = _cairo_clip_get_polygon (extents->clip,
					  &clipper,
					  &clip_fill_rule,
					  &clip_antialias);
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
	    cairo_clip_t *old_clip;

	    if (clip_antialias == antialias) {
		/* refresh limits after trimming extents */
		_cairo_polygon_limit_to_clip(polygon, extents->clip);

		status = _cairo_polygon_intersect (polygon, fill_rule,
						   &clipper, clip_fill_rule);
		_cairo_polygon_fini (&clipper);
		if (unlikely (status))
		    return status;

		old_clip = extents->clip;
		extents->clip = _cairo_clip_copy_region (extents->clip);
		_cairo_clip_destroy (old_clip);
	    } else {
		_cairo_polygon_fini (&clipper);
	    }
	}
    }

    return composite_polygon (compositor, extents,
			      polygon, fill_rule, antialias);
}
static cairo_int_status_t
clip_and_composite_polygon (const cairo_spans_compositor_t	*compositor,
			    cairo_composite_rectangles_t	 *extents,
			    cairo_polygon_t			*polygon,
			    cairo_fill_rule_t			 fill_rule,
			    cairo_antialias_t			 antialias)
{
    cairo_int_status_t status;

    TRACE ((stderr, "%s\n", __FUNCTION__));

    /* XXX simply uses polygon limits.point extemities, tessellation? */
    status = trim_extents_to_polygon (extents, polygon);
    if (unlikely (status))
	return status;

    if (_cairo_polygon_is_empty (polygon)) {
	cairo_boxes_t boxes;

	if (extents->is_bounded)
	    return CAIRO_STATUS_SUCCESS;

	_cairo_boxes_init (&boxes);
	extents->bounded.width = extents->bounded.height = 0;
	return fixup_unbounded_boxes (compositor, extents, &boxes);
    }

    if (extents->is_bounded && extents->clip->path) {
	cairo_polygon_t clipper;
	cairo_antialias_t clip_antialias;
	cairo_fill_rule_t clip_fill_rule;

	TRACE((stderr, "%s - combining shape with clip polygon\n",
	       __FUNCTION__));

	status = _cairo_clip_get_polygon (extents->clip,
					  &clipper,
					  &clip_fill_rule,
					  &clip_antialias);
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
	    cairo_clip_t *old_clip;

	    if (clip_antialias == antialias) {
		status = _cairo_polygon_intersect (polygon, fill_rule,
						   &clipper, clip_fill_rule);
		_cairo_polygon_fini (&clipper);
		if (unlikely (status))
		    return status;

		old_clip = extents->clip;
		extents->clip = _cairo_clip_copy_region (extents->clip);
		_cairo_clip_destroy (old_clip);

		status = trim_extents_to_polygon (extents, polygon);
		if (unlikely (status))
		    return status;

		fill_rule = CAIRO_FILL_RULE_WINDING;
	    } else {
		_cairo_polygon_fini (&clipper);
	    }
	}
    }

    return composite_polygon (compositor, extents,
			      polygon, fill_rule, antialias);
}