Esempio n. 1
0
void
_cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
			   const cairo_unscaled_font_backend_t *backend)
{
    CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
    unscaled_font->backend = backend;
}
Esempio n. 2
0
static cairo_status_t
_cairo_clip_intersect_path (cairo_clip_t       *clip,
			    cairo_path_fixed_t *path,
			    cairo_fill_rule_t   fill_rule,
			    double              tolerance,
			    cairo_antialias_t   antialias)
{
    cairo_clip_path_t *clip_path;
    cairo_status_t status;

    if (clip->mode != CAIRO_CLIP_MODE_PATH)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    clip_path = malloc (sizeof (cairo_clip_path_t));
    if (clip_path == NULL)
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    status = _cairo_path_fixed_init_copy (&clip_path->path, path);
    if (status) {
	free (clip_path);
	return status;
    }

    CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1);
    clip_path->fill_rule = fill_rule;
    clip_path->tolerance = tolerance;
    clip_path->antialias = antialias;
    clip_path->prev = clip->path;
    clip->path = clip_path;

    return CAIRO_STATUS_SUCCESS;
}
Esempio n. 3
0
cairo_drm_device_t *
_cairo_drm_device_init (cairo_drm_device_t *dev,
			int fd,
			dev_t devid,
			int max_surface_size)
{
    CAIRO_REFERENCE_COUNT_INIT (&dev->ref_count, 1);
    dev->status = CAIRO_STATUS_SUCCESS;

    dev->id = devid;
    dev->fd = fd;

    dev->max_surface_size = max_surface_size;

    dev->prev = NULL;
    dev->next = _cairo_drm_known_devices;
    if (_cairo_drm_known_devices != NULL)
	_cairo_drm_known_devices->prev = dev;
    _cairo_drm_known_devices = dev;

    if (_cairo_drm_default_device == NULL)
	_cairo_drm_default_device = cairo_drm_device_reference (dev);

    return dev;
}
Esempio n. 4
0
void
_cairo_region_init (cairo_region_t *region)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));

    region->status = CAIRO_STATUS_SUCCESS;
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
    pixman_region32_init (&region->rgn);
}
Esempio n. 5
0
void
_cairo_region_init_rectangle (cairo_region_t *region,
			      const cairo_rectangle_int_t *rectangle)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));

    region->status = CAIRO_STATUS_SUCCESS;
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
    pixman_region32_init_rect (&region->rgn,
			       rectangle->x, rectangle->y,
			       rectangle->width, rectangle->height);
}
Esempio n. 6
0
void
_cairo_font_face_init (cairo_font_face_t               *font_face,
		       const cairo_font_face_backend_t *backend)
{
    CAIRO_MUTEX_INITIALIZE ();

    font_face->status = CAIRO_STATUS_SUCCESS;
    CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
    font_face->backend = backend;

    _cairo_user_data_array_init (&font_face->user_data);
}
Esempio n. 7
0
/**
 * cairo_region_create_rectangles:
 * @rects: an array of @count rectangles
 * @count: number of rectangles
 *
 * Allocates a new region object containing the union of all given @rects.
 *
 * Return value: A newly allocated #cairo_region_t. Free with
 *   cairo_region_destroy(). This function always returns a
 *   valid pointer; if memory cannot be allocated, then a special
 *   error object is returned where all operations on the object do nothing.
 *   You can check for this with cairo_region_status().
 *
 * Since: 1.10
 **/
