/**
 * cairo_image_surface_create_for_data:
 * @data: a pointer to a buffer supplied by the application
 *    in which to write contents.
 * @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. Having this be specified separate from @width
 *   allows for padding at the end of rows, or for writing
 *   to a subportion of a larger image.
 * 
 * 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 @buffer will be used as the inital image contents; you
 * must explicitely clear the buffer, using, for example,
 * cairo_rectangle() and cairo_fill() if you want it cleared.
 *
 * 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_image_surface_create_for_data (unsigned char     *data,
				     cairo_format_t	format,
				     int		width,
				     int		height,
				     int		stride)
{
    cairo_surface_t *surface;
    pixman_format_t *pixman_format;
    pixman_image_t *pixman_image;

    if (! CAIRO_FORMAT_VALID (format))
	return (cairo_surface_t*) &_cairo_surface_nil;

    pixman_format = _create_pixman_format (format);
    if (pixman_format == NULL) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return (cairo_surface_t*) &_cairo_surface_nil;
    }
    
    pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
						 width, height,
						 _cairo_format_bpp (format),
						 stride);

    pixman_format_destroy (pixman_format);

    if (pixman_image == NULL) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return (cairo_surface_t*) &_cairo_surface_nil;
    }

    surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);

    return surface;
}
Beispiel #2
0
static cairo_status_t xfs_read_func(void * closure, unsigned char * data, unsigned int size)
{
	struct xfs_file_t * file = closure;
	size_t ret;

    while(size)
    {
    	ret = xfs_read(file, data, 1, size);
    	size -= ret;
    	data += ret;
    	if(size && xfs_eof(file))
    		return _cairo_error(CAIRO_STATUS_READ_ERROR);
    }
    return CAIRO_STATUS_SUCCESS;
}
/**
 * cairo_image_surface_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 an image surface of the specified format and
 * dimensions. Initially the surface contents are all
 * 0. (Specifically, within each pixel, each color or alpha channel
 * belonging to format will be 0. The contents of bits within a pixel,
 * but not belonging to the given format are undefined).
 *
 * 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.
 *
 * Since: 1.0
 **/
