Ejemplo n.º 1
0
/**
 * cairo_image_surface_create_for_data:
 * @data: a pointer to a buffer supplied by the application in which
 *     to write contents. This pointer must be suitably aligned for any
 *     kind of variable, (for example, a pointer returned by malloc).
 * @format: the format of pixels in the buffer
 * @width: the width of the image to be stored in the buffer
 * @height: the height of the image to be stored in the buffer
 * @stride: the number of bytes between the start of rows in the
 *     buffer as allocated. This value should always be computed by
 *     cairo_format_stride_for_width() before allocating the data
 *     buffer.
 *
 * Creates an image surface for the provided pixel data. The output
 * buffer must be kept around until the #cairo_surface_t is destroyed
 * or cairo_surface_finish() is called on the surface.  The initial
 * contents of @data will be used as the initial image contents; you
 * must explicitly clear the buffer, using, for example,
 * cairo_rectangle() and cairo_fill() if you want it cleared.
 *
 * Note that the stride may be larger than
 * width*bytes_per_pixel to provide proper alignment for each pixel
 * and row. This alignment is required to allow high-performance rendering
 * within cairo. The correct way to obtain a legal stride value is to
 * call cairo_format_stride_for_width() with the desired format and
 * maximum image width value, and the use the resulting stride value
 * to allocate the data and to create the image surface. See
 * cairo_format_stride_for_width() for example code.
 *
 * Return value: a pointer to the newly created surface. The caller
 * owns the surface and should call cairo_surface_destroy() when done
 * with it.
 *
 * This function always returns a valid pointer, but it will return a
 * pointer to a "nil" surface in the case of an error such as out of
 * memory or an invalid stride value. In case of invalid stride value
 * the error status of the returned surface will be
 * %CAIRO_STATUS_INVALID_STRIDE.  You can use
 * cairo_surface_status() to check for this.
 *
 * See cairo_surface_set_user_data() for a means of attaching a
 * destroy-notification fallback to the surface if necessary.
 **/
