/** * 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; }
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); }
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; }
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; }
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; }
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; }
/** * _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; }
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; }
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; }
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; }
/** * _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; }
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; }
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; }