cairo_surface_t *
cairo_image_surface_create (cairo_format_t	format,
			    int			width,
			    int			height)
{
    pixman_format_code_t pixman_format;

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

    pixman_format = _cairo_format_to_pixman_format_code (format);

    return _cairo_image_surface_create_with_pixman_format (NULL, pixman_format,
							   width, height, -1);
}
Beispiel #4
0
void
cairo_tee_surface_add (cairo_surface_t *abstract_surface,
		       cairo_surface_t *target)
{
    cairo_tee_surface_t *surface;
    cairo_surface_wrapper_t slave;
    cairo_status_t status;

    if (unlikely (abstract_surface->status))
	return;
    if (unlikely (abstract_surface->finished)) {
	status = _cairo_surface_set_error (abstract_surface,
					   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
	return;
    }

    if (abstract_surface->backend != &cairo_tee_surface_backend) {
	status = _cairo_surface_set_error (abstract_surface,
					   _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
	return;
    }

    if (unlikely (target->status)) {
	status = _cairo_surface_set_error (abstract_surface, target->status);
	return;
    }

    surface = (cairo_tee_surface_t *) abstract_surface;

    _cairo_surface_wrapper_init (&slave, target);
    status = _cairo_array_append (&surface->slaves, &slave);
    if (unlikely (status)) {
	_cairo_surface_wrapper_fini (&slave);
	status = _cairo_surface_set_error (&surface->base, status);
    }
}
/**
 * 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 then 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.
 *
 * Since: 1.0
 **/
    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));

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

    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);
}
cairo_status_t
_cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path,
			       cairo_fixed_t	   dx,
			       cairo_fixed_t	   dy)
{
    cairo_fixed_t x, y;

    if (! path->has_current_point)
	return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);

    x = path->current_point.x + dx;
    y = path->current_point.y + dy;

    return _cairo_path_fixed_line_to (path, x, y);
}
static cairo_status_t
_cairo_clip_path_reapply_clip_path_translate (cairo_clip_t      *clip,
					      cairo_clip_path_t *other_path,
					      int tx, int ty)
{
    cairo_status_t status;
    cairo_clip_path_t *clip_path;

    if (other_path->prev != NULL) {
        status = _cairo_clip_path_reapply_clip_path_translate (clip,
							       other_path->prev,
							       tx, ty);
	if (unlikely (status))
	    return status;
    }

    clip_path = _cairo_clip_path_create (clip);
    if (unlikely (clip_path == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

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

    _cairo_path_fixed_translate (&clip_path->path,
				 _cairo_fixed_from_int (tx),
				 _cairo_fixed_from_int (ty));

    clip_path->fill_rule = other_path->fill_rule;
    clip_path->tolerance = other_path->tolerance;
    clip_path->antialias = other_path->antialias;

    clip_path->flags = other_path->flags;
    if (other_path->region != NULL) {
	clip_path->region = cairo_region_copy (other_path->region);
	cairo_region_translate (clip_path->region, tx, ty);
    }
    clip_path->surface = cairo_surface_reference (other_path->surface);

    clip_path->extents = other_path->extents;
    clip_path->extents.x += tx;
    clip_path->extents.y += ty;

    return CAIRO_STATUS_SUCCESS;
}
/**
 * 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;
}
Beispiel #9
0
cairo_surface_t *
_cairo_xcb_surface_create_internal (cairo_xcb_screen_t		*screen,
				    xcb_drawable_t		 drawable,
				    cairo_bool_t		 owns_pixmap,
				    pixman_format_code_t	 pixman_format,
				    xcb_render_pictformat_t	 xrender_format,
				    int				 width,
				    int				 height)
{
    cairo_xcb_surface_t *surface;

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

    _cairo_surface_init (&surface->base,
			 &_cairo_xcb_surface_backend,
			 &screen->connection->device,
			 _cairo_content_from_pixman_format (pixman_format));

    surface->connection = _cairo_xcb_connection_reference (screen->connection);
    surface->screen = screen;
    cairo_list_add (&surface->link, &screen->surfaces);

    surface->drawable = drawable;
    surface->owns_pixmap = owns_pixmap;

    surface->deferred_clear = FALSE;
    surface->deferred_clear_color = *CAIRO_COLOR_TRANSPARENT;

    surface->width  = width;
    surface->height = height;
    surface->depth  = PIXMAN_FORMAT_DEPTH (pixman_format);

    surface->picture = XCB_NONE;
    if (screen->connection->force_precision != -1)
	surface->precision = screen->connection->force_precision;
    else
	surface->precision = XCB_RENDER_POLY_MODE_IMPRECISE;

    surface->pixman_format = pixman_format;
    surface->xrender_format = xrender_format;

    surface->fallback = NULL;
    _cairo_boxes_init (&surface->fallback_damage);

    return &surface->base;
}
cairo_surface_t *
_cairo_analysis_surface_create (cairo_surface_t		*target,
				int			 width,
				int			 height)
{
    cairo_analysis_surface_t *surface;

    surface = malloc (sizeof (cairo_analysis_surface_t));
    if (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;
}
cairo_surface_t *
cairo_skia_surface_create (cairo_format_t format,
			   int width,
			   int height)
{
    SkBitmap::Config config;
    bool opaque;

    if (! CAIRO_FORMAT_VALID (format) ||
	! format_to_sk_config (format, config, opaque))
    {
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
    }

    return &_cairo_skia_surface_create_internal (config, opaque, NULL, width, height, 0)->image.base;
}
static cairo_status_t
_cairo_image_surface_set_matrix (cairo_image_surface_t	*surface,
                                 const cairo_matrix_t	*matrix)
{
    pixman_transform_t pixman_transform;

    //+EAWebKitChange - Added a ref point (width/2, height/2) for shadow box bug fix.
    //6/26/2013
    _cairo_matrix_to_pixman_matrix (matrix, &pixman_transform, surface->width/2., surface->height/2.);
    //-EAWebKitChange

    if (! pixman_image_set_transform (surface->pixman_image, &pixman_transform))
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_meta_surface_fill (void			*abstract_surface,
			  cairo_operator_t	 op,
			  cairo_pattern_t	*source,
			  cairo_path_fixed_t	*path,
			  cairo_fill_rule_t	 fill_rule,
			  double		 tolerance,
			  cairo_antialias_t	 antialias)
{
    cairo_status_t status;
    cairo_meta_surface_t *meta = abstract_surface;
    cairo_command_fill_t *command;

    command = malloc (sizeof (cairo_command_fill_t));
    if (command == NULL)
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    command->header.type = CAIRO_COMMAND_FILL;
    command->header.region = CAIRO_META_REGION_ALL;
    command->op = op;

    status = _cairo_pattern_init_snapshot (&command->source.base, source);
    if (status)
	goto CLEANUP_COMMAND;

    status = _cairo_path_fixed_init_copy (&command->path, path);
    if (status)
	goto CLEANUP_SOURCE;

    command->fill_rule = fill_rule;
    command->tolerance = tolerance;
    command->antialias = antialias;

    status = _cairo_array_append (&meta->commands, &command);
    if (status)
	goto CLEANUP_PATH;

    return CAIRO_STATUS_SUCCESS;

  CLEANUP_PATH:
    _cairo_path_fixed_fini (&command->path);
  CLEANUP_SOURCE:
    _cairo_pattern_fini (&command->source.base);
  CLEANUP_COMMAND:
    free (command);
    return status;
}
Beispiel #14
0
static cairo_status_t
cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
				  cairo_format_t format,
                                  cairo_gl_glyph_cache_t **cache_out)
{
    cairo_gl_glyph_cache_t *cache;
    cairo_content_t content;

    switch (format) {
    case CAIRO_FORMAT_RGB30:
    case CAIRO_FORMAT_RGB16_565:
    case CAIRO_FORMAT_ARGB32:
    case CAIRO_FORMAT_RGB24:
	cache = &ctx->glyph_cache[0];
        content = CAIRO_CONTENT_COLOR_ALPHA;
	break;
    case CAIRO_FORMAT_A8:
    case CAIRO_FORMAT_A1:
	cache = &ctx->glyph_cache[1];
        content = CAIRO_CONTENT_ALPHA;
	break;
    default:
    case CAIRO_FORMAT_INVALID:
	ASSERT_NOT_REACHED;
	return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
    }

    if (unlikely (cache->surface == NULL)) {
	cairo_surface_t *surface;

	surface = _cairo_gl_surface_create_scratch_for_caching (ctx,
							        content,
							        GLYPH_CACHE_WIDTH,
							        GLYPH_CACHE_HEIGHT);
	if (unlikely (surface->status))
	    return surface->status;

	_cairo_surface_release_device_reference (surface);

	cache->surface = (cairo_gl_surface_t *)surface;
	cache->surface->operand.texture.attributes.has_component_alpha =
	    content == CAIRO_CONTENT_COLOR_ALPHA;
    }

    *cache_out = cache;
    return CAIRO_STATUS_SUCCESS;
}
/* Handles compositing for %CAIRO_OPERATOR_SOURCE, which is special; it's
 * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip))
 */
static cairo_status_t
clip_and_composite_source (const cairo_composite_rectangles_t	*extents,
			   draw_func_t				 draw_func,
			   void					*draw_closure)
{
    cairo_image_surface_t *dst = (cairo_image_surface_t *)extents->surface;
    cairo_image_surface_t *mask;
    pixman_image_t *src;
    int src_x, src_y;
    cairo_status_t status = CAIRO_STATUS_SUCCESS;

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

    mask = create_composite_mask (dst, draw_closure, draw_func, extents);
    if (unlikely (mask->base.status))
	return mask->base.status;

    pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE,
			      mask->pixman_image, NULL, dst->pixman_image,
			      0,      0,
			      0,      0,
			      extents->bounded.x, extents->bounded.y,
			      extents->bounded.width, extents->bounded.height);

    src = _pixman_image_for_pattern (dst,
				     &extents->source_pattern.base, FALSE,
				     &extents->bounded,
				     &extents->source_sample_area,
				     &src_x, &src_y);
    if (unlikely (src == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto error;
    }

    pixman_image_composite32 (PIXMAN_OP_ADD,
			      src, mask->pixman_image, dst->pixman_image,
			      extents->bounded.x + src_x,  extents->bounded.y + src_y,
			      0, 0,
			      extents->bounded.x, extents->bounded.y,
			      extents->bounded.width, extents->bounded.height);

    pixman_image_unref (src);

error:
    cairo_surface_destroy (&mask->base);
    return status;
}
Beispiel #16
0
cairo_status_t
_cairo_polygon_init_boxes (cairo_polygon_t *polygon,
			   const cairo_boxes_t *boxes)
{
    const struct _cairo_boxes_chunk *chunk;
    int i;

    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));

    polygon->status = CAIRO_STATUS_SUCCESS;

    polygon->num_edges = 0;

    polygon->edges = polygon->edges_embedded;
    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
    if (boxes->num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
	polygon->edges_size = 2 * boxes->num_boxes;
	polygon->edges = _cairo_malloc_ab (polygon->edges_size,
					   2*sizeof(cairo_edge_t));
	if (unlikely (polygon->edges == XNULL))
	    return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
    }

    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;

    polygon->limits = XNULL;
    polygon->num_limits = 0;

    for (chunk = &boxes->chunks; chunk != XNULL; chunk = chunk->next) {
	for (i = 0; i < chunk->count; i++) {
	    cairo_point_t p1, p2;

	    p1 = chunk->base[i].p1;
	    p2.x = p1.x;
	    p2.y = chunk->base[i].p2.y;
	    _cairo_polygon_add_edge (polygon, &p1, &p2, 1);

	    p1 = chunk->base[i].p2;
	    p2.x = p1.x;
	    p2.y = chunk->base[i].p1.y;
	    _cairo_polygon_add_edge (polygon, &p1, &p2, 1);
	}
    }

    return polygon->status;
}
static cairo_status_t
_cairo_sub_font_glyph_lookup_unicode (cairo_scaled_font_t    *scaled_font,
				      unsigned long	      scaled_font_glyph_index,
				      uint32_t     	     *unicode_out,
				      char  		    **utf8_out,
				      int          	     *utf8_len_out)
{
    uint32_t unicode;
    char buf[8];
    int len;
    cairo_status_t status;

    /* Do a reverse lookup on the glyph index. unicode is -1 if the
     * index could not be mapped to a unicode character. */
    unicode = -1;
    status = _cairo_truetype_index_to_ucs4 (scaled_font,
					    scaled_font_glyph_index,
					    &unicode);
    if (_cairo_status_is_error (status))
	return status;

    if (unicode == (uint32_t)-1 && scaled_font->backend->index_to_ucs4) {
	status = scaled_font->backend->index_to_ucs4 (scaled_font,
						      scaled_font_glyph_index,
						      &unicode);
	if (unlikely (status))
	    return status;
    }

    *unicode_out = unicode;
    *utf8_out = NULL;
    *utf8_len_out = 0;
    if (unicode != (uint32_t) -1) {
	len = _cairo_ucs4_to_utf8 (unicode, buf);
	if (len > 0) {
	    *utf8_out = malloc (len + 1);
	    if (unlikely (*utf8_out == NULL))
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);

	    memcpy (*utf8_out, buf, len);
	    (*utf8_out)[len] = 0;
	    *utf8_len_out = len;
	}
    }

    return CAIRO_STATUS_SUCCESS;
}
Beispiel #18
0
/**
 * _cairo_matrix_compute_basis_scale_factors:
 * @matrix: a matrix
 * @basis_scale: the scale factor in the direction of basis
 * @normal_scale: the scale factor in the direction normal to the basis
 * @x_basis: basis to use.  X basis if true, Y basis otherwise.
 *
 * Computes |Mv| and det(M)/|Mv| for v=[1,0] if x_basis is true, and v=[0,1]
 * otherwise, and M is @matrix.
 *
 * Return value: the scale factor of @matrix on the height of the font,
 * or 1.0 if @matrix is %NULL.
 **/