cairo_surface_t *
cairo_image_surface_create_for_data (unsigned char     *data,
                                     cairo_format_t	format,
                                     int		width,
                                     int		height,
                                     int		stride)
{
    pixman_format_code_t pixman_format;
    int minstride;

    if (! CAIRO_FORMAT_VALID (format))
        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));

    if ((stride & (CAIRO_STRIDE_ALIGNMENT-1)) != 0)
        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));

    minstride = cairo_format_stride_for_width (format, width);
    if (stride < 0) {
        if (stride > -minstride) {
            return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
        }
    } else {
        if (stride < minstride) {
            return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
        }
    }

    pixman_format = _cairo_format_to_pixman_format_code (format);

    return _cairo_image_surface_create_with_pixman_format (data, pixman_format,
            width, height, stride);
}
Ejemplo n.º 2
0
static cairo_surface_t *
radeon_surface_create_internal (cairo_drm_device_t *device,
				cairo_format_t format,
				int width, int height)
{
    radeon_surface_t *surface;
    cairo_status_t status;

    surface = malloc (sizeof (radeon_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    radeon_surface_init (surface, device, format, width, height);

    if (width && height) {
	surface->base.stride =
	    cairo_format_stride_for_width (surface->base.format, width);

	surface->base.bo = radeon_bo_create (to_radeon_device (&device->base),
					     surface->base.stride * height,
					     RADEON_GEM_DOMAIN_GTT);

	if (unlikely (surface->base.bo == NULL)) {
	    status = _cairo_drm_surface_finish (&surface->base);
	    free (surface);
	    return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
	}
    }

    return &surface->base.base;
}
Ejemplo n.º 3
0
cairo_surface_t *
cairo_gl_surface_create_for_window (cairo_device_t	*device,
				    Window		 win,
				    int			 width,
				    int			 height)
{
    cairo_glx_surface_t *surface;

    if (unlikely (device->status))
	return _cairo_surface_create_in_error (device->status);

    if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));

    if (width <= 0 || height <= 0)
        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));

    surface = calloc (1, sizeof (cairo_glx_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_gl_surface_init (device, &surface->base,
			    CAIRO_CONTENT_COLOR_ALPHA, width, height);
    surface->win = win;

    return &surface->base.base;
}
Ejemplo n.º 4
0
static cairo_surface_t *
_cairo_gl_surface_create_similar (void		 *abstract_surface,
				  cairo_content_t  content,
				  int		  width,
				  int		  height)
{
    cairo_surface_t *surface = abstract_surface;
    cairo_gl_context_t *ctx;
    cairo_status_t status;

    if (! _cairo_gl_surface_size_valid (abstract_surface, width, height))
        return _cairo_image_surface_create_with_content (content, width, height);

    status = _cairo_gl_context_acquire (surface->device, &ctx);
    if (unlikely (status))
	return _cairo_surface_create_in_error (status);

    surface = _cairo_gl_surface_create_scratch (ctx, content, width, height);

    status = _cairo_gl_context_release (ctx, status);
    if (unlikely (status)) {
        cairo_surface_destroy (surface);
        return _cairo_surface_create_in_error (status);
    }

    return surface;
}
Ejemplo n.º 5
0
/**
 * cairo_xcb_surface_create_for_bitmap:
 * @connection: an XCB connection
 * @screen: the XCB screen associated with @bitmap
 * @bitmap: an XCB drawable (a Pixmap with depth 1)
 * @width: the current width of @bitmap
 * @height: the current height of @bitmap
 *
 * Creates an XCB surface that draws to the given bitmap.
 * This will be drawn to as a %CAIRO_FORMAT_A1 object.
 *
 * Return value: a pointer to the newly created surface. The caller
 * owns the surface and should call cairo_surface_destroy() when done
 * with it.
 *
 * This function always returns a valid pointer, but it will return a
 * pointer to a "nil" surface if an error such as out of memory
 * occurs. You can use cairo_surface_status() to check for this.
 **/
cairo_surface_t *
cairo_xcb_surface_create_for_bitmap (xcb_connection_t	*connection,
				     xcb_screen_t	*screen,
				     xcb_pixmap_t	 bitmap,
				     int		 width,
				     int		 height)
{
    cairo_xcb_screen_t *cairo_xcb_screen;

    if (xcb_connection_has_error (connection))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR));

    if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
    if (unlikely (width <= 0 || height <= 0))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));

    cairo_xcb_screen = _cairo_xcb_screen_get (connection, screen);
    if (unlikely (cairo_xcb_screen == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    return _cairo_xcb_surface_create_internal (cairo_xcb_screen, bitmap, FALSE,
					       PIXMAN_a1,
					       cairo_xcb_screen->connection->standard_formats[CAIRO_FORMAT_A1],
					       width, height);
}
Ejemplo n.º 6
0
static cairo_surface_t *
radeon_surface_map_to_image (radeon_surface_t *surface)
{
    if (surface->base.fallback == NULL) {
	cairo_surface_t *image;
	cairo_status_t status;
	void *ptr;

	if (surface->base.base.backend->flush != NULL) {
	    status = surface->base.base.backend->flush (surface);
	    if (unlikely (status))
		return _cairo_surface_create_in_error (status);
	}

	ptr = radeon_bo_map (to_radeon_device (surface->base.base.device),
			    to_radeon_bo (surface->base.bo));
	if (unlikely (ptr == NULL))
	    return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);

	image = cairo_image_surface_create_for_data (ptr,
						     surface->base.format,
						     surface->base.width,
						     surface->base.height,
						     surface->base.stride);
	if (unlikely (image->status)) {
	    radeon_bo_unmap (to_radeon_bo (surface->base.bo));
	    return image;
	}

	surface->base.fallback = image;
    }

    return surface->base.fallback;
}
Ejemplo n.º 7
0
/**
 * cairo_gl_surface_create_for_texture:
 * @content: type of content in the surface
 * @tex: name of texture to use for storage of surface pixels
 * @width: width of the surface, in pixels
 * @height: height of the surface, in pixels
 *
 * Creates a GL surface for the specified texture with the specified
 * content and dimensions.  The texture must be kept around until the
 * #cairo_surface_t is destroyed or cairo_surface_finish() is called
 * on the surface.  The initial contents of @tex will be used as the
 * initial image contents; you must explicitly clear the buffer,
 * using, for example, cairo_rectangle() and cairo_fill() if you want
 * it cleared.  The format of @tex should be compatible with @content,
 * in the sense that it must have the color components required by
 * @content.
 *
 * Return value: a pointer to the newly created surface. The caller
 * owns the surface and should call cairo_surface_destroy() when done
 * with it.
 *
 * This function always returns a valid pointer, but it will return a
 * pointer to a "nil" surface if an error such as out of memory
 * occurs. You can use cairo_surface_status() to check for this.
 **/
