cairo_status_t _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info, Visual *visual, cairo_xlib_visual_info_t **out) { Display *dpy = info->display->display; cairo_xlib_visual_info_t **visuals, *ret = NULL; cairo_status_t status; int i, n_visuals; CAIRO_MUTEX_LOCK (info->mutex); visuals = _cairo_array_index (&info->visuals, 0); n_visuals = _cairo_array_num_elements (&info->visuals); for (i = 0; i < n_visuals; i++) { if (visuals[i]->visualid == visual->visualid) { ret = visuals[i]; break; } } CAIRO_MUTEX_UNLOCK (info->mutex); if (ret != NULL) { *out = ret; return CAIRO_STATUS_SUCCESS; } status = _cairo_xlib_visual_info_create (dpy, XScreenNumberOfScreen (info->screen), visual->visualid, &ret); if (status) return status; CAIRO_MUTEX_LOCK (info->mutex); if (n_visuals != _cairo_array_num_elements (&info->visuals)) { /* check that another thread has not added our visual */ int new_visuals = _cairo_array_num_elements (&info->visuals); visuals = _cairo_array_index (&info->visuals, 0); for (i = n_visuals; i < new_visuals; i++) { if (visuals[i]->visualid == visual->visualid) { _cairo_xlib_visual_info_destroy (dpy, ret); ret = visuals[i]; break; } } if (i == new_visuals) status = _cairo_array_append (&info->visuals, &ret); } else status = _cairo_array_append (&info->visuals, &ret); CAIRO_MUTEX_UNLOCK (info->mutex); if (status) { _cairo_xlib_visual_info_destroy (dpy, ret); return status; } *out = ret; return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_meta_surface_fill_rectangles (void *abstract_surface, cairo_operator_t operator, const cairo_color_t *color, cairo_rectangle_t *rects, int num_rects) { cairo_meta_surface_t *meta = abstract_surface; cairo_command_fill_rectangles_t *command; command = malloc (sizeof (cairo_command_fill_rectangles_t)); if (command == NULL) return CAIRO_STATUS_NO_MEMORY; command->type = CAIRO_COMMAND_FILL_RECTANGLES; command->operator = operator; command->color = *color; command->rects = malloc (sizeof (cairo_rectangle_t) * num_rects); if (command->rects == NULL) { free (command); return CAIRO_STATUS_NO_MEMORY; } memcpy (command->rects, rects, sizeof (cairo_rectangle_t) * num_rects); command->num_rects = num_rects; if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { free (command->rects); free (command); return CAIRO_STATUS_NO_MEMORY; } return CAIRO_STATUS_SUCCESS; }
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 (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); } }
static cairo_int_status_t _cairo_recording_surface_stroke (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, cairo_path_fixed_t *path, const cairo_stroke_style_t *style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, cairo_clip_t *clip) { cairo_status_t status; cairo_recording_surface_t *recording_surface = abstract_surface; cairo_command_stroke_t *command; command = malloc (sizeof (cairo_command_stroke_t)); if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _command_init (recording_surface, &command->header, CAIRO_COMMAND_STROKE, op, clip); if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_path_fixed_init_copy (&command->path, path); if (unlikely (status)) goto CLEANUP_SOURCE; status = _cairo_stroke_style_init_copy (&command->style, style); if (unlikely (status)) goto CLEANUP_PATH; command->ctm = *ctm; command->ctm_inverse = *ctm_inverse; command->tolerance = tolerance; command->antialias = antialias; status = _cairo_array_append (&recording_surface->commands, &command); if (unlikely (status)) goto CLEANUP_STYLE; return CAIRO_STATUS_SUCCESS; CLEANUP_STYLE: _cairo_stroke_style_fini (&command->style); CLEANUP_PATH: _cairo_path_fixed_fini (&command->path); CLEANUP_SOURCE: _cairo_pattern_fini (&command->source.base); CLEANUP_COMMAND: _cairo_clip_fini (&command->header.clip); free (command); return status; }
static cairo_int_status_t _cairo_meta_surface_stroke (void *abstract_surface, cairo_operator_t op, cairo_pattern_t *source, cairo_path_fixed_t *path, cairo_stroke_style_t *style, cairo_matrix_t *ctm, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; cairo_command_stroke_t *command; command = malloc (sizeof (cairo_command_stroke_t)); if (command == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_STROKE; 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; status = _cairo_stroke_style_init_copy (&command->style, style); if (status) goto CLEANUP_PATH; command->ctm = *ctm; command->ctm_inverse = *ctm_inverse; command->tolerance = tolerance; command->antialias = antialias; status = _cairo_array_append (&meta->commands, &command); if (status) goto CLEANUP_STYLE; return CAIRO_STATUS_SUCCESS; CLEANUP_STYLE: _cairo_stroke_style_fini (&command->style); CLEANUP_PATH: _cairo_path_fixed_fini (&command->path); CLEANUP_SOURCE: _cairo_pattern_fini (&command->source.base); CLEANUP_COMMAND: free (command); return status; }
static cairo_int_status_t _cairo_gl_composite_append_vertex_indices (cairo_gl_context_t *ctx, int number_of_new_indices, cairo_bool_t is_connected) { cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; cairo_array_t *indices = &ctx->tristrip_indices; int number_of_indices = _cairo_array_num_elements (indices); unsigned short current_vertex_index = 0; int i; assert (number_of_new_indices > 0); /* If any preexisting triangle triangle strip indices exist on this context, we insert a set of degenerate triangles from the last preexisting vertex to our first one. */ if (number_of_indices > 0 && is_connected) { const unsigned short *indices_array = _cairo_array_index_const (indices, 0); current_vertex_index = indices_array[number_of_indices - 1]; status = _cairo_array_append (indices, ¤t_vertex_index); if (unlikely (status)) return status; current_vertex_index++; status =_cairo_array_append (indices, ¤t_vertex_index); if (unlikely (status)) return status; } else current_vertex_index = (unsigned short) number_of_indices; for (i = 0; i < number_of_new_indices; i++) { status = _cairo_array_append (indices, ¤t_vertex_index); current_vertex_index++; if (unlikely (status)) return status; } return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_meta_surface_show_glyphs (cairo_scaled_font_t *scaled_font, cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_surface, int source_x, int source_y, int dest_x, int dest_y, unsigned int width, unsigned int height, const cairo_glyph_t *glyphs, int num_glyphs) { cairo_meta_surface_t *meta = abstract_surface; cairo_command_show_glyphs_t *command; command = malloc (sizeof (cairo_command_show_glyphs_t)); if (command == NULL) return CAIRO_STATUS_NO_MEMORY; command->type = CAIRO_COMMAND_SHOW_GLYPHS; command->scaled_font = cairo_scaled_font_reference (scaled_font); command->operator = operator; _cairo_pattern_init_copy (&command->pattern.base, pattern); command->source_x = source_x; command->source_y = source_y; command->dest_x = dest_x; command->dest_y = dest_y; command->width = width; command->height = height; command->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs); if (command->glyphs == NULL) { _cairo_pattern_fini (&command->pattern.base); free (command); return CAIRO_STATUS_NO_MEMORY; } memcpy (command->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); command->num_glyphs = num_glyphs; if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { _cairo_pattern_fini (&command->pattern.base); free (command->glyphs); free (command); return CAIRO_STATUS_NO_MEMORY; } return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_meta_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_surface, cairo_antialias_t antialias, int x_src, int y_src, int x_dst, int y_dst, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, int num_traps) { cairo_meta_surface_t *meta = abstract_surface; cairo_command_composite_trapezoids_t *command; command = malloc (sizeof (cairo_command_composite_trapezoids_t)); if (command == NULL) return CAIRO_STATUS_NO_MEMORY; command->type = CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS; command->operator = operator; _cairo_pattern_init_copy (&command->pattern.base, pattern); command->antialias = antialias; command->x_src = x_src; command->y_src = y_src; command->x_dst = x_dst; command->y_dst = y_dst; command->width = width; command->height = height; command->traps = malloc (sizeof (cairo_trapezoid_t) * num_traps); if (command->traps == NULL) { _cairo_pattern_fini (&command->pattern.base); free (command); return CAIRO_STATUS_NO_MEMORY; } memcpy (command->traps, traps, sizeof (cairo_trapezoid_t) * num_traps); command->num_traps = num_traps; if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { _cairo_pattern_fini (&command->pattern.base); free (command->traps); free (command); return CAIRO_STATUS_NO_MEMORY; } return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_meta_surface_composite (cairo_operator_t operator, cairo_pattern_t *src_pattern, cairo_pattern_t *mask_pattern, void *abstract_surface, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height) { cairo_meta_surface_t *meta = abstract_surface; cairo_command_composite_t *command; command = malloc (sizeof (cairo_command_composite_t)); if (command == NULL) return CAIRO_STATUS_NO_MEMORY; command->type = CAIRO_COMMAND_COMPOSITE; command->operator = operator; _cairo_pattern_init_copy (&command->src_pattern.base, src_pattern); if (mask_pattern) { _cairo_pattern_init_copy (&command->mask_pattern.base, mask_pattern); command->mask_pattern_pointer = &command->mask_pattern.base; } else { command->mask_pattern_pointer = NULL; } command->src_x = src_x; command->src_y = src_y; command->mask_x = mask_x; command->mask_y = mask_y; command->dst_x = dst_x; command->dst_y = dst_y; command->width = width; command->height = height; if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { _cairo_pattern_fini (&command->src_pattern.base); _cairo_pattern_fini (command->mask_pattern_pointer); free (command); return CAIRO_STATUS_NO_MEMORY; } return CAIRO_STATUS_SUCCESS; }
/** * _cairo_user_data_array_set_data: * @array: a #cairo_user_data_array_t * @key: the address of a #cairo_user_data_key_t to attach the user data to * @user_data: the user data to attach * @destroy: a #cairo_destroy_func_t which will be called when the * user data array is destroyed or when new user data is attached using the * same key. * * Attaches user data to a user data array. To remove user data, * call this function with the key that was used to set it and %NULL * for @data. * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a * slot could not be allocated for the user data. **/ cairo_status_t _cairo_user_data_array_set_data (cairo_user_data_array_t *array, const cairo_user_data_key_t *key, void *user_data, cairo_destroy_func_t destroy) { cairo_status_t status; int i, num_slots; cairo_user_data_slot_t *slots, *slot, new_slot; if (user_data) { new_slot.key = key; new_slot.user_data = user_data; new_slot.destroy = destroy; } else { new_slot.key = NULL; new_slot.user_data = NULL; new_slot.destroy = NULL; } slot = NULL; num_slots = array->num_elements; slots = _cairo_array_index (array, 0); for (i = 0; i < num_slots; i++) { if (slots[i].key == key) { slot = &slots[i]; if (slot->destroy && slot->user_data) slot->destroy (slot->user_data); break; } if (user_data && slots[i].user_data == NULL) { slot = &slots[i]; /* Have to keep searching for an exact match */ } } if (slot) { *slot = new_slot; return CAIRO_STATUS_SUCCESS; } status = _cairo_array_append (array, &new_slot); if (status) return status; return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_meta_surface_intersect_clip_path (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias) { cairo_meta_surface_t *meta = dst; cairo_command_intersect_clip_path_t *command; cairo_status_t status; command = malloc (sizeof (cairo_command_intersect_clip_path_t)); if (command == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH; command->header.region = CAIRO_META_REGION_ALL; if (path) { status = _cairo_path_fixed_init_copy (&command->path, path); if (status) { free (command); return status; } command->path_pointer = &command->path; meta->is_clipped = TRUE; } else { command->path_pointer = NULL; meta->is_clipped = FALSE; } command->fill_rule = fill_rule; command->tolerance = tolerance; command->antialias = antialias; status = _cairo_array_append (&meta->commands, &command); if (status) { if (path) _cairo_path_fixed_fini (&command->path); free (command); return status; } return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_recording_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, cairo_clip_t *clip) { cairo_status_t status; cairo_recording_surface_t *recording_surface = abstract_surface; cairo_command_mask_t *command; command = malloc (sizeof (cairo_command_mask_t)); if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _command_init (recording_surface, &command->header, CAIRO_COMMAND_MASK, op, clip); if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->mask.base, mask); if (unlikely (status)) goto CLEANUP_SOURCE; status = _cairo_array_append (&recording_surface->commands, &command); if (unlikely (status)) goto CLEANUP_MASK; return CAIRO_STATUS_SUCCESS; CLEANUP_MASK: _cairo_pattern_fini (&command->mask.base); CLEANUP_SOURCE: _cairo_pattern_fini (&command->source.base); CLEANUP_COMMAND: _cairo_clip_fini (&command->header.clip); free (command); return status; }
static cairo_status_t cairo_truetype_font_check_boundary (cairo_truetype_font_t *font, unsigned long boundary) { cairo_status_t status; if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH) { status = _cairo_array_append (&font->string_offsets, &font->last_boundary); if (status) return status; font->last_offset = font->last_boundary; } font->last_boundary = boundary; return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_recording_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, cairo_clip_t *clip) { cairo_status_t status; cairo_recording_surface_t *recording_surface = abstract_surface; cairo_command_paint_t *command; command = malloc (sizeof (cairo_command_paint_t)); if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _command_init (recording_surface, &command->header, CAIRO_COMMAND_PAINT, op, clip); if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_array_append (&recording_surface->commands, &command); if (unlikely (status)) goto CLEANUP_SOURCE; /* An optimisation that takes care to not replay what was done * before surface is cleared. We don't erase recorded commands * since we may have earlier snapshots of this surface. */ if (op == CAIRO_OPERATOR_CLEAR && clip == NULL) recording_surface->replay_start_idx = recording_surface->commands.num_elements; return CAIRO_STATUS_SUCCESS; CLEANUP_SOURCE: _cairo_pattern_fini (&command->source.base); CLEANUP_COMMAND: _cairo_clip_fini (&command->header.clip); free (command); return status; }
static cairo_int_status_t _cairo_meta_surface_mask (void *abstract_surface, cairo_operator_t op, cairo_pattern_t *source, cairo_pattern_t *mask) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; cairo_command_mask_t *command; command = malloc (sizeof (cairo_command_mask_t)); if (command == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_MASK; 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_pattern_init_snapshot (&command->mask.base, mask); if (status) goto CLEANUP_SOURCE; status = _cairo_array_append (&meta->commands, &command); if (status) goto CLEANUP_MASK; return CAIRO_STATUS_SUCCESS; CLEANUP_MASK: _cairo_pattern_fini (&command->mask.base); CLEANUP_SOURCE: _cairo_pattern_fini (&command->source.base); CLEANUP_COMMAND: free (command); return status; }
static cairo_int_status_t _cairo_meta_surface_paint (void *abstract_surface, cairo_operator_t op, cairo_pattern_t *source) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; cairo_command_paint_t *command; command = malloc (sizeof (cairo_command_paint_t)); if (command == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_PAINT; 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_array_append (&meta->commands, &command); if (status) goto CLEANUP_SOURCE; /* An optimisation that takes care to not replay what was done * before surface is cleared. We don't erase recorded commands * since we may have earlier snapshots of this surface. */ if (op == CAIRO_OPERATOR_CLEAR && !meta->is_clipped) meta->replay_start_idx = meta->commands.num_elements; return CAIRO_STATUS_SUCCESS; CLEANUP_SOURCE: _cairo_pattern_fini (&command->source.base); CLEANUP_COMMAND: free (command); return status; }
static cairo_int_status_t _cairo_meta_surface_fill_path (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_surface, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance) { cairo_meta_surface_t *meta = abstract_surface; cairo_command_fill_path_t *command; cairo_status_t status; command = malloc (sizeof (cairo_command_fill_path_t)); if (command == NULL) return CAIRO_STATUS_NO_MEMORY; command->type = CAIRO_COMMAND_FILL_PATH; command->operator = operator; _cairo_pattern_init_copy (&command->pattern.base, pattern); status = _cairo_path_fixed_init_copy (&command->path, path); if (status) { _cairo_pattern_fini (&command->pattern.base); free (command); return CAIRO_STATUS_NO_MEMORY; } command->fill_rule = fill_rule; command->tolerance = tolerance; if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { _cairo_path_fixed_fini (&command->path); _cairo_pattern_fini (&command->pattern.base); free (command); return CAIRO_STATUS_NO_MEMORY; } return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_recording_surface_show_text_glyphs (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const char *utf8, int utf8_len, cairo_glyph_t *glyphs, int num_glyphs, const cairo_text_cluster_t *clusters, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, cairo_clip_t *clip) { cairo_status_t status; cairo_recording_surface_t *recording_surface = abstract_surface; cairo_command_show_text_glyphs_t *command; command = malloc (sizeof (cairo_command_show_text_glyphs_t)); if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _command_init (recording_surface, &command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS, op, clip); if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) goto CLEANUP_COMMAND; command->utf8 = NULL; command->utf8_len = utf8_len; command->glyphs = NULL; command->num_glyphs = num_glyphs; command->clusters = NULL; command->num_clusters = num_clusters; if (utf8_len) { command->utf8 = malloc (utf8_len); if (unlikely (command->utf8 == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_ARRAYS; } memcpy (command->utf8, utf8, utf8_len); } if (num_glyphs) { command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (glyphs[0])); if (unlikely (command->glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_ARRAYS; } memcpy (command->glyphs, glyphs, sizeof (glyphs[0]) * num_glyphs); } if (num_clusters) { command->clusters = _cairo_malloc_ab (num_clusters, sizeof (clusters[0])); if (unlikely (command->clusters == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_ARRAYS; } memcpy (command->clusters, clusters, sizeof (clusters[0]) * num_clusters); } command->cluster_flags = cluster_flags; command->scaled_font = cairo_scaled_font_reference (scaled_font); status = _cairo_array_append (&recording_surface->commands, &command); if (unlikely (status)) goto CLEANUP_SCALED_FONT; return CAIRO_STATUS_SUCCESS; CLEANUP_SCALED_FONT: cairo_scaled_font_destroy (command->scaled_font); CLEANUP_ARRAYS: free (command->utf8); free (command->glyphs); free (command->clusters); _cairo_pattern_fini (&command->source.base); CLEANUP_COMMAND: _cairo_clip_fini (&command->header.clip); free (command); return status; }