< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc

Print this page

        

*** 29,42 **** #include "hb-buffer-private.hh" #include "hb-utf-private.hh" - #ifndef HB_DEBUG_BUFFER - #define HB_DEBUG_BUFFER (HB_DEBUG+0) - #endif - /** * SECTION: hb-buffer * @title: Buffers * @short_description: Input and output buffers * @include: hb.h --- 29,38 ----
*** 122,142 **** in_error = true; return false; } unsigned int new_allocated = allocated; ! hb_glyph_position_t *new_pos = NULL; ! hb_glyph_info_t *new_info = NULL; bool separate_out = out_info != info; if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0])))) goto done; while (size >= new_allocated) new_allocated += (new_allocated >> 1) + 32; ! ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0])); if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0])))) goto done; new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0])); new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0])); --- 118,138 ---- in_error = true; return false; } unsigned int new_allocated = allocated; ! hb_glyph_position_t *new_pos = nullptr; ! hb_glyph_info_t *new_info = nullptr; bool separate_out = out_info != info; if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0])))) goto done; while (size >= new_allocated) new_allocated += (new_allocated >> 1) + 32; ! static_assert ((sizeof (info[0]) == sizeof (pos[0])), ""); if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0])))) goto done; new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0])); new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
*** 265,275 **** glyph = &info[len]; memset (glyph, 0, sizeof (*glyph)); glyph->codepoint = codepoint; ! glyph->mask = 1; glyph->cluster = cluster; len++; } --- 261,271 ---- glyph = &info[len]; memset (glyph, 0, sizeof (*glyph)); glyph->codepoint = codepoint; ! glyph->mask = 0; glyph->cluster = cluster; len++; }
*** 548,563 **** void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) return; unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) ! cluster = MIN (cluster, info[i].cluster); /* Extend end */ while (end < len && info[end - 1].cluster == info[end].cluster) end++; --- 544,562 ---- void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + { + unsafe_to_break (start, end); return; + } unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) ! cluster = MIN<unsigned int> (cluster, info[i].cluster); /* Extend end */ while (end < len && info[end - 1].cluster == info[end].cluster) end++;
*** 566,579 **** start--; /* If we hit the start of buffer, continue in out-buffer. */ if (idx == start) for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) ! out_info[i - 1].cluster = cluster; for (unsigned int i = start; i < end; i++) ! info[i].cluster = cluster; } void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { --- 565,578 ---- start--; /* If we hit the start of buffer, continue in out-buffer. */ if (idx == start) for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) ! set_cluster (out_info[i - 1], cluster); for (unsigned int i = start; i < end; i++) ! set_cluster (info[i], cluster); } void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) {
*** 584,594 **** return; unsigned int cluster = out_info[start].cluster; for (unsigned int i = start + 1; i < end; i++) ! cluster = MIN (cluster, out_info[i].cluster); /* Extend start */ while (start && out_info[start - 1].cluster == out_info[start].cluster) start--; --- 583,593 ---- return; unsigned int cluster = out_info[start].cluster; for (unsigned int i = start + 1; i < end; i++) ! cluster = MIN<unsigned int> (cluster, out_info[i].cluster); /* Extend start */ while (start && out_info[start - 1].cluster == out_info[start].cluster) start--;
*** 597,614 **** end++; /* If we hit the end of out-buffer, continue in buffer. */ if (end == out_len) for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) ! info[i].cluster = cluster; for (unsigned int i = start; i < end; i++) ! out_info[i].cluster = cluster; } void hb_buffer_t::delete_glyph () { unsigned int cluster = info[idx].cluster; if (idx + 1 < len && cluster == info[idx + 1].cluster) { /* Cluster survives; do nothing. */ goto done; --- 596,615 ---- end++; /* If we hit the end of out-buffer, continue in buffer. */ if (end == out_len) for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) ! set_cluster (info[i], cluster); for (unsigned int i = start; i < end; i++) ! set_cluster (out_info[i], cluster); } void hb_buffer_t::delete_glyph () { + /* The logic here is duplicated in hb_ot_hide_default_ignorables(). */ + unsigned int cluster = info[idx].cluster; if (idx + 1 < len && cluster == info[idx + 1].cluster) { /* Cluster survives; do nothing. */ goto done;
*** 617,629 **** if (out_len) { /* Merge cluster backward. */ if (cluster < out_info[out_len - 1].cluster) { unsigned int old_cluster = out_info[out_len - 1].cluster; for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--) ! out_info[i - 1].cluster = cluster; } goto done; } if (idx + 1 < len) --- 618,631 ---- if (out_len) { /* Merge cluster backward. */ if (cluster < out_info[out_len - 1].cluster) { + unsigned int mask = info[idx].mask; unsigned int old_cluster = out_info[out_len - 1].cluster; for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--) ! set_cluster (out_info[i - 1], cluster, mask); } goto done; } if (idx + 1 < len)
*** 636,645 **** --- 638,673 ---- done: skip_glyph (); } void + hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end) + { + unsigned int cluster = (unsigned int) -1; + cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster); + _unsafe_to_break_set_mask (info, start, end, cluster); + } + void + hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end) + { + if (!have_output) + { + unsafe_to_break_impl (start, end); + return; + } + + assert (start <= out_len); + assert (idx <= end); + + unsigned int cluster = (unsigned int) -1; + cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster); + cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster); + _unsafe_to_break_set_mask (out_info, start, out_len, cluster); + _unsafe_to_break_set_mask (info, idx, end, cluster); + } + + void hb_buffer_t::guess_segment_properties (void) { assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
*** 1378,1387 **** --- 1406,1432 ---- return (hb_glyph_position_t *) buffer->pos; } /** + * hb_glyph_info_get_glyph_flags: + * @info: a #hb_glyph_info_t. + * + * Returns glyph flags encoded within a #hb_glyph_info_t. + * + * Return value: + * The #hb_glyph_flags_t encoded within @info. + * + * Since: 1.5.0 + **/ + hb_glyph_flags_t + (hb_glyph_info_get_glyph_flags) (const hb_glyph_info_t *info) + { + return hb_glyph_info_get_glyph_flags (info); + } + + /** * hb_buffer_reverse: * @buffer: an #hb_buffer_t. * * Reverses buffer contents. *
*** 1664,1673 **** --- 1709,1770 ---- { hb_buffer_add_utf<hb_utf32_t<false> > (buffer, text, text_length, item_offset, item_length); } + /** + * hb_buffer_append: + * @buffer: an #hb_buffer_t. + * @source: source #hb_buffer_t. + * @start: start index into source buffer to copy. Use 0 to copy from start of buffer. + * @end: end index into source buffer to copy. Use (unsigned int) -1 to copy to end of buffer. + * + * Append (part of) contents of another buffer to this buffer. + * + * Since: 1.5.0 + **/ + HB_EXTERN void + hb_buffer_append (hb_buffer_t *buffer, + hb_buffer_t *source, + unsigned int start, + unsigned int end) + { + assert (!buffer->have_output && !source->have_output); + assert (buffer->have_positions == source->have_positions || + !buffer->len || !source->len); + assert (buffer->content_type == source->content_type || + !buffer->len || !source->len); + + if (end > source->len) + end = source->len; + if (start > end) + start = end; + if (start == end) + return; + + if (!buffer->len) + buffer->content_type = source->content_type; + if (!buffer->have_positions && source->have_positions) + buffer->clear_positions (); + + if (buffer->len + (end - start) < buffer->len) /* Overflows. */ + { + buffer->in_error = true; + return; + } + + unsigned int orig_len = buffer->len; + hb_buffer_set_length (buffer, buffer->len + (end - start)); + if (buffer->in_error) + return; + + memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); + if (buffer->have_positions) + memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); + } + + static int compare_info_codepoint (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) { return (int) pb->codepoint - (int) pa->codepoint;
*** 1734,1744 **** **/ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) { assert (buffer->have_positions); ! assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); unsigned int count = buffer->len; if (unlikely (!count)) return; --- 1831,1842 ---- **/ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) { assert (buffer->have_positions); ! assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS || ! (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); unsigned int count = buffer->len; if (unlikely (!count)) return;
*** 1773,1782 **** --- 1871,1972 ---- info[j] = t; } } } + + /* + * Comparing buffers. + */ + + /** + * hb_buffer_diff: + * + * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT + * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most + * callers if just comparing two buffers is needed. + * + * Since: 1.5.0 + **/ + hb_buffer_diff_flags_t + hb_buffer_diff (hb_buffer_t *buffer, + hb_buffer_t *reference, + hb_codepoint_t dottedcircle_glyph, + unsigned int position_fuzz) + { + if (buffer->content_type != reference->content_type && buffer->len && reference->len) + return HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH; + + hb_buffer_diff_flags_t result = HB_BUFFER_DIFF_FLAG_EQUAL; + bool contains = dottedcircle_glyph != (hb_codepoint_t) -1; + + unsigned int count = reference->len; + + if (buffer->len != count) + { + /* + * we can't compare glyph-by-glyph, but we do want to know if there + * are .notdef or dottedcircle glyphs present in the reference buffer + */ + const hb_glyph_info_t *info = reference->info; + unsigned int i; + for (i = 0; i < count; i++) + { + if (contains && info[i].codepoint == dottedcircle_glyph) + result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; + if (contains && info[i].codepoint == 0) + result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT; + } + result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH; + return hb_buffer_diff_flags_t (result); + } + + if (!count) + return hb_buffer_diff_flags_t (result); + + const hb_glyph_info_t *buf_info = buffer->info; + const hb_glyph_info_t *ref_info = reference->info; + for (unsigned int i = 0; i < count; i++) + { + if (buf_info->codepoint != ref_info->codepoint) + result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH; + if (buf_info->cluster != ref_info->cluster) + result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH; + if ((buf_info->mask & HB_GLYPH_FLAG_DEFINED) != (ref_info->mask & HB_GLYPH_FLAG_DEFINED)) + result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH; + if (contains && ref_info->codepoint == dottedcircle_glyph) + result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; + if (contains && ref_info->codepoint == 0) + result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT; + buf_info++; + ref_info++; + } + + if (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) + { + assert (buffer->have_positions); + const hb_glyph_position_t *buf_pos = buffer->pos; + const hb_glyph_position_t *ref_pos = reference->pos; + for (unsigned int i = 0; i < count; i++) + { + if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz || + (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz || + (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz || + (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz) + { + result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH; + break; + } + buf_pos++; + ref_pos++; + } + } + + return result; + } + + /* * Debugging. */ /**
*** 1801,1813 **** if (func) { buffer->message_func = func; buffer->message_data = user_data; buffer->message_destroy = destroy; } else { ! buffer->message_func = NULL; ! buffer->message_data = NULL; ! buffer->message_destroy = NULL; } } bool hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap) --- 1991,2003 ---- if (func) { buffer->message_func = func; buffer->message_data = user_data; buffer->message_destroy = destroy; } else { ! buffer->message_func = nullptr; ! buffer->message_data = nullptr; ! buffer->message_destroy = nullptr; } } bool hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
< prev index next >