cairo_surface_t *
cairo_gl_surface_create_for_texture (cairo_device_t	*abstract_device,
				     cairo_content_t	 content,
				     unsigned int	 tex,
				     int		 width,
				     int		 height)
{
    cairo_gl_context_t *ctx;
    cairo_gl_surface_t *surface;
    cairo_status_t status;

    if (! CAIRO_CONTENT_VALID (content))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));

    if (abstract_device == NULL)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));

    if (abstract_device->status)
	return _cairo_surface_create_in_error (abstract_device->status);

    if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH));

    status = _cairo_gl_context_acquire (abstract_device, &ctx);
    if (unlikely (status))
	return _cairo_surface_create_in_error (status);

    surface = (cairo_gl_surface_t *)
	_cairo_gl_surface_create_scratch_for_texture (ctx, content,
						      tex, width, height);
    status = _cairo_gl_context_release (ctx, status);

    return &surface->base;
}
Ejemplo n.º 8
0
cairo_surface_t *
_cairo_gl_pattern_to_source (cairo_surface_t *dst,
			     const cairo_pattern_t *pattern,
			     cairo_bool_t is_mask,
			     const cairo_rectangle_int_t *extents,
			     const cairo_rectangle_int_t *sample,
			     int *src_x, int *src_y)
{
    cairo_gl_source_t *source;
    cairo_int_status_t status;

    TRACE ((stderr, "%s\n", __FUNCTION__));
    if (pattern == NULL)
	return _cairo_gl_white_source ();

    source = malloc (sizeof (*source));
    if (unlikely (source == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&source->base,
			 &cairo_gl_source_backend,
			 NULL, /* device */
			 CAIRO_CONTENT_COLOR_ALPHA);

    *src_x = *src_y = 0;
    status = _cairo_gl_operand_init (&source->operand, pattern,
				     (cairo_gl_surface_t *)dst,
				     sample, extents, FALSE);
    if (unlikely (status)) {
	cairo_surface_destroy (&source->base);
	return _cairo_surface_create_in_error (status);
    }

    return &source->base;
}
Ejemplo n.º 9
0
cairo_surface_t *
_cairo_image_surface_create_with_pixman_format (unsigned char		*data,
						pixman_format_code_t	 pixman_format,
						int			 width,
						int			 height,
						int			 stride)
{
    cairo_surface_t *surface;
    pixman_image_t *pixman_image;

    if (! _cairo_image_surface_is_size_valid (width, height))
    {
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
    }

    pixman_image = pixman_image_create_bits (pixman_format, width, height,
					     (uint32_t *) data, stride);

    if (unlikely (pixman_image == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
							    pixman_format);
    if (unlikely (surface->status)) {
	pixman_image_unref (pixman_image);
	return surface;
    }

    /* we can not make any assumptions about the initial state of user data */
    surface->is_clear = data == NULL;
    return surface;
}
Ejemplo n.º 10
0
cairo_surface_t *
cairo_tee_surface_index (cairo_surface_t *abstract_surface,
			 int index)
{
    cairo_tee_surface_t *surface;

    if (unlikely (abstract_surface->status))
	return _cairo_surface_create_in_error (abstract_surface->status);

    if (abstract_surface->backend != &cairo_tee_surface_backend)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));

    surface = (cairo_tee_surface_t *) abstract_surface;
    if (index == 0) {
	return surface->master.target;
    } else {
	cairo_surface_wrapper_t *slave;

	index--;

	if (index >= _cairo_array_num_elements (&surface->slaves))
	    return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_INDEX));

	slave = _cairo_array_index (&surface->slaves, index);
	return slave->target;
    }
}
Ejemplo n.º 11
0
/**
 * cairo_surface_create_for_rectangle:
 * @target: an existing surface for which the sub-surface will point to
 * @x: the x-origin of the sub-surface from the top-left of the target surface (in device-space units)
 * @y: the y-origin of the sub-surface from the top-left of the target surface (in device-space units)
 * @width: width of the sub-surface (in device-space units)
 * @height: height of the sub-surface (in device-space units)
 *
 * Create a new surface that is a rectangle within the target surface.
 * All operations drawn to this surface are then clipped and translated
 * onto the target surface. Nothing drawn via this sub-surface outside of
 * its bounds is drawn onto the target surface, making this a useful method
 * for passing constrained child surfaces to library routines that draw
 * directly onto the parent surface, i.e. with no further backend allocations,
 * double buffering or copies.
 *
 * <note><para>The semantics of subsurfaces have not been finalized yet
 * unless the rectangle is in full device units, is contained within
 * the extents of the target surface, and the target or subsurface's
 * device transforms are not changed.</para></note>
 *
 * Return value: a pointer to the newly allocated surface. The caller
 * owns the surface and should call cairo_surface_destroy() when done
 * with it.
 *
 * This function always returns a valid pointer, but it will return a
 * pointer to a "nil" surface if @other is already in an error state
 * or any other error occurs.
 *
 * Since: 1.10
 **/