cairo_region_t *
cairo_region_create_rectangles (const cairo_rectangle_int_t *rects,
				int count)
{
    pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
    pixman_box32_t *pboxes = stack_pboxes;
    cairo_region_t *region;
    int i;

    region = _cairo_malloc (sizeof (cairo_region_t));
    if (unlikely (region == NULL))
	return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
    region->status = CAIRO_STATUS_SUCCESS;

    if (count == 1) {
	pixman_region32_init_rect (&region->rgn,
				   rects->x, rects->y,
				   rects->width, rects->height);

	return region;
    }

    if (count > ARRAY_LENGTH (stack_pboxes)) {
	pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
	if (unlikely (pboxes == NULL)) {
	    free (region);
	    return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
	}
    }

    for (i = 0; i < count; i++) {
	pboxes[i].x1 = rects[i].x;
	pboxes[i].y1 = rects[i].y;
	pboxes[i].x2 = rects[i].x + rects[i].width;
	pboxes[i].y2 = rects[i].y + rects[i].height;
    }

    i = pixman_region32_init_rects (&region->rgn, pboxes, count);

    if (pboxes != stack_pboxes)
	free (pboxes);

    if (unlikely (i == 0)) {
	free (region);
	return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }

    return region;
}
Esempio n. 8
0
/**
 * cairo_region_create:
 *
 * Allocates a new empty region object.
 *
 * Return value: A newly allocated #cairo_region_t. Free with
 *   cairo_region_destroy(). This function always returns a
 *   valid pointer; if memory cannot be allocated, then a special
 *   error object is returned where all operations on the object do nothing.
 *   You can check for this with cairo_region_status().
 *
 * Since: 1.10
 **/
cairo_region_t *
cairo_region_create (void)
{
    cairo_region_t *region;

    region = _cairo_malloc (sizeof (cairo_region_t));
    if (region == NULL)
	return (cairo_region_t *) &_cairo_region_nil;

    region->status = CAIRO_STATUS_SUCCESS;
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);

    pixman_region32_init (&region->rgn);

    return region;
}
Esempio n. 9
0
static cairo_drm_bo_t *
_gallium_fake_bo_create (uint32_t size, uint32_t name)
{
    cairo_drm_bo_t *bo;

    /* XXX integrate with winsys handle */

    bo = malloc (sizeof (cairo_drm_bo_t));

    CAIRO_REFERENCE_COUNT_INIT (&bo->ref_count, 1);
    bo->name = name;
    bo->handle = 0;
    bo->size = size;

    return bo;
}
Esempio n. 10
0
/**
 * cairo_region_create_rectangle:
 * @rectangle: a #cairo_rectangle_int_t
 *
 * Allocates a new region object containing @rectangle.
 *
 * Return value: A newly allocated #cairo_region_t. Free with
 *   cairo_region_destroy(). This function always returns a
 *   valid pointer; if memory cannot be allocated, then a special
 *   error object is returned where all operations on the object do nothing.
 *   You can check for this with cairo_region_status().
 *
 * Since: 1.10
 **/