cairo_status_t
_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
					   double *basis_scale, double *normal_scale,
					   cairo_bool_t x_basis)
{
    double det;

    det = _cairo_matrix_compute_determinant (matrix);

    if (! ISFINITE (det))
	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);

    if (det == 0)
    {
	*basis_scale = *normal_scale = 0;
    }
    else
    {
	double x = x_basis != 0;
	double y = x == 0;
	double major, minor;

	cairo_matrix_transform_distance (matrix, &x, &y);
	major = hypot (x, y);
	/*
	 * ignore mirroring
	 */
	if (det < 0)
	    det = -det;
	if (major)
	    minor = det / major;
	else
	    minor = 0.0;
	if (x_basis)
	{
	    *basis_scale = major;
	    *normal_scale = minor;
	}
	else
	{
	    *basis_scale = minor;
	    *normal_scale = major;
	}
    }

    return CAIRO_STATUS_SUCCESS;
}
Beispiel #19
0
cairo_status_t
_cairo_pen_init (cairo_pen_t	*pen,
		 double		 radius,
		 double		 tolerance,
		 cairo_matrix_t	*ctm)
{
    int i;
    int reflect;

    pen->radius = radius;
    pen->tolerance = tolerance;

    reflect = _cairo_matrix_compute_determinant (ctm) < 0.;

    pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
						    radius,
						    ctm);

    if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
	pen->vertices = _cairo_malloc_ab (pen->num_vertices,
					  sizeof (cairo_pen_vertex_t));
	if (pen->vertices == NULL)
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    } else {
	pen->vertices = pen->vertices_embedded;
    }

    /*
     * Compute pen coordinates.  To generate the right ellipse, compute points around
     * a circle in user space and transform them to device space.  To get a consistent
     * orientation in device space, flip the pen if the transformation matrix
     * is reflecting
     */
    for (i=0; i < pen->num_vertices; i++) {
	double theta = 2 * M_PI * i / (double) pen->num_vertices;
	double dx = radius * cos (reflect ? -theta : theta);
	double dy = radius * sin (reflect ? -theta : theta);
	cairo_pen_vertex_t *v = &pen->vertices[i];
	cairo_matrix_transform_distance (ctm, &dx, &dy);
	v->point.x = _cairo_fixed_from_double (dx);
	v->point.y = _cairo_fixed_from_double (dy);
    }

    _cairo_pen_compute_slopes (pen);

    return CAIRO_STATUS_SUCCESS;
}
Beispiel #20
0
cairo_surface_t *
_cairo_test_null_surface_create (cairo_content_t content)
{
    cairo_surface_t *surface;

    surface = malloc (sizeof (cairo_surface_t));
    if (unlikely (surface == NULL)) {
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }

    _cairo_surface_init (surface,
			 &null_surface_backend,
			 NULL, /* device */
			 content);

    return surface;
}
/* XXX The integer width,height here should be doubles and all uses updated */
cairo_surface_t *
_cairo_paginated_surface_create (cairo_surface_t				*target,
				 cairo_content_t				 content,
				 int						 width,
				 int						 height,
				 const cairo_paginated_surface_backend_t	*backend)
{
    cairo_paginated_surface_t *surface;
    cairo_status_t status;

    surface = malloc (sizeof (cairo_paginated_surface_t));
    if (surface == NULL) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto FAIL;
    }

    _cairo_surface_init (&surface->base, &cairo_paginated_surface_backend,
			 content);

    /* Override surface->base.type with target's type so we don't leak
     * evidence of the paginated wrapper out to the user. */
    surface->base.type = cairo_surface_get_type (target);

    surface->target = cairo_surface_reference (target);

    surface->content = content;
    surface->width = width;
    surface->height = height;

    surface->backend = backend;

    surface->meta = _cairo_meta_surface_create (content, width, height);
    status = cairo_surface_status (surface->meta);
    if (status)
	goto FAIL_CLEANUP_SURFACE;

    surface->page_num = 1;
    surface->page_is_blank = TRUE;

    return &surface->base;

  FAIL_CLEANUP_SURFACE:
    free (surface);
  FAIL:
    return _cairo_surface_create_in_error (status);
}
cairo_status_t
intel_surface_acquire_source_image (void *abstract_surface,
				    cairo_image_surface_t **image_out,
				    void **image_extra)
{
    intel_surface_t *surface = abstract_surface;
    cairo_surface_t *image;
    cairo_status_t status;
    void *ptr;

    if (surface->drm.fallback != NULL) {
	image = surface->drm.fallback;
	goto DONE;
    }

    image = _cairo_surface_has_snapshot (&surface->drm.base,
	                                 &_cairo_image_surface_backend);
    if (image != NULL)
	goto DONE;

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

    ptr = intel_bo_map (to_intel_device (surface->drm.base.device),
			to_intel_bo (surface->drm.bo));
    if (unlikely (ptr == NULL))
	return _cairo_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->status;

    _cairo_surface_attach_snapshot (&surface->drm.base, image, surface_finish_and_destroy);

DONE:
    *image_out = (cairo_image_surface_t *) cairo_surface_reference (image);
    *image_extra = NULL;
    return CAIRO_STATUS_SUCCESS;
}
/**
 * cairo_os2_surface_set_hps:
 * @surface: the cairo surface to associate with the HPS
 * @hps: new HPS to be associated with the surface (the HPS may be null)
 *
 * This API replaces the HPS associated with the surface with a new one.
 * The caller retains ownership of the HPS and must dispose of it after
 * the surface has been destroyed or it has been replaced by another
 * call to this function.
 *
 * Return value: %CAIRO_STATUS_SUCCESS if the hps could be replaced,
 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface,
 *
 * Since: 1.10
 **/