cairo_surface_t *
cairo_surface_create_for_rectangle (cairo_surface_t *target,
				    double x, double y,
				    double width, double height)
{
    cairo_surface_subsurface_t *surface;

    if (unlikely (width < 0 || height < 0))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));

    if (unlikely (target->status))
	return _cairo_surface_create_in_error (target->status);
    if (unlikely (target->finished))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));

    surface = malloc (sizeof (cairo_surface_subsurface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    x *= target->device_transform.xx;
    y *= target->device_transform.yy;

    width *= target->device_transform.xx;
    height *= target->device_transform.yy;

    x += target->device_transform.x0;
    y += target->device_transform.y0;

    _cairo_surface_init (&surface->base,
			 &_cairo_surface_subsurface_backend,
			 NULL, /* device */
			 target->content);

    /* XXX forced integer alignment */
    surface->extents.x = ceil (x);
    surface->extents.y = ceil (y);
    surface->extents.width = floor (x + width) - surface->extents.x;
    surface->extents.height = floor (y + height) - surface->extents.y;
    if ((surface->extents.width | surface->extents.height) < 0)
	surface->extents.width = surface->extents.height = 0;

    if (target->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
	/* Maintain subsurfaces as 1-depth */
	cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) target;
	surface->extents.x += sub->extents.x;
	surface->extents.y += sub->extents.y;
	target = sub->target;
    }

    surface->target = cairo_surface_reference (target);
    surface->base.type = surface->target->type;

    surface->snapshot = NULL;

    cairo_surface_set_device_scale (&surface->base,
                                    target->device_transform.xx,
                                    target->device_transform.yy);

    return &surface->base;
}
Ejemplo n.º 12
0
static cairo_surface_t *
intel_surface_create (cairo_drm_device_t *device,
		      cairo_format_t format,
		      int width, int height)
{
    intel_surface_t *surface;
    cairo_status_t status;

    surface = malloc (sizeof (intel_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    intel_surface_init (surface, &intel_surface_backend, device,
			format, width, height);

    if (width && height) {
	/* Vol I, p134: size restrictions for textures */
	width  = (width  + 3) & -4;
	height = (height + 1) & -2;
	surface->drm.stride =
	    cairo_format_stride_for_width (surface->drm.format, width);
	surface->drm.bo = &intel_bo_create (to_intel_device (&device->base),
					    surface->drm.stride * height,
					    surface->drm.stride * height,
					    TRUE, I915_TILING_NONE, surface->drm.stride)->base;
	if (surface->drm.bo == NULL) {
	    status = _cairo_drm_surface_finish (&surface->drm);
	    free (surface);
	    return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
	}
    }

    return &surface->drm.base;
}
Ejemplo n.º 13
0
cairo_surface_t *
intel_surface_map_to_image (void *abstract_surface)
{
    intel_surface_t *surface = abstract_surface;

    if (surface->drm.fallback == NULL) {
	cairo_surface_t *image;
	cairo_status_t status;
	void *ptr;

	if (surface->drm.base.backend->flush != NULL) {
	    status = surface->drm.base.backend->flush (surface);
	    if (unlikely (status))
		return _cairo_surface_create_in_error (status);
	}

	ptr = intel_bo_map (to_intel_device (surface->drm.base.device),
			    to_intel_bo (surface->drm.bo));
	if (unlikely (ptr == NULL))
	    return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);

	image = cairo_image_surface_create_for_data (ptr,
						     surface->drm.format,
						     surface->drm.width,
						     surface->drm.height,
						     surface->drm.stride);
	if (unlikely (image->status))
	    return image;

	surface->drm.fallback = image;
    }

    return surface->drm.fallback;
}
Ejemplo n.º 14
0
cairo_surface_t *
cairo_tee_surface_create (cairo_surface_t *master)
{
    cairo_tee_surface_t *surface;

    if (unlikely (master->status))
	return _cairo_surface_create_in_error (master->status);

    surface = malloc (sizeof (cairo_tee_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&surface->base,
			 &cairo_tee_surface_backend,
			 master->content);

    _cairo_surface_wrapper_init (&surface->master, master);
    /* we trust that these are already set and remain constant */
    surface->base.device_transform = master->device_transform;
    surface->base.device_transform_inverse = master->device_transform_inverse;

    _cairo_array_init (&surface->slaves, sizeof (cairo_surface_wrapper_t));

    return &surface->base;
}
Ejemplo n.º 15
0
cairo_surface_t *
_cairo_surface_create_for_rectangle_int (cairo_surface_t *target,
					 const cairo_rectangle_int_t *extents)
{
    cairo_surface_subsurface_t *surface;

    if (unlikely (target->status))
	return _cairo_surface_create_in_error (target->status);
    if (unlikely (target->finished))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));

    assert (target->backend->type != CAIRO_SURFACE_TYPE_SUBSURFACE);

    surface = malloc (sizeof (cairo_surface_subsurface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    assert (_cairo_matrix_is_translation (&target->device_transform));

    _cairo_surface_init (&surface->base,
			 &_cairo_surface_subsurface_backend,
			 NULL, /* device */
			 target->content);

    surface->extents = *extents;
    surface->extents.x += target->device_transform.x0;
    surface->extents.y += target->device_transform.y0;

    surface->target = cairo_surface_reference (target);
    surface->base.type = surface->target->type;

    surface->snapshot = NULL;

    return &surface->base;
}
/**
 * cairo_win32_surface_create_with_ddb:
 * @hdc: a DC compatible with the surface to create
 * @format: format of pixels in the surface to create
 * @width: width of the surface, in pixels
 * @height: height of the surface, in pixels
 *
 * Creates a device-dependent-bitmap surface not associated with
 * any particular existing surface or device context. The created
 * bitmap will be uninitialized.
 *
 * Return value: the newly created surface
 *
 * Since: 1.4
 **/
cairo_surface_t *
cairo_win32_surface_create_with_ddb (HDC hdc,
				     cairo_format_t format,
				     int width,
				     int height)
{
    cairo_win32_display_surface_t *new_surf;
    HBITMAP ddb;
    HDC screen_dc, ddb_dc;
    HBITMAP saved_dc_bitmap;

    if (format != CAIRO_FORMAT_RGB24)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
/* XXX handle these eventually
	format != CAIRO_FORMAT_A8 ||
	format != CAIRO_FORMAT_A1)
*/

    if (!hdc) {
	screen_dc = GetDC (NULL);
	hdc = screen_dc;
    } else {
	screen_dc = NULL;
    }

    ddb_dc = CreateCompatibleDC (hdc);
    if (ddb_dc == NULL) {
	new_surf = (cairo_win32_display_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
	goto FINISH;
    }

    ddb = CreateCompatibleBitmap (hdc, width, height);
    if (ddb == NULL) {
	DeleteDC (ddb_dc);

	/* Note that if an app actually does hit this out of memory
	 * condition, it's going to have lots of other issues, as
	 * video memory is probably exhausted.  However, it can often
	 * continue using DIBs instead of DDBs.
	 */
	new_surf = (cairo_win32_display_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
	goto FINISH;
    }

    saved_dc_bitmap = SelectObject (ddb_dc, ddb);

    new_surf = (cairo_win32_display_surface_t*) cairo_win32_surface_create (ddb_dc);
    new_surf->bitmap = ddb;
    new_surf->saved_dc_bitmap = saved_dc_bitmap;
    new_surf->is_dib = FALSE;

FINISH:
    if (screen_dc)
	ReleaseDC (NULL, screen_dc);

    return &new_surf->win32.base;
}
Ejemplo n.º 17
0
/**
 * cairo_xcb_surface_create_with_xrender_format:
 * @connection: an XCB connection
 * @drawable: an XCB drawable
 * @screen: the XCB screen associated with @drawable
 * @format: the picture format to use for drawing to @drawable. The
 *          depth of @format mush match the depth of the drawable.
 * @width: the current width of @drawable
 * @height: the current height of @drawable
 *
 * Creates an XCB surface that draws to the given drawable.
 * The way that colors are represented in the drawable is specified
 * by the provided picture format.
 *
 * Note: If @drawable is a Window, then the function
 * cairo_xcb_surface_set_size() must be called whenever the size of the
 * window changes.
 *
 * When @drawable is a Window containing child windows then drawing to
 * the created surface will be clipped by those child windows.  When
 * the created surface is used as a source, the contents of the
 * children will be included.
 *
 * Return value: a pointer to the newly created surface. The caller
 * owns the surface and should call cairo_surface_destroy() when done
 * with it.
 *
 * This function always returns a valid pointer, but it will return a
 * pointer to a "nil" surface if an error such as out of memory
 * occurs. You can use cairo_surface_status() to check for this.
 **/
cairo_surface_t *
cairo_xcb_surface_create_with_xrender_format (xcb_connection_t	    *connection,
					      xcb_screen_t	    *screen,
					      xcb_drawable_t	     drawable,
					      xcb_render_pictforminfo_t *format,
					      int		     width,
					      int		     height)
{
    cairo_xcb_screen_t *cairo_xcb_screen;
    cairo_format_masks_t image_masks;
    pixman_format_code_t pixman_format;

    if (xcb_connection_has_error (connection))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR));

    if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
    if (unlikely (width <= 0 || height <= 0))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));

    image_masks.alpha_mask =
	(unsigned long) format->direct.alpha_mask << format->direct.alpha_shift;
    image_masks.red_mask =
	(unsigned long) format->direct.red_mask << format->direct.red_shift;
    image_masks.green_mask =
	(unsigned long) format->direct.green_mask << format->direct.green_shift;
    image_masks.blue_mask =
	(unsigned long) format->direct.blue_mask << format->direct.blue_shift;
#if 0
    image_masks.bpp = format->depth;
#else
    if (format->depth > 16)
	image_masks.bpp = 32;
    else if (format->depth > 8)
	image_masks.bpp = 16;
    else if (format->depth > 1)
	image_masks.bpp = 8;
    else
	image_masks.bpp = 1;
#endif

    if (! _pixman_format_from_masks (&image_masks, &pixman_format))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));

    cairo_xcb_screen = _cairo_xcb_screen_get (connection, screen);
    if (unlikely (cairo_xcb_screen == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    return _cairo_xcb_surface_create_internal (cairo_xcb_screen,
					       drawable,
					       FALSE,
					       pixman_format,
					       format->id,
					       width, height);
}
Ejemplo n.º 18
0
/**
 * _cairo_surface_snapshot:
 * @surface: a #cairo_surface_t
 *
 * Make an immutable reference to @surface. It is an error to call a
 * surface-modifying function on the result of this function. The
 * resulting 'snapshot' is a lazily copied-on-write surface i.e. it
 * remains a reference to the original surface until that surface is
 * written to again, at which time a copy is made of the original surface
 * and the snapshot then points to that instead. Multiple snapshots of the
 * same unmodified surface point to the same copy.
 *
 * The caller owns the return value and should call
 * cairo_surface_destroy() when finished with it. This function will not
 * return %NULL, but will return a nil surface instead.
 *
 * Return value: The snapshot surface. Note that the return surface
 * may not necessarily be of the same type as @surface.
 **/
cairo_surface_t *
_cairo_surface_snapshot (cairo_surface_t *surface)
{
    cairo_surface_snapshot_t *snapshot;
    cairo_status_t status;

    TRACE ((stderr, "%s: target=%d\n", __FUNCTION__, surface->unique_id));

    if (unlikely (surface->status))
	return _cairo_surface_create_in_error (surface->status);

    if (unlikely (surface->finished))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));

    if (surface->snapshot_of != NULL)
	return cairo_surface_reference (surface);

    if (_cairo_surface_is_snapshot (surface))
	return cairo_surface_reference (surface);

    snapshot = (cairo_surface_snapshot_t *)
	_cairo_surface_has_snapshot (surface, &_cairo_surface_snapshot_backend);
    if (snapshot != NULL)
	return cairo_surface_reference (&snapshot->base);

    snapshot = malloc (sizeof (cairo_surface_snapshot_t));
    if (unlikely (snapshot == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));

    _cairo_surface_init (&snapshot->base,
			 &_cairo_surface_snapshot_backend,
			 NULL, /* device */
			 surface->content);
    snapshot->base.type = surface->type;

    CAIRO_MUTEX_INIT (snapshot->mutex);
    snapshot->target = surface;
    snapshot->clone = NULL;

    status = _cairo_surface_copy_mime_data (&snapshot->base, surface);
    if (unlikely (status)) {
	cairo_surface_destroy (&snapshot->base);
	return _cairo_surface_create_in_error (status);
    }

    snapshot->base.device_transform = surface->device_transform;
    snapshot->base.device_transform_inverse = surface->device_transform_inverse;

    _cairo_surface_attach_snapshot (surface,
				    &snapshot->base,
				    _cairo_surface_snapshot_copy_on_write);

    return &snapshot->base;
}
Ejemplo n.º 19
0
cairo_surface_t *
cairo_xcb_surface_create (xcb_connection_t  *xcb_connection,
			  xcb_drawable_t     drawable,
			  xcb_visualtype_t  *visual,
			  int		     width,
			  int		     height)
{
    cairo_xcb_screen_t *screen;
    xcb_screen_t *xcb_screen;
    cairo_format_masks_t image_masks;
    pixman_format_code_t pixman_format;
    xcb_render_pictformat_t xrender_format;
    int depth;

    if (xcb_connection_has_error (xcb_connection))
	return _cairo_surface_create_in_error (CAIRO_STATUS_WRITE_ERROR);

    if (unlikely (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX))
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);

    xcb_screen = _cairo_xcb_screen_from_visual (xcb_connection, visual, &depth);
    if (unlikely (xcb_screen == NULL))
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_VISUAL);

    image_masks.alpha_mask = 0;
    image_masks.red_mask   = visual->red_mask;
    image_masks.green_mask = visual->green_mask;
    image_masks.blue_mask  = visual->blue_mask;
    if (depth > 16)
	image_masks.bpp = 32;
    else if (depth > 8)
	image_masks.bpp = 16;
    else if (depth > 1)
	image_masks.bpp = 8;
    else
	image_masks.bpp = 1;

    if (! _pixman_format_from_masks (&image_masks, &pixman_format))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));

    screen = _cairo_xcb_screen_get (xcb_connection, xcb_screen);
    if (unlikely (screen == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    xrender_format =
	_cairo_xcb_connection_get_xrender_format_for_visual (screen->connection,
							     visual->visual_id);

    return _cairo_xcb_surface_create_internal (screen, drawable, FALSE,
					       pixman_format,
					       xrender_format,
					       width, height);
}
Ejemplo n.º 20
0
cairo_surface_t *
_cairo_analysis_surface_create (cairo_surface_t		*target,
				int			 width,
				int			 height)
{
    cairo_analysis_surface_t *surface;
    cairo_status_t status;

    status = target->status;
    if (unlikely (status))
	return _cairo_surface_create_in_error (status);

    surface = malloc (sizeof (cairo_analysis_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    /* I believe the content type here is truly arbitrary. I'm quite
     * sure nothing will ever use this value. */
    _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend,
			 CAIRO_CONTENT_COLOR_ALPHA);

    surface->width = width;
    surface->height = height;
    cairo_matrix_init_identity (&surface->ctm);
    surface->has_ctm = FALSE;

    surface->target = cairo_surface_reference (target);
    surface->first_op  = TRUE;
    surface->has_supported = FALSE;
    surface->has_unsupported = FALSE;

    surface->page_bbox.p1.x = 0;
    surface->page_bbox.p1.y = 0;
    surface->page_bbox.p2.x = 0;
    surface->page_bbox.p2.y = 0;

    _cairo_region_init (&surface->supported_region);
    _cairo_region_init (&surface->fallback_region);

    if (width == -1 && height == -1) {
	surface->current_clip.x      = CAIRO_RECT_INT_MIN;
	surface->current_clip.y      = CAIRO_RECT_INT_MIN;
	surface->current_clip.width  = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
	surface->current_clip.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
    } else {
	surface->current_clip.x = 0;
	surface->current_clip.y = 0;
	surface->current_clip.width = width;
	surface->current_clip.height = height;
    }

    return &surface->base;
}
Ejemplo n.º 21
0
cairo_surface_t *
cairo_xml_surface_create (cairo_device_t *device,
			  cairo_content_t content,
			  double width, double height)
{
    if (unlikely (device->backend->type != CAIRO_DEVICE_TYPE_XML))
	return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);

    if (unlikely (device->status))
	return _cairo_surface_create_in_error (device->status);

    return _cairo_xml_surface_create_internal (device, content, width, height);
}
/**
 * cairo_symbian_surface_create:
 * @window: an RWindow
 *
 * Creates a Symbian surface that draws to the given window.
 *
 * Note:
 * The function cairo_symbian_surface_set_size() must be called whenever the size of the
 * window changes.
 *
 * Return value: the newly created surface
 **/
cairo_surface_t *
cairo_symbian_surface_create (symbian_window_t window) {
 
	if (window == NULL)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
    
    XCairoSymbianSurface *surface = NULL;
    surface = XCairoSymbianSurface::Create(window);
    if (surface == NULL)
    return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    
    return (cairo_surface_t *)surface;
}
Ejemplo n.º 23
0
static cairo_gl_surface_t *
tristrip_to_surface (void *_dst,
		  const cairo_rectangle_int_t *extents,
		  cairo_antialias_t	antialias,
		  cairo_tristrip_t	*strip)
{
    pixman_format_code_t pixman_format;
    pixman_image_t *pixman_image;
    cairo_surface_t *image, *mask;
    cairo_status_t status;

    pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1,
    pixman_image = pixman_image_create_bits (pixman_format,
					     extents->width,
					     extents->height,
					     NULL, 0);
    if (unlikely (pixman_image == NULL))
	return (cairo_gl_surface_t *)_cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _pixman_image_add_tristrip (pixman_image, extents->x, extents->y, strip);
    image = _cairo_image_surface_create_for_pixman_image (pixman_image,
							  pixman_format);
    if (unlikely (image->status)) {
	pixman_image_unref (pixman_image);
	return (cairo_gl_surface_t *)image;
    }

    mask = _cairo_surface_create_scratch (_dst,
					  CAIRO_CONTENT_COLOR_ALPHA,
					  extents->width,
					  extents->height,
					  NULL);
    if (unlikely (mask->status)) {
	cairo_surface_destroy (image);
	return (cairo_gl_surface_t *)mask;
    }

    status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *)mask,
					   (cairo_image_surface_t *)image,
					   0, 0,
					   extents->width, extents->height,
					   0, 0,
					   TRUE);
    cairo_surface_destroy (image);
    if (unlikely (status)) {
	cairo_surface_destroy (mask);
	return (cairo_gl_surface_t*)_cairo_surface_create_in_error (status);
    }

    return (cairo_gl_surface_t*)mask;
}
Ejemplo n.º 24
0
cairo_surface_t *
cairo_qt_surface_create_with_qpixmap (cairo_content_t content,
				      int width,
				      int height)
{
    cairo_qt_surface_t *qs;

    if ((content & CAIRO_CONTENT_COLOR) == 0)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));

    qs = (cairo_qt_surface_t *) malloc (sizeof(cairo_qt_surface_t));
    if (qs == NULL)
        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    memset (qs, 0, sizeof(cairo_qt_surface_t));

    QPixmap *pixmap = new QPixmap (width, height);
    if (pixmap == NULL) {
	free (qs);
        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }

    // By default, a QPixmap is opaque; however, if it's filled
    // with a color with a transparency component, it is converted
    // to a format that preserves transparency.
    if (content == CAIRO_CONTENT_COLOR_ALPHA)
	pixmap->fill(Qt::transparent);

    _cairo_surface_init (&qs->base,
			 &cairo_qt_surface_backend,
			 NULL, /* device */
			 content);

    _cairo_surface_clipper_init (&qs->clipper,
				 _cairo_qt_surface_clipper_intersect_clip_path);

    qs->pixmap = pixmap;

    if (!pixmap->isNull()) {
        qs->p = new QPainter(pixmap);
        qs->supports_porter_duff = qs->p->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
    }

    qs->window = QRect(0, 0, width, height);

    D(fprintf(stderr, "qpainter_surface_create: qpixmap: [%d %d %d %d] pd:%d\n",
              qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(),
              qs->supports_porter_duff));

    return &qs->base;
}
Ejemplo n.º 25
0
cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface)
{
    cairo_surface_t *snapshot;
    cairo_status_t status;
    cairo_pattern_union_t pattern;
    cairo_image_surface_t *image;
    void *image_extra;

    status = _cairo_surface_acquire_source_image (surface,
						  &image, &image_extra);
    if (status)
	return _cairo_surface_create_in_error (status);

    snapshot = cairo_image_surface_create (image->format,
					   image->width,
					   image->height);
    if (cairo_surface_status (snapshot)) {
	_cairo_surface_release_source_image (surface,
					     image, image_extra);
	return snapshot;
    }

    _cairo_pattern_init_for_surface (&pattern.surface, &image->base);

    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
			               &pattern.base,
				       NULL,
				       snapshot,
				       0, 0,
				       0, 0,
				       0, 0,
				       image->width,
				       image->height);

    _cairo_pattern_fini (&pattern.base);
    _cairo_surface_release_source_image (surface,
					 image, image_extra);

    if (status) {
	cairo_surface_destroy (snapshot);
	return _cairo_surface_create_in_error (status);
    }

    snapshot->device_transform = surface->device_transform;
    snapshot->device_transform_inverse = surface->device_transform_inverse;

    snapshot->is_snapshot = TRUE;

    return snapshot;
}
Ejemplo n.º 26
0
cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface)
{
    cairo_surface_t *snapshot;
    cairo_status_t status;
    cairo_format_t format;
    cairo_surface_pattern_t pattern;
    cairo_image_surface_t *image;
    void *image_extra;

    status = _cairo_surface_acquire_source_image (surface,
						  &image, &image_extra);
    if (unlikely (status))
	return _cairo_surface_create_in_error (status);

    format = image->format;
    if (format == CAIRO_FORMAT_INVALID) {
	/* Non-standard images formats can be generated when retrieving
	 * images from unusual xservers, for example.
	 */
	format = _cairo_format_from_content (image->base.content);
    }
    snapshot = cairo_image_surface_create (format,
					   image->width,
					   image->height);
    if (cairo_surface_status (snapshot)) {
	_cairo_surface_release_source_image (surface, image, image_extra);
	return snapshot;
    }

    _cairo_pattern_init_for_surface (&pattern, &image->base);
    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
			               &pattern.base,
				       NULL,
				       snapshot,
				       0, 0,
				       0, 0,
				       0, 0,
				       image->width,
				       image->height);
    _cairo_pattern_fini (&pattern.base);
    _cairo_surface_release_source_image (surface, image, image_extra);
    if (unlikely (status)) {
	cairo_surface_destroy (snapshot);
	return _cairo_surface_create_in_error (status);
    }

    return snapshot;
}
Ejemplo n.º 27
0
static cairo_surface_t *
_cairo_xcb_surface_create_shm_image (cairo_xcb_connection_t *connection,
				     pixman_format_code_t pixman_format,
				     int width, int height,
				     cairo_bool_t might_reuse,
				     cairo_xcb_shm_info_t **shm_info_out)
{
    cairo_surface_t *image;
    cairo_xcb_shm_info_t *shm_info;
    cairo_int_status_t status;
    size_t stride;

    *shm_info_out = NULL;

    stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width,
					 PIXMAN_FORMAT_BPP (pixman_format));
    status = _cairo_xcb_connection_allocate_shm_info (connection,
						      stride * height,
						      might_reuse,
						      &shm_info);
    if (unlikely (status)) {
	if (status == CAIRO_INT_STATUS_UNSUPPORTED)
	    return NULL;

	return _cairo_surface_create_in_error (status);
    }

    image = _cairo_image_surface_create_with_pixman_format (shm_info->mem,
							    pixman_format,
							    width, height,
							    stride);
    if (unlikely (image->status)) {
	_cairo_xcb_shm_info_destroy (shm_info);
	return image;
    }

    status = _cairo_user_data_array_set_data (&image->user_data,
					      (const cairo_user_data_key_t *) connection,
					      shm_info,
					      (cairo_destroy_func_t) _cairo_xcb_shm_info_destroy);
    if (unlikely (status)) {
	cairo_surface_destroy (image);
	_cairo_xcb_shm_info_destroy (shm_info);
	return _cairo_surface_create_in_error (status);
    }

    *shm_info_out = shm_info;
    return image;
}
/**
 * cairo_recording_surface_create:
 * @content: the content of the recording surface
 * @extents: the extents to record in pixels, can be %NULL to record
 *           unbounded operations.
 *
 * Creates a recording-surface which can be used to record all drawing operations
 * at the highest level (that is, the level of paint, mask, stroke, fill
 * and show_text_glyphs). The recording surface can then be "replayed" against
 * any target surface by using it as a source to drawing operations.
 *
 * The recording phase of the recording surface is careful to snapshot all
 * necessary objects (paths, patterns, etc.), in order to achieve
 * accurate replay.
 *
 * Return value: a pointer to the newly created surface. The caller
 * owns the surface and should call cairo_surface_destroy() when done
 * with it.
 *
 * Since: 1.10
 **/