cairo_region_t *
cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle)
{
    cairo_region_t *region;

    region = _cairo_malloc (sizeof (cairo_region_t));
    if (unlikely (region == NULL))
	return (cairo_region_t *) &_cairo_region_nil;

    region->status = CAIRO_STATUS_SUCCESS;
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);

    pixman_region32_init_rect (&region->rgn,
			       rectangle->x, rectangle->y,
			       rectangle->width, rectangle->height);

    return region;
}
Esempio n. 11
0
cairo_region_t *
_cairo_region_create_from_boxes (const cairo_box_t *boxes, int count)
{
    cairo_region_t *region;

    region = _cairo_malloc (sizeof (cairo_region_t));
    if (unlikely (region == NULL))
	return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
    region->status = CAIRO_STATUS_SUCCESS;

    if (! pixman_region32_init_rects (&region->rgn,
				      (pixman_box32_t *)boxes, count)) {
	free (region);
	return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }

    return region;
}
Esempio n. 12
0
static cairo_clip_path_t *
_cairo_clip_path_create (cairo_clip_t *clip)
{
    cairo_clip_path_t *clip_path;

    clip_path = _freed_pool_get (&clip_path_pool);
    if (unlikely (clip_path == NULL)) {
	clip_path = malloc (sizeof (cairo_clip_path_t));
	if (unlikely (clip_path == NULL))
	    return NULL;
    }

    CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1);

    clip_path->flags = 0;
    clip_path->region = NULL;
    clip_path->surface = NULL;

    clip_path->prev = clip->path;
    clip->path = clip_path;

    return clip_path;
}
Esempio n. 13
0
cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
{
    cairo_xlib_screen_info_t *info = NULL, **prev;

    CAIRO_MUTEX_LOCK (display->mutex);
    if (display->closed) {
	CAIRO_MUTEX_UNLOCK (display->mutex);
	return NULL;
    }

    for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
	if (info->screen == screen) {
	    /*
	     * MRU the list
	     */
	    if (prev != &display->screens) {
		*prev = info->next;
		info->next = display->screens;
		display->screens = info;
	    }
	    break;
	}
    }
    CAIRO_MUTEX_UNLOCK (display->mutex);

    if (info != NULL) {
	info = _cairo_xlib_screen_info_reference (info);
    } else {
	info = malloc (sizeof (cairo_xlib_screen_info_t));
	if (info != NULL) {
	    CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
	    CAIRO_MUTEX_INIT (info->mutex);
	    info->display = _cairo_xlib_display_reference (display);
	    info->screen = screen;
	    info->has_render = FALSE;
	    _cairo_font_options_init_default (&info->font_options);
	    memset (info->gc, 0, sizeof (info->gc));
	    info->gc_needs_clip_reset = 0;

	    _cairo_array_init (&info->visuals,
			       sizeof (cairo_xlib_visual_info_t*));

	    if (screen) {
		Display *dpy = display->display;
		int event_base, error_base;

		info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
			(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
		_cairo_xlib_init_screen_font_options (dpy, info);
	    }

	    CAIRO_MUTEX_LOCK (display->mutex);
	    info->next = display->screens;
	    display->screens = info;
	    CAIRO_MUTEX_UNLOCK (display->mutex);
	}
    }

    return info;
}
Esempio n. 14
0
cairo_int_status_t
_cairo_gl_gradient_create (cairo_gl_context_t           *ctx,
			   unsigned int                  n_stops,
			   const cairo_gradient_stop_t  *stops,
			   cairo_gl_gradient_t         **gradient_out)
{
    unsigned long hash;
    cairo_gl_gradient_t *gradient;
    cairo_status_t status;
    int tex_width;
    GLint internal_format;
    void *data;

    if ((unsigned int) ctx->max_texture_size / 2 <= n_stops)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    hash = _cairo_gl_gradient_hash (n_stops, stops);

    gradient = _cairo_gl_gradient_lookup (ctx, hash, n_stops, stops);
    if (gradient) {
	*gradient_out = _cairo_gl_gradient_reference (gradient);
	return CAIRO_STATUS_SUCCESS;
    }

    gradient = _cairo_malloc (sizeof (cairo_gl_gradient_t) + sizeof (cairo_gradient_stop_t) * (n_stops - 1));
    if (gradient == NULL)
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    tex_width = _cairo_gl_gradient_sample_width (n_stops, stops);
    if (tex_width > ctx->max_texture_size)
	tex_width = ctx->max_texture_size;

    CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 2);
    gradient->cache_entry.hash = hash;
    gradient->cache_entry.size = tex_width;
    gradient->device = &ctx->base;
    gradient->n_stops = n_stops;
    gradient->stops = gradient->stops_embedded;
    memcpy (gradient->stops_embedded, stops, n_stops * sizeof (cairo_gradient_stop_t));

    glGenTextures (1, &gradient->tex);
    _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
    glBindTexture (ctx->tex_target, gradient->tex);

    data = _cairo_malloc_ab (tex_width, sizeof (uint32_t));
    if (unlikely (data == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto cleanup_gradient;
    }

    status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width);
    if (unlikely (status))
	goto cleanup_data;

    /*
     * In OpenGL ES 2.0 no format conversion is allowed i.e. 'internalFormat'
     * must match 'format' in glTexImage2D.
     */
    if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES3 ||
	_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2)
	internal_format = GL_BGRA;
    else
	internal_format = GL_RGBA;

    glTexImage2D (ctx->tex_target, 0, internal_format, tex_width, 1, 0,
		  GL_BGRA, GL_UNSIGNED_BYTE, data);

    free (data);

    /* we ignore errors here and just return an uncached gradient */
    if (unlikely (_cairo_cache_insert (&ctx->gradients, &gradient->cache_entry)))
	CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1);

    *gradient_out = gradient;
    return CAIRO_STATUS_SUCCESS;

