Esempio n. 1
0
// cairo_public cairo_status_t
// cairo_region_status (const cairo_region_t *region);
static int l_cairo_region_status (lua_State* L)
{
    const cairo_region_t *region = get_cairo_region_t (L, 1);
    cairo_status_t v = cairo_region_status (region);
    lua_pushinteger(L, v);
    return 1;
}
static void
update_shape (GtkWidget* window,
	      gint       radius,
	      gint       shadow_size)
{
	if (g_composited)
	{		
		/* remove any current shape-mask */
		gtk_widget_input_shape_combine_region (window, NULL);
		return;
	}

	int width;
	int height;
	gtk_widget_get_size_request (window, &width, &height);
	const cairo_rectangle_int_t rects[] = {{2, 0, width - 4, height},
										   {1, 1, width - 2, height - 2},
										   {0, 2, width, height - 4}};
	cairo_region_t* region = NULL;

	region = cairo_region_create_rectangles (rects, 3);
	if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS)
	{
		gtk_widget_shape_combine_region (window, NULL);
		gtk_widget_shape_combine_region (window, region);
	}
}
static
void
update_input_shape (GtkWidget* window,
		    gint       width,
		    gint       height)
{
	cairo_region_t*             region = NULL;
	const cairo_rectangle_int_t rect   = {0, 0, 1, 1};

	region = cairo_region_create_rectangle (&rect);
	if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS)
	{
		gtk_widget_input_shape_combine_region (window, NULL);
		gtk_widget_input_shape_combine_region (window, region);
	}
}
Esempio n. 4
0
/* Warning: This call modifies the coordinates of traps */
static cairo_status_t
_clip_and_composite_trapezoids (const 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;
    cairo_region_t *trap_region = NULL;
    cairo_region_t *clear_region = NULL;
    cairo_rectangle_int_t extents;
    cairo_composite_traps_info_t traps_info;

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

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

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

    if (_cairo_operator_bounded_by_mask (op)) {
        cairo_rectangle_int_t trap_extents;

        if (trap_region) {
            status = _cairo_clip_intersect_to_region (clip, trap_region);
            if (unlikely (status))
                goto out;

            cairo_region_get_extents (trap_region, &trap_extents);
        } else {
            cairo_box_t trap_box;
            _cairo_traps_extents (traps, &trap_box);
            _cairo_box_round_to_rectangle (&trap_box, &trap_extents);
        }

        if (! _cairo_rectangle_intersect (&extents, &trap_extents)) {
	    status = CAIRO_STATUS_SUCCESS;
	    goto out;
	}

        status = _cairo_clip_intersect_to_rectangle (clip, &extents);
        if (unlikely (status))
            goto out;
    } else {
        cairo_surface_t *clip_surface = clip ? clip->surface : NULL;

        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_rectangle (&extents);

	    status = cairo_region_status (clear_region);
	    if (unlikely (status))
		goto out;

            status = _cairo_clip_intersect_to_region (clip, clear_region);
            if (unlikely (status))
                goto out;

            cairo_region_get_extents (clear_region, &extents);

            status = cairo_region_subtract (clear_region, trap_region);
            if (unlikely (status))
                goto out;

            if (cairo_region_is_empty (clear_region)) {
                cairo_region_destroy (clear_region);
		clear_region = NULL;
            }
        } else {
            status = _cairo_clip_intersect_to_rectangle (clip, &extents);
        }
    }

    if (unlikely (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 its 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)
        cairo_region_destroy (trap_region);
    if (clear_region)
        cairo_region_destroy (clear_region);

    return status;
}