cairo_status_t
cairo_os2_surface_set_hps (cairo_surface_t *surface,
                           HPS              hps)
{
    cairo_os2_surface_t *local_os2_surface;

    local_os2_surface = (cairo_os2_surface_t *) surface;
    if ((!local_os2_surface) ||
        (local_os2_surface->base.backend != &cairo_os2_surface_backend))
    {
        /* Invalid parameter (wrong surface)! */
        return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
    }
    local_os2_surface->hps_client_window = hps;

    return CAIRO_STATUS_SUCCESS;
}
Beispiel #24
0
static cairo_status_t
twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
					cairo_toy_font_face_t *toy_face)
{
    twin_face_properties_t *props;

    props = twin_font_face_create_properties (twin_face);
    if (unlikely (props == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    props->slant = toy_face->slant;
    props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ?
		    TWIN_WEIGHT_NORMAL : TWIN_WEIGHT_BOLD;
    face_props_parse (props, toy_face->family);

    return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
twin_scaled_font_compute_properties (cairo_scaled_font_t *scaled_font,
				     cairo_t           *cr)
{
    cairo_status_t status;
    twin_scaled_properties_t *props;

    props = malloc (sizeof (twin_scaled_properties_t));
    if (unlikely (props == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);


    props->face_props = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
						       &twin_properties_key);

    props->snap = scaled_font->options.hint_style > CAIRO_HINT_STYLE_NONE;

    /* weight */
    props->weight = props->face_props->weight * (F (4) / TWIN_WEIGHT_NORMAL);

    /* pen & margins */
    props->penx = props->peny = props->weight;
    props->marginl = props->marginr = F (4);
    if (scaled_font->options.hint_style > CAIRO_HINT_STYLE_SLIGHT)
	twin_hint_pen_and_margins(cr,
				  &props->penx, &props->peny,
				  &props->marginl, &props->marginr);

    /* stretch */
    props->stretch = 1 + .1 * ((int) props->face_props->stretch - (int) TWIN_STRETCH_NORMAL);


    /* Save it */
    status = cairo_scaled_font_set_user_data (scaled_font,
					      &twin_properties_key,
					      props, free);
    if (unlikely (status))
	goto FREE_PROPS;

    return CAIRO_STATUS_SUCCESS;

FREE_PROPS:
    free (props);
    return status;
}
Beispiel #26
0
/**
 * _cairo_traps_init_boxes:
 * @traps: a #cairo_traps_t
 * @box: an array box that will each be converted to a single trapezoid
 *       to store in @traps.
 *
 * Initializes a #cairo_traps_t to contain an array of rectangular
 * trapezoids.
 **/
cairo_status_t
_cairo_traps_init_boxes (cairo_traps_t	    *traps,
		         const cairo_boxes_t *boxes)
{
    cairo_trapezoid_t *trap;
    const struct _cairo_boxes_chunk *chunk;

    _cairo_traps_init (traps);

    while (traps->traps_size < boxes->num_boxes) {
	if (unlikely (! _cairo_traps_grow (traps))) {
	    _cairo_traps_fini (traps);
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	}
    }

    traps->num_traps = boxes->num_boxes;
    traps->is_rectilinear = TRUE;
    traps->is_rectangular = TRUE;
    traps->maybe_region = boxes->is_pixel_aligned;

    trap = &traps->traps[0];
    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
	const cairo_box_t *box;
	int i;

	box = chunk->base;
	for (i = 0; i < chunk->count; i++) {
	    trap->top    = box->p1.y;
	    trap->bottom = box->p2.y;

	    trap->left.p1   = box->p1;
	    trap->left.p2.x = box->p1.x;
	    trap->left.p2.y = box->p2.y;

	    trap->right.p1.x = box->p2.x;
	    trap->right.p1.y = box->p1.y;
	    trap->right.p2   = box->p2;

	    box++, trap++;
	}
    }

    return CAIRO_STATUS_SUCCESS;
}
static cairo_image_surface_t *
_cairo_win32_display_surface_map_to_image (void                    *abstract_surface,
					   const cairo_rectangle_int_t   *extents)
{
    cairo_win32_display_surface_t *surface = abstract_surface;
    cairo_status_t status;

    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, surface->win32.base.unique_id));

    if (surface->image)
	goto done;

    if (surface->fallback == NULL) {
	surface->fallback =
	    _cairo_win32_display_surface_create_for_dc (surface->win32.dc,
							surface->win32.format,
							surface->win32.extents.width,
							surface->win32.extents.height);
	if (unlikely (status = surface->fallback->status))
	    goto err;

	if (!BitBlt (to_win32_surface(surface->fallback)->dc,
		     0, 0,
		     surface->win32.extents.width,
		     surface->win32.extents.height,
		     surface->win32.dc,
		     0, 0,
		     SRCCOPY)) {
	    status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
	    goto err;
	}
    }

    surface = to_win32_display_surface (surface->fallback);
done:
    GdiFlush();
    return _cairo_surface_map_to_image (surface->image, extents);

err:
    cairo_surface_destroy (surface->fallback);
    surface->fallback = NULL;

    return _cairo_image_surface_create_in_error (status);
}
cairo_surface_t *
cairo_qt_surface_create_with_qimage (cairo_format_t format,
				     int width,
				     int height)
{
    cairo_qt_surface_t *qs;

    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));

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

    _cairo_surface_clipper_init (&qs->clipper,
				 _cairo_qt_surface_clipper_intersect_clip_path);


    QImage *image = new QImage (width, height,
				_qimage_format_from_cairo_format (format));

    qs->image = image;

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

    qs->image_equiv = cairo_image_surface_create_for_data (image->bits(),
                                                           format,
                                                           width, height,
                                                           image->bytesPerLine());

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

    D(fprintf(stderr, "qpainter_surface_create: qimage: [%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;
}
Beispiel #29
0
static cairo_skia_surface_t *
_cairo_skia_surface_create_internal (SkBitmap::Config config,
				     bool opaque,
				     unsigned char *data,
				     int width,
				     int height,
				     int stride)
{
    cairo_skia_surface_t *surface;
    cairo_format_t format;

    surface = (cairo_skia_surface_t *) malloc (sizeof (cairo_skia_surface_t));
    if (surface == NULL)
	return (cairo_skia_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    memset (surface, 0, sizeof (cairo_skia_surface_t));

    format = sk_config_to_format (config, opaque);
    assert (format != -1);

    _cairo_surface_init (&surface->base,
			 &cairo_skia_surface_backend,
			 NULL, /* device */
			 _cairo_content_from_format (format));

    _cairo_surface_clipper_init (&surface->clipper,
				 _cairo_skia_surface_clipper_intersect_clip_path);

    surface->bitmap = new SkBitmap;
    if (data == NULL)
	stride = cairo_format_stride_for_width (format, width);
    surface->bitmap->setConfig (config, width, height, stride);
    surface->bitmap->setIsOpaque (opaque);
    if (data != NULL)
	surface->bitmap->setPixels (data);
    else
	surface->bitmap->allocPixels ();

    surface->canvas = new SkCanvas (*surface->bitmap);
    //surface->canvas->translate (SkIntToScalar (0), SkIntToScalar (height));
    //surface->canvas->scale (SkIntToScalar (1), SkIntToScalar (-1));
    surface->canvas->save ();

    return surface;
}
Beispiel #30
0
cairo_status_t
_cairo_polygon_init_box_array (cairo_polygon_t *polygon,
			       cairo_box_t *boxes,
			       int num_boxes)
{
    int i;

    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));

    polygon->status = CAIRO_STATUS_SUCCESS;

    polygon->num_edges = 0;

    polygon->edges = polygon->edges_embedded;
    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
    if (num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
	polygon->edges_size = 2 * num_boxes;
	polygon->edges = _cairo_malloc_ab (polygon->edges_size,
					   2*sizeof(cairo_edge_t));
	if (unlikely (polygon->edges == XNULL))
	    return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
    }

    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;

    polygon->limits = XNULL;
    polygon->num_limits = 0;

    for (i = 0; i < num_boxes; i++) {
	cairo_point_t p1, p2;

	p1 = boxes[i].p1;
	p2.x = p1.x;
	p2.y = boxes[i].p2.y;
	_cairo_polygon_add_edge (polygon, &p1, &p2, 1);

	p1 = boxes[i].p2;
	p2.x = p1.x;
	p2.y = boxes[i].p1.y;
	_cairo_polygon_add_edge (polygon, &p1, &p2, 1);
    }

    return polygon->status;
}