void hb_buffer_set_flags(hb_buffer_t * buffer, hb_buffer_flags_t flags) { if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; buffer->flags = flags; }
void hb_buffer_set_direction(hb_buffer_t * buffer, hb_direction_t direction) { if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; buffer->props.direction = direction; }
void hb_buffer_set_language(hb_buffer_t * buffer, hb_language_t language) { if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; buffer->props.language = language; }
void hb_buffer_set_script(hb_buffer_t * buffer, hb_script_t script) { if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; buffer->props.script = script; }
void hb_buffer_clear(hb_buffer_t * buffer) { hb_segment_properties_t default_props; if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; /*XXX:default_props = HB_SEGMENT_PROPERTIES_DEFAULT;*/ HB_SEGMENT_PROPERTIES_DEFAULT_INIT(default_props); buffer->props = default_props; buffer->flags = HB_BUFFER_FLAG_DEFAULT; buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID; buffer->in_error = FALSE; buffer->have_output = FALSE; buffer->have_positions = FALSE; buffer->idx = 0; buffer->len = 0; buffer->out_len = 0; buffer->out_info = buffer->info; buffer->serial = 0; memset(buffer->allocated_var_bytes, 0, sizeof(buffer->allocated_var_bytes)); memset(buffer->allocated_var_owner, 0, sizeof(buffer->allocated_var_owner)); memset(buffer->context, 0, sizeof(buffer->context)); memset(buffer->context_len, 0, sizeof(buffer->context_len)); }
void hb_buffer_destroy(hb_buffer_t * buffer) { if (!buffer) return; if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; hb_atomic_int32_add(&buffer->ref_cnt, -1); if (hb_atomic_int32_get(&buffer->ref_cnt) > 0) return; hb_atomic_int32_set(&buffer->ref_cnt, REF_CNT_INVALID_VAL); hb_unicode_funcs_destroy(buffer->unicode); free(buffer->info); free(buffer->pos); free(buffer); }
void hb_buffer_reset(hb_buffer_t * buffer) { if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; hb_unicode_funcs_destroy(buffer->unicode); buffer->unicode = hb_unicode_funcs_get_default(); hb_buffer_clear(buffer); }
void hb_buffer_set_unicode_funcs(hb_buffer_t * buffer, hb_unicode_funcs_t * unicode_funcs) { if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; if (!unicode_funcs) unicode_funcs = hb_unicode_funcs_get_default(); hb_unicode_funcs_reference(unicode_funcs); hb_unicode_funcs_destroy(buffer->unicode); buffer->unicode = unicode_funcs; }
void hb_buffer_clear_positions(hb_buffer_t * buffer) { if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; buffer->have_output = FALSE; buffer->have_positions = TRUE; buffer->out_len = 0; buffer->out_info = buffer->info; memset(buffer->pos, 0, sizeof(buffer->pos[0]) * buffer->len); }
void hb_font_destroy(hb_font_t *font) { if (!font) return; if (hb_atomic_int32_get(&font->ref_cnt) == REF_CNT_INVALID_VAL) return; hb_atomic_int32_add(&font->ref_cnt, -1); if (hb_atomic_int32_get(&font->ref_cnt) > 0) return; hb_atomic_int32_set(&font->ref_cnt, REF_CNT_INVALID_VAL); #ifdef HAVE_GRAPHITE2 if (font->shaper_data.graphite2 && font->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID && font->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED) hb_graphite2_shaper_font_data_destroy(font->shaper_data.graphite2); #endif #ifdef HAVE_OT if (font->shaper_data.ot && font->shaper_data.ot != HB_SHAPER_DATA_INVALID && font->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED) hb_ot_shaper_font_data_destroy(font->shaper_data.ot); #endif if (font->shaper_data.fallback && font->shaper_data.fallback != HB_SHAPER_DATA_INVALID && font->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED) hb_fallback_shaper_font_data_destroy(font->shaper_data.fallback); if (font->destroy) font->destroy(font->user_data); hb_font_destroy(font->parent); hb_face_destroy(font->face); hb_font_funcs_destroy(font->klass); free(font); }
/*to unroll the original c++, could have used a macro ASSEMBLY:maybe worth to be unrolled to fine tuned assembly*/ static void hb_buffer_add_utf(hb_buffer_t * buffer, struct utf *utf, void *text, int text_length, unsigned item_offset, int item_length) { void *next; void *end; assert(buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL) return; if (text_length == -1) text_length = utf->len(text); if (item_length == -1) item_length = text_length - item_offset; ensure(buffer, buffer->len + item_length * utf->bytes_n / 4); /*If buffer is empty and pre-context provided, install it. This check is written this way, to make sure people can provide pre-context in one add_utf() call, then provide text in a follow-up call. See: https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13 */ if (!buffer->len && item_offset > 0) { void *prev; void *start; /*Add pre-context */ clear_context(buffer, 0); prev = utf->ptr_offset(text, item_offset); start = text; while (start < prev && buffer->context_len[0] < HB_BUFFER_CONTEXT_LENGTH) { hb_codepoint_t u; prev = utf->prev(prev, start, &u); buffer->context[0][buffer->context_len[0]++] = u; } } next = utf->ptr_offset(text, item_offset); end = utf->ptr_offset(next, item_length); while (next < end) { hb_codepoint_t u; void *old_next; old_next = next; next = utf->next(next, end, &u); add(buffer, u, utf->diff(old_next, text)); } /*Add post-context */ clear_context(buffer, 1); end = utf->ptr_offset(text, text_length); while (next < end && buffer->context_len[1] < HB_BUFFER_CONTEXT_LENGTH) { hb_codepoint_t u; next = utf->next(next, end, &u); buffer->context[1][buffer->context_len[1]++] = u; } buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE; }