Пример #1
0
	void substractTaintedArea(const IntRect &rect)
	{
		if (!touchesTaintedArea(rect))
			return;

		pixman_region16_t m_reg;
		pixman_region_init_rect(&m_reg, rect.x, rect.y, rect.w, rect.h);

		pixman_region_subtract(&tainted, &m_reg, &tainted);

		pixman_region_fini(&m_reg);
	}
/* Warning: This call modifies the coordinates of traps */
static cairo_status_t
_clip_and_composite_trapezoids (cairo_pattern_t *src,
				cairo_operator_t op,
				cairo_surface_t *dst,
				cairo_traps_t *traps,
				cairo_clip_t *clip,
				cairo_antialias_t antialias)
{
    cairo_status_t status;
    pixman_region16_t *trap_region;
    pixman_region16_t *clear_region = NULL;
    cairo_rectangle_int16_t extents;
    cairo_composite_traps_info_t traps_info;

    if (traps->num_traps == 0)
	return CAIRO_STATUS_SUCCESS;

    status = _cairo_traps_extract_region (traps, &trap_region);
    if (status)
	return status;

    if (_cairo_operator_bounded_by_mask (op))
    {
	if (trap_region) {
	    status = _cairo_clip_intersect_to_region (clip, trap_region);
	    _cairo_region_extents_rectangle (trap_region, &extents);
	} else {
	    cairo_box_t trap_extents;
	    _cairo_traps_extents (traps, &trap_extents);
	    _cairo_box_round_to_rectangle (&trap_extents, &extents);
	    status = _cairo_clip_intersect_to_rectangle (clip, &extents);
	}
    }
    else
    {
	cairo_surface_t *clip_surface = clip ? clip->surface : NULL;

	status = _cairo_surface_get_extents (dst, &extents);
	if (status)
	    return status;

	if (trap_region && !clip_surface) {
	    /* If we optimize drawing with an unbounded operator to
	     * _cairo_surface_fill_rectangles() or to drawing with a
	     * clip region, then we have an additional region to clear.
	     */
	    clear_region = _cairo_region_create_from_rectangle (&extents);
	    if (clear_region == NULL)
		return CAIRO_STATUS_NO_MEMORY;

	    status = _cairo_clip_intersect_to_region (clip, clear_region);
	    if (status)
		return status;

	    _cairo_region_extents_rectangle (clear_region,  &extents);

	    if (pixman_region_subtract (clear_region, clear_region, trap_region) != PIXMAN_REGION_STATUS_SUCCESS)
		return CAIRO_STATUS_NO_MEMORY;

	    if (!pixman_region_not_empty (clear_region)) {
		pixman_region_destroy (clear_region);
		clear_region = NULL;
	    }
	} else {
	    status = _cairo_clip_intersect_to_rectangle (clip, &extents);
	    if (status)
		return status;
	}
    }

    if (status)
	goto out;

    if (trap_region)
    {
	cairo_surface_t *clip_surface = clip ? clip->surface : NULL;

	if ((src->type == CAIRO_PATTERN_TYPE_SOLID || op == CAIRO_OPERATOR_CLEAR) &&
	    !clip_surface)
	{
	    const cairo_color_t *color;

	    if (op == CAIRO_OPERATOR_CLEAR)
		color = CAIRO_COLOR_TRANSPARENT;
	    else
		color = &((cairo_solid_pattern_t *)src)->color;

	    /* Solid rectangles special case */
	    status = _cairo_surface_fill_region (dst, op, color, trap_region);
	    if (!status && clear_region)
		status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
						     CAIRO_COLOR_TRANSPARENT,
						     clear_region);

	    goto out;
	}

	if ((_cairo_operator_bounded_by_mask (op) && op != CAIRO_OPERATOR_SOURCE) ||
	    !clip_surface)
	{
	    /* For a simple rectangle, we can just use composite(), for more
	     * rectangles, we have to set a clip region. The cost of rasterizing
	     * trapezoids is pretty high for most backends currently, so it's
	     * worthwhile even if a region is needed.
	     *
	     * If we have a clip surface, we set it as the mask; this only works
	     * for bounded operators other than SOURCE; for unbounded operators,
	     * clip and mask cannot be interchanged. For SOURCE, the operator
	     * as implemented by the backends is different in it's handling
	     * of the mask then what we want.
	     *
	     * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has
	     * more than rectangle and the destination doesn't support clip
	     * regions. In that case, we fall through.
	     */
	    status = _composite_trap_region (clip, src, op, dst,
					     trap_region, &extents);
	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	    {
		if (!status && clear_region)
		    status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
							 CAIRO_COLOR_TRANSPARENT,
							 clear_region);
		goto out;
	    }
	}
    }

    traps_info.traps = traps;
    traps_info.antialias = antialias;

    status = _clip_and_composite (clip, op, src,
				  _composite_traps_draw_func, &traps_info,
				  dst, &extents);

 out:
    if (trap_region)
	pixman_region_destroy (trap_region);
    if (clear_region)
	pixman_region_destroy (clear_region);

    return status;
}
Пример #3
0
EAPI int
ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *rm, Ecore_X_XRegion *rs)
{
   return pixman_region_subtract((pixman_region16_t *)dst, (pixman_region16_t *)rm, (pixman_region16_t *)rs);
}
Пример #4
0
EAPI Eina_Bool
ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *rm, Ecore_X_XRegion *rs)
{
   return pixman_region_subtract((pixman_region16_t *)dst, (pixman_region16_t *)rm, (pixman_region16_t *)rs);
} /* ecore_x_xregion_subtract */