static void cairo_truetype_font_destroy (cairo_truetype_font_t *font) { _cairo_array_fini (&font->string_offsets); free (font->base.widths); free (font->base.base_font); free (font->parent_to_subset); free (font->glyphs); _cairo_array_fini (&font->output); free (font); }
static void _gl_destroy (void *device) { cairo_gl_context_t *ctx = device; ctx->acquire (ctx); while (! cairo_list_is_empty (&ctx->fonts)) { cairo_gl_font_t *font; font = cairo_list_first_entry (&ctx->fonts, cairo_gl_font_t, link); cairo_list_del (&font->base.link); cairo_list_del (&font->link); free (font); } _cairo_array_fini (&ctx->tristrip_indices); cairo_region_destroy (ctx->clip_region); _cairo_clip_destroy (ctx->clip); free (ctx->vb); ctx->destroy (ctx); free (ctx); }
void _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info) { cairo_xlib_screen_info_t **prev; cairo_xlib_screen_info_t *list; assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); if (! _cairo_reference_count_dec_and_test (&info->ref_count)) return; CAIRO_MUTEX_LOCK (info->display->mutex); for (prev = &info->display->screens; (list = *prev); prev = &list->next) { if (list == info) { *prev = info->next; break; } } CAIRO_MUTEX_UNLOCK (info->display->mutex); _cairo_xlib_screen_info_close_display (info); _cairo_xlib_display_destroy (info->display); _cairo_array_fini (&info->visuals); CAIRO_MUTEX_FINI (info->mutex); free (info); }
static cairo_status_t _cairo_meta_surface_finish (void *abstract_surface) { cairo_meta_surface_t *meta = abstract_surface; cairo_command_t *command; cairo_command_t **elements; int i, num_elements; num_elements = meta->commands.num_elements; elements = (cairo_command_t **) meta->commands.elements; for (i = 0; i < num_elements; i++) { command = elements[i]; switch (command->type) { case CAIRO_COMMAND_COMPOSITE: _cairo_pattern_fini (&command->composite.src_pattern.base); if (command->composite.mask_pattern_pointer) _cairo_pattern_fini (command->composite.mask_pattern_pointer); free (command); break; case CAIRO_COMMAND_FILL_RECTANGLES: free (command->fill_rectangles.rects); free (command); break; case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS: _cairo_pattern_fini (&command->composite_trapezoids.pattern.base); free (command->composite_trapezoids.traps); free (command); break; case CAIRO_COMMAND_INTERSECT_CLIP_PATH: if (command->intersect_clip_path.path_pointer) _cairo_path_fixed_fini (&command->intersect_clip_path.path); free (command); break; case CAIRO_COMMAND_SHOW_GLYPHS: cairo_scaled_font_destroy (command->show_glyphs.scaled_font); _cairo_pattern_fini (&command->show_glyphs.pattern.base); free (command->show_glyphs.glyphs); free (command); break; case CAIRO_COMMAND_FILL_PATH: _cairo_pattern_fini (&command->fill_path.pattern.base); _cairo_path_fixed_fini (&command->fill_path.path); free (command); break; default: ASSERT_NOT_REACHED; } } _cairo_array_fini (&meta->commands); return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _cairo_recording_surface_finish (void *abstract_surface) { cairo_recording_surface_t *recording_surface = abstract_surface; cairo_command_t **elements; int i, num_elements; num_elements = recording_surface->commands.num_elements; elements = _cairo_array_index (&recording_surface->commands, 0); for (i = 0; i < num_elements; i++) { cairo_command_t *command = elements[i]; switch (command->header.type) { case CAIRO_COMMAND_PAINT: _cairo_pattern_fini (&command->paint.source.base); break; case CAIRO_COMMAND_MASK: _cairo_pattern_fini (&command->mask.source.base); _cairo_pattern_fini (&command->mask.mask.base); break; case CAIRO_COMMAND_STROKE: _cairo_pattern_fini (&command->stroke.source.base); _cairo_path_fixed_fini (&command->stroke.path); _cairo_stroke_style_fini (&command->stroke.style); break; case CAIRO_COMMAND_FILL: _cairo_pattern_fini (&command->fill.source.base); _cairo_path_fixed_fini (&command->fill.path); break; case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: _cairo_pattern_fini (&command->show_text_glyphs.source.base); free (command->show_text_glyphs.utf8); free (command->show_text_glyphs.glyphs); free (command->show_text_glyphs.clusters); cairo_scaled_font_destroy (command->show_text_glyphs.scaled_font); break; default: ASSERT_NOT_REACHED; } _cairo_clip_fini (&command->header.clip); free (command); } _cairo_array_fini (&recording_surface->commands); _cairo_clip_fini (&recording_surface->clip); return CAIRO_STATUS_SUCCESS; }
/** * _cairo_user_data_array_fini: * @array: a #cairo_user_data_array_t * * Destroys all current keys in the user data array and deallocates * any memory allocated for the array itself. **/ void _cairo_user_data_array_fini (cairo_user_data_array_t *array) { int i, num_slots; cairo_user_data_slot_t *slots; num_slots = array->num_elements; slots = _cairo_array_index (array, 0); for (i = 0; i < num_slots; i++) { if (slots[i].user_data != NULL && slots[i].destroy != NULL) slots[i].destroy (slots[i].user_data); } _cairo_array_fini (array); }
static cairo_status_t _cairo_tee_surface_finish (void *abstract_surface) { cairo_tee_surface_t *surface = abstract_surface; cairo_surface_wrapper_t *slaves; int n, num_slaves; _cairo_surface_wrapper_fini (&surface->master); num_slaves = _cairo_array_num_elements (&surface->slaves); slaves = _cairo_array_index (&surface->slaves, 0); for (n = 0; n < num_slaves; n++) _cairo_surface_wrapper_fini (&slaves[n]); _cairo_array_fini (&surface->slaves); return CAIRO_STATUS_SUCCESS; }
/** * _cairo_user_data_array_fini: * @array: a #cairo_user_data_array_t * * Destroys all current keys in the user data array and deallocates * any memory allocated for the array itself. **/ void _cairo_user_data_array_fini (cairo_user_data_array_t *array) { unsigned int num_slots; num_slots = array->num_elements; if (num_slots) { cairo_user_data_slot_t *slots; slots = _cairo_array_index (array, 0); do { if (slots->user_data != NULL && slots->destroy != NULL) slots->destroy (slots->user_data); slots++; } while (--num_slots); } _cairo_array_fini (array); }
/** * _cairo_user_data_array_fini: * @array: a #cairo_user_data_array_t * * Destroys all current keys in the user data array and deallocates * any memory allocated for the array itself. **/ void _cairo_user_data_array_fini (cairo_user_data_array_t *array) { unsigned int num_slots; num_slots = array->num_elements; if (num_slots) { cairo_user_data_slot_t *slots; slots = _cairo_array_index (array, 0); while (num_slots--) { cairo_user_data_slot_t *s = &slots[num_slots]; if (s->user_data != NULL && s->destroy != NULL) s->destroy (s->user_data); } } _cairo_array_fini (array); }
static cairo_status_t _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, cairo_truetype_font_t **font_return) { cairo_status_t status; cairo_truetype_font_t *font; const cairo_scaled_font_backend_t *backend; tt_head_t head; tt_hhea_t hhea; tt_maxp_t maxp; unsigned long size; backend = scaled_font_subset->scaled_font->backend; if (!backend->load_truetype_table) return CAIRO_INT_STATUS_UNSUPPORTED; /* FIXME: We should either support subsetting vertical fonts, or fail on * vertical. Currently font_options_t doesn't have vertical flag, but * it should be added in the future. For now, the freetype backend * returns UNSUPPORTED in load_truetype_table if the font is vertical. * * if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font)) * return CAIRO_INT_STATUS_UNSUPPORTED; */ size = sizeof (tt_head_t); status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_head, 0, (unsigned char *) &head, &size); if (unlikely (status)) return status; size = sizeof (tt_maxp_t); status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_maxp, 0, (unsigned char *) &maxp, &size); if (unlikely (status)) return status; size = sizeof (tt_hhea_t); status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_hhea, 0, (unsigned char *) &hhea, &size); if (unlikely (status)) return status; font = malloc (sizeof (cairo_truetype_font_t)); if (unlikely (font == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font->backend = backend; font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs); font->scaled_font_subset = scaled_font_subset; font->last_offset = 0; font->last_boundary = 0; _cairo_array_init (&font->output, sizeof (char)); status = _cairo_array_grow_by (&font->output, 4096); if (unlikely (status)) goto fail1; font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t)); if (unlikely (font->glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int)); if (unlikely (font->parent_to_subset == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } font->base.num_glyphs = 0; font->base.x_min = (int16_t) be16_to_cpu (head.x_min); font->base.y_min = (int16_t) be16_to_cpu (head.y_min); font->base.x_max = (int16_t) be16_to_cpu (head.x_max); font->base.y_max = (int16_t) be16_to_cpu (head.y_max); font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender); font->base.descent = (int16_t) be16_to_cpu (hhea.descender); font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em); if (font->base.units_per_em == 0) font->base.units_per_em = 2048; font->base.font_name = NULL; status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font, &font->base.ps_name, &font->base.font_name); if (_cairo_status_is_error (status)) goto fail3; /* If the PS name is not found, create a CairoFont-x-y name. */ if (font->base.ps_name == NULL) { font->base.ps_name = malloc (30); if (unlikely (font->base.ps_name == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } snprintf(font->base.ps_name, 30, "CairoFont-%u-%u", scaled_font_subset->font_id, scaled_font_subset->subset_id); } font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int)); if (unlikely (font->base.widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail4; } _cairo_array_init (&font->string_offsets, sizeof (unsigned long)); status = _cairo_array_grow_by (&font->string_offsets, 10); if (unlikely (status)) goto fail5; font->status = CAIRO_STATUS_SUCCESS; *font_return = font; return CAIRO_STATUS_SUCCESS; fail5: _cairo_array_fini (&font->string_offsets); free (font->base.widths); fail4: free (font->base.ps_name); fail3: free (font->parent_to_subset); if (font->base.font_name) free (font->base.font_name); fail2: free (font->glyphs); fail1: _cairo_array_fini (&font->output); free (font); return status; }
static cairo_status_t _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, cairo_truetype_font_t **font_return) { cairo_status_t status; cairo_truetype_font_t *font; const cairo_scaled_font_backend_t *backend; tt_head_t head; tt_hhea_t hhea; tt_maxp_t maxp; tt_name_t *name; tt_name_record_t *record; unsigned long size; int i, j; backend = scaled_font_subset->scaled_font->backend; if (!backend->load_truetype_table) return CAIRO_INT_STATUS_UNSUPPORTED; /* FIXME: We should either support subsetting vertical fonts, or fail on * vertical. Currently font_options_t doesn't have vertical flag, but * it should be added in the future. For now, the freetype backend * returns UNSUPPORTED in load_truetype_table if the font is vertical. * * if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font)) * return CAIRO_INT_STATUS_UNSUPPORTED; */ size = sizeof (tt_head_t); if (backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_head, 0, (unsigned char *) &head, &size) != CAIRO_STATUS_SUCCESS) return CAIRO_INT_STATUS_UNSUPPORTED; size = sizeof (tt_maxp_t); if (backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_maxp, 0, (unsigned char *) &maxp, &size) != CAIRO_STATUS_SUCCESS) return CAIRO_INT_STATUS_UNSUPPORTED; size = sizeof (tt_hhea_t); if (backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_hhea, 0, (unsigned char *) &hhea, &size) != CAIRO_STATUS_SUCCESS) return CAIRO_INT_STATUS_UNSUPPORTED; size = 0; if (backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_name, 0, NULL, &size) != CAIRO_STATUS_SUCCESS) return CAIRO_INT_STATUS_UNSUPPORTED; name = malloc(size); if (name == NULL) return CAIRO_STATUS_NO_MEMORY; status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_name, 0, (unsigned char *) name, &size); if (status) goto fail0; font = malloc (sizeof (cairo_truetype_font_t)); if (font == NULL) { status = CAIRO_STATUS_NO_MEMORY; goto fail0; } font->backend = backend; font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs); font->scaled_font_subset = scaled_font_subset; font->last_offset = 0; font->last_boundary = 0; _cairo_array_init (&font->output, sizeof (char)); status = _cairo_array_grow_by (&font->output, 4096); if (status) goto fail1; font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t)); if (font->glyphs == NULL) { status = CAIRO_STATUS_NO_MEMORY; goto fail1; } font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int)); if (font->parent_to_subset == NULL) { status = CAIRO_STATUS_NO_MEMORY; goto fail2; } font->base.num_glyphs = 0; font->base.x_min = (int16_t) be16_to_cpu (head.x_min); font->base.y_min = (int16_t) be16_to_cpu (head.y_min); font->base.x_max = (int16_t) be16_to_cpu (head.x_max); font->base.y_max = (int16_t) be16_to_cpu (head.y_max); font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender); font->base.descent = (int16_t) be16_to_cpu (hhea.descender); font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em); if (font->base.units_per_em == 0) font->base.units_per_em = 2048; /* Extract the font name from the name table. At present this * just looks for the Mac platform/Roman encoded font name. It * should be extended to use any suitable font name in the * name table. If the mac/roman font name is not found a * CairoFont-x-y name is created. */ font->base.base_font = NULL; for (i = 0; i < be16_to_cpu(name->num_records); i++) { record = &(name->records[i]); if ((be16_to_cpu (record->platform) == 1) && (be16_to_cpu (record->encoding) == 0) && (be16_to_cpu (record->name) == 4)) { font->base.base_font = malloc (be16_to_cpu(record->length) + 1); if (font->base.base_font) { strncpy(font->base.base_font, ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset), be16_to_cpu (record->length)); font->base.base_font[be16_to_cpu (record->length)] = 0; } break; } } free (name); name = NULL; if (font->base.base_font == NULL) { font->base.base_font = malloc (30); if (font->base.base_font == NULL) { status = CAIRO_STATUS_NO_MEMORY; goto fail3; } snprintf(font->base.base_font, 30, "CairoFont-%u-%u", scaled_font_subset->font_id, scaled_font_subset->subset_id); } for (i = 0, j = 0; font->base.base_font[j]; j++) { if (font->base.base_font[j] == ' ') continue; font->base.base_font[i++] = font->base.base_font[j]; } font->base.base_font[i] = '\0'; font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int)); if (font->base.widths == NULL) { status = CAIRO_STATUS_NO_MEMORY; goto fail4; } _cairo_array_init (&font->string_offsets, sizeof (unsigned long)); status = _cairo_array_grow_by (&font->string_offsets, 10); if (status) goto fail5; font->status = CAIRO_STATUS_SUCCESS; *font_return = font; return CAIRO_STATUS_SUCCESS; fail5: _cairo_array_fini (&font->string_offsets); free (font->base.widths); fail4: free (font->base.base_font); fail3: free (font->parent_to_subset); fail2: free (font->glyphs); fail1: _cairo_array_fini (&font->output); free (font); fail0: if (name) free (name); return status; }
static cairo_status_t _cairo_meta_surface_finish (void *abstract_surface) { cairo_meta_surface_t *meta = abstract_surface; cairo_command_t *command; cairo_command_t **elements; int i, num_elements; if (meta->commands_owner) { cairo_surface_destroy (meta->commands_owner); return CAIRO_STATUS_SUCCESS; } num_elements = meta->commands.num_elements; elements = _cairo_array_index (&meta->commands, 0); for (i = 0; i < num_elements; i++) { command = elements[i]; switch (command->header.type) { /* 5 basic drawing operations */ case CAIRO_COMMAND_PAINT: _cairo_pattern_fini (&command->paint.source.base); free (command); break; case CAIRO_COMMAND_MASK: _cairo_pattern_fini (&command->mask.source.base); _cairo_pattern_fini (&command->mask.mask.base); free (command); break; case CAIRO_COMMAND_STROKE: _cairo_pattern_fini (&command->stroke.source.base); _cairo_path_fixed_fini (&command->stroke.path); _cairo_stroke_style_fini (&command->stroke.style); free (command); break; case CAIRO_COMMAND_FILL: _cairo_pattern_fini (&command->fill.source.base); _cairo_path_fixed_fini (&command->fill.path); free (command); break; case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: _cairo_pattern_fini (&command->show_text_glyphs.source.base); free (command->show_text_glyphs.utf8); free (command->show_text_glyphs.glyphs); free (command->show_text_glyphs.clusters); cairo_scaled_font_destroy (command->show_text_glyphs.scaled_font); free (command); break; /* Other junk. */ case CAIRO_COMMAND_INTERSECT_CLIP_PATH: if (command->intersect_clip_path.path_pointer) _cairo_path_fixed_fini (&command->intersect_clip_path.path); free (command); break; default: ASSERT_NOT_REACHED; } } _cairo_array_fini (&meta->commands); return CAIRO_STATUS_SUCCESS; }