summaryrefslogtreecommitdiff
path: root/thirdparty/harfbuzz/src/hb-buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/harfbuzz/src/hb-buffer.cc')
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.cc99
1 files changed, 77 insertions, 22 deletions
diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc
index 57a5ae03ed..4b6c2d9eaa 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer.cc
@@ -172,12 +172,13 @@ hb_buffer_t::enlarge (unsigned int size)
while (size >= new_allocated)
new_allocated += (new_allocated >> 1) + 32;
- static_assert ((sizeof (info[0]) == sizeof (pos[0])), "");
- if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]))))
+ unsigned new_bytes;
+ if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes)))
goto done;
- new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0]));
- new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0]));
+ static_assert (sizeof (info[0]) == sizeof (pos[0]), "");
+ new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes);
+ new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes);
done:
if (unlikely (!new_pos || !new_info))
@@ -208,7 +209,7 @@ hb_buffer_t::make_room_for (unsigned int num_in,
assert (have_output);
out_info = (hb_glyph_info_t *) pos;
- memcpy (out_info, info, out_len * sizeof (out_info[0]));
+ hb_memcpy (out_info, info, out_len * sizeof (out_info[0]));
}
return true;
@@ -229,7 +230,7 @@ hb_buffer_t::shift_forward (unsigned int count)
* Ideally, we should at least set Default_Ignorable bits on
* these, as well as consistent cluster values. But the former
* is layering violation... */
- memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
+ hb_memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
}
len += count;
idx += count;
@@ -298,8 +299,8 @@ hb_buffer_t::clear ()
out_len = 0;
out_info = info;
- memset (context, 0, sizeof context);
- memset (context_len, 0, sizeof context_len);
+ hb_memset (context, 0, sizeof context);
+ hb_memset (context_len, 0, sizeof context_len);
deallocate_var_all ();
serial = 0;
@@ -313,15 +314,14 @@ hb_buffer_t::enter ()
serial = 0;
shaping_failed = false;
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
- if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR)))
+ unsigned mul;
+ if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul)))
{
- max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR,
- (unsigned) HB_BUFFER_MAX_LEN_MIN);
+ max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN);
}
- if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR)))
+ if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR, &mul)))
{
- max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR,
- (unsigned) HB_BUFFER_MAX_OPS_MIN);
+ max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN);
}
}
void
@@ -345,7 +345,7 @@ hb_buffer_t::add (hb_codepoint_t codepoint,
glyph = &info[len];
- memset (glyph, 0, sizeof (*glyph));
+ hb_memset (glyph, 0, sizeof (*glyph));
glyph->codepoint = codepoint;
glyph->mask = 0;
glyph->cluster = cluster;
@@ -606,6 +606,53 @@ done:
}
void
+hb_buffer_t::delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info))
+{
+ /* Merge clusters and delete filtered glyphs.
+ * NOTE! We can't use out-buffer as we have positioning data. */
+ unsigned int j = 0;
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (filter (&info[i]))
+ {
+ /* Merge clusters.
+ * Same logic as delete_glyph(), but for in-place removal. */
+
+ unsigned int cluster = info[i].cluster;
+ if (i + 1 < count && cluster == info[i + 1].cluster)
+ continue; /* Cluster survives; do nothing. */
+
+ if (j)
+ {
+ /* Merge cluster backward. */
+ if (cluster < info[j - 1].cluster)
+ {
+ unsigned int mask = info[i].mask;
+ unsigned int old_cluster = info[j - 1].cluster;
+ for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
+ set_cluster (info[k - 1], cluster, mask);
+ }
+ continue;
+ }
+
+ if (i + 1 < count)
+ merge_clusters (i, i + 2); /* Merge cluster forward. */
+
+ continue;
+ }
+
+ if (j != i)
+ {
+ info[j] = info[i];
+ pos[j] = pos[i];
+ }
+ j++;
+ }
+ len = j;
+}
+
+void
hb_buffer_t::guess_segment_properties ()
{
assert_unicode ();
@@ -933,7 +980,6 @@ hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer)
void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction)
-
{
if (unlikely (hb_object_is_immutable (buffer)))
return;
@@ -1385,9 +1431,9 @@ hb_buffer_set_length (hb_buffer_t *buffer,
/* Wipe the new space */
if (length > buffer->len) {
- memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
+ hb_memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
if (buffer->have_positions)
- memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
+ hb_memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
}
buffer->len = length;
@@ -1795,7 +1841,9 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer,
* marks at stat of run.
*
* This function does not check the validity of @text, it is up to the caller
- * to ensure it contains a valid Unicode code points.
+ * to ensure it contains a valid Unicode scalar values. In contrast,
+ * hb_buffer_add_utf32() can be used that takes similar input but performs
+ * sanity-check on the input.
*
* Since: 0.9.31
**/
@@ -1858,9 +1906,9 @@ hb_buffer_append (hb_buffer_t *buffer,
hb_segment_properties_overlay (&buffer->props, &source->props);
- memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
+ hb_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]));
+ hb_memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
if (source->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE)
{
@@ -2048,7 +2096,7 @@ hb_buffer_diff (hb_buffer_t *buffer,
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 & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED))
+ if ((buf_info->mask ^ 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;
@@ -2103,6 +2151,13 @@ hb_buffer_set_message_func (hb_buffer_t *buffer,
hb_buffer_message_func_t func,
void *user_data, hb_destroy_func_t destroy)
{
+ if (unlikely (hb_object_is_immutable (buffer)))
+ {
+ if (destroy)
+ destroy (user_data);
+ return;
+ }
+
if (buffer->message_destroy)
buffer->message_destroy (buffer->message_data);