< 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 >