cairo_surface_t *
cairo_recording_surface_create (cairo_content_t		 content,
				const cairo_rectangle_t	*extents)
{
    cairo_recording_surface_t *recording_surface;
    cairo_status_t status;

    recording_surface = malloc (sizeof (cairo_recording_surface_t));
    if (unlikely (recording_surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&recording_surface->base,
			 &cairo_recording_surface_backend,
			 NULL, /* device */
			 content);

    recording_surface->content = content;

    recording_surface->unbounded = TRUE;
    _cairo_clip_init (&recording_surface->clip);

    /* unbounded -> 'infinite' extents */
    if (extents != NULL) {
	recording_surface->extents_pixels = *extents;

	/* XXX check for overflow */
	recording_surface->extents.x = floor (extents->x);
	recording_surface->extents.y = floor (extents->y);
	recording_surface->extents.width = ceil (extents->x + extents->width) - recording_surface->extents.x;
	recording_surface->extents.height = ceil (extents->y + extents->height) - recording_surface->extents.y;

	status = _cairo_clip_rectangle (&recording_surface->clip,
					&recording_surface->extents);
	if (unlikely (status)) {
	    free (recording_surface);
	    return _cairo_surface_create_in_error (status);
	}

	recording_surface->unbounded = FALSE;
    }

    _cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));

    recording_surface->replay_start_idx = 0;
    recording_surface->base.is_clear = TRUE;

    return &recording_surface->base;
}
Ejemplo n.º 29
0
/* A convenience function for when one needs to coerce an image
 * surface to an alternate format. */