cleanup_data:
    free (data);
cleanup_gradient:
    free (gradient);
    return status;
}
Esempio n. 15
0
cairo_xlib_display_t *
_cairo_xlib_display_get (Display *dpy)
{
    cairo_xlib_display_t *display;
    cairo_xlib_display_t **prev;
    XExtCodes *codes;
    int major_unused, minor_unused;

    /* There is an apparent deadlock between this mutex and the
     * mutex for the display, but it's actually safe. For the
     * app to call XCloseDisplay() while any other thread is
     * inside this function would be an error in the logic
     * app, and the CloseDisplay hook is the only other place we
     * acquire this mutex.
     */
    CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex);

    for (prev = &_cairo_xlib_display_list; (display = *prev); prev = &(*prev)->next)
    {
	if (display->display == dpy) {
	    /*
	     * MRU the list
	     */
	    if (prev != &_cairo_xlib_display_list) {
		*prev = display->next;
		display->next = _cairo_xlib_display_list;
		_cairo_xlib_display_list = display;
	    }
	    break;
	}
    }

    if (display != NULL) {
	display = _cairo_xlib_display_reference (display);
	goto UNLOCK;
    }

    display = malloc (sizeof (cairo_xlib_display_t));
    if (display == NULL) {
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
	goto UNLOCK;
    }

    /* Xlib calls out to the extension close_display hooks in LIFO
     * order. So we have to ensure that all extensions that we depend
     * on in our close_display hook are properly initialized before we
     * add our hook. For now, that means Render, so we call into its
     * QueryVersion function to ensure it gets initialized.
     */
    XRenderQueryVersion (dpy, &major_unused, &minor_unused);

    codes = XAddExtension (dpy);
    if (codes == NULL) {
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
	free (display);
	display = NULL;
	goto UNLOCK;
    }

    XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);

    _cairo_freelist_init (&display->wq_freelist, sizeof (cairo_xlib_job_t));
    _cairo_freelist_init (&display->hook_freelist, sizeof (cairo_xlib_hook_t));

    CAIRO_REFERENCE_COUNT_INIT (&display->ref_count, 2); /* add one for the CloseDisplay */
    CAIRO_MUTEX_INIT (display->mutex);
    display->display = dpy;
    display->screens = NULL;
    display->workqueue = NULL;
    display->close_display_hooks = NULL;
    display->closed = FALSE;

    display->buggy_repeat = FALSE;
    if (strstr (ServerVendor (dpy), "X.Org") != NULL) {
	/* When modularized, the X.Org server VendorRelease was
	 * bogusly reset to a very small number, without any change in
	 * the ServerVendor string. We avoid considering the new
	 * servers with the small number as buggy by restricting the
	 * test to known bad releases. But there could be a problem
	 * again in the future if X.Org server versions ever climb
	 * back up to 6.7 or 6.8. */
	if (VendorRelease (dpy) >= 60700000 && VendorRelease (dpy) <= 60802000)
	    display->buggy_repeat = TRUE;

	/* But even the new modular server has bugs, (bad enough to
	 * crash the X server), that it so happens we can avoid with
	 * the exact same buggy_repeat workaround. We've verified that
	 * this bug exists as least as late as version 1.3.0.0, (which
	 * is in Fedora 8), and is gone again in version 1.4.99.901
	 * (from a Fedora 9 Beta). Versions between those are still
	 * unknown, but until we learn more, we'll assume that any 1.3
	 * version is buggy.  */
	if (VendorRelease (dpy) < 10400000)
	    display->buggy_repeat = TRUE;
    } else if (strstr (ServerVendor (dpy), "XFree86") != NULL) {
	if (VendorRelease (dpy) <= 40500000)
	    display->buggy_repeat = TRUE;
    }

    display->next = _cairo_xlib_display_list;
    _cairo_xlib_display_list = display;

UNLOCK:
    CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
    return display;
}