cairo_image_surface_t *
_cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface,
			               cairo_format_t	      format)
{
    cairo_image_surface_t *clone;
    cairo_status_t status;

    status = surface->base.status;
    if (unlikely (status))
	return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);

    if (surface->format == format)
	return (cairo_image_surface_t *)cairo_surface_reference(&surface->base);

    clone = (cairo_image_surface_t *)
	cairo_image_surface_create (format, surface->width, surface->height);
    if (unlikely (clone->base.status))
	return clone;

    pixman_image_composite32 (PIXMAN_OP_SRC,
                              surface->pixman_image, NULL, clone->pixman_image,
                              0, 0,
                              0, 0,
                              0, 0,
                              surface->width, surface->height);
    clone->base.is_clear = FALSE;

    clone->base.device_transform =
	surface->base.device_transform;
    clone->base.device_transform_inverse =
	surface->base.device_transform_inverse;

    return clone;
}
Ejemplo n.º 30
0
static cairo_surface_t *
_cairo_xcb_surface_fallback (cairo_xcb_surface_t *surface,
			     cairo_composite_rectangles_t *composite)
{
    cairo_image_surface_t *image;
    cairo_status_t status;

    status = _cairo_composite_rectangles_add_to_damage (composite,
							&surface->fallback_damage);
    if (unlikely (status))
	    return _cairo_surface_create_in_error (status);

    if (surface->fallback)
	return &surface->fallback->base;

    image = (cairo_image_surface_t *)
	    _get_image (surface, TRUE, 0, 0, surface->width, surface->height);

    /* If there was a deferred clear, _get_image applied it */
    if (image->base.status == CAIRO_STATUS_SUCCESS) {
	surface->deferred_clear = FALSE;

	surface->fallback = image;
    }

    return &surface->fallback->base;
}