diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2017-08-24 07:10:36 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2017-08-24 07:10:36 +0000 |
commit | f341d1fa059b0578ffa6ebb69c521cc69b6b1c6e (patch) | |
tree | 56b21bf3a912c35662bc6d8529c464d616d8fff5 /Build/source/libs/harfbuzz/harfbuzz-src/src | |
parent | 2b80175b17ec392bc974543c19e6ef33c3c08c15 (diff) |
harfbuzz 1.5.0
git-svn-id: svn://tug.org/texlive/trunk@45105 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src')
30 files changed, 489 insertions, 80 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh index bca308da2f5..37380b40d1c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh @@ -50,6 +50,7 @@ ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)); HB_MARK_AS_FLAG_T (hb_buffer_flags_t); HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t); +HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t); enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, @@ -57,6 +58,8 @@ enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, + HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u, + /* Reserved for complex shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u, @@ -232,25 +235,31 @@ struct hb_buffer_t { for (unsigned int j = 0; j < len; j++) info[j].mask |= mask; } - HB_INTERNAL void set_masks (hb_mask_t value, - hb_mask_t mask, - unsigned int cluster_start, - unsigned int cluster_end); + HB_INTERNAL void set_masks (hb_mask_t value, hb_mask_t mask, + unsigned int cluster_start, unsigned int cluster_end); - HB_INTERNAL void merge_clusters (unsigned int start, - unsigned int end) + inline void merge_clusters (unsigned int start, unsigned int end) { if (end - start < 2) return; merge_clusters_impl (start, end); } - HB_INTERNAL void merge_clusters_impl (unsigned int start, - unsigned int end); - HB_INTERNAL void merge_out_clusters (unsigned int start, - unsigned int end); + HB_INTERNAL void merge_clusters_impl (unsigned int start, unsigned int end); + HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); /* Merge clusters for deleting current glyph, and skip it. */ HB_INTERNAL void delete_glyph (void); + inline void unsafe_to_break (unsigned int start, + unsigned int end) + { + if (end - start < 2) + return; + unsafe_to_break_impl (start, end); + } + HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end); + HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end); + + /* Internal methods */ HB_INTERNAL bool enlarge (unsigned int size); @@ -282,9 +291,66 @@ struct hb_buffer_t { return ret; } HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0); + + static inline void + set_cluster (hb_glyph_info_t &info, unsigned int cluster, unsigned int mask = 0) + { + if (info.cluster != cluster) + { + if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + info.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + else + info.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + } + info.cluster = cluster; + } + + int + _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *info, + unsigned int start, unsigned int end, + unsigned int cluster) const + { + for (unsigned int i = start; i < end; i++) + cluster = MIN (cluster, info[i].cluster); + return cluster; + } + void + _unsafe_to_break_set_mask (hb_glyph_info_t *info, + unsigned int start, unsigned int end, + unsigned int cluster) + { + for (unsigned int i = start; i < end; i++) + if (cluster != info[i].cluster) + { + scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK; + info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + } + } }; +/* Loop over clusters. Duplicated in foreach_syllable(). */ +#define foreach_cluster(buffer, start, end) \ + for (unsigned int \ + _count = buffer->len, \ + start = 0, end = _count ? _next_cluster (buffer, 0) : 0; \ + start < _count; \ + start = end, end = _next_cluster (buffer, start)) + +static inline unsigned int +_next_cluster (hb_buffer_t *buffer, unsigned int start) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + unsigned int cluster = info[start].cluster; + while (++start < count && cluster == info[start].cluster) + ; + + return start; +} + + #define HB_BUFFER_XALLOCATE_VAR(b, func, var) \ b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \ sizeof (b->info[0].var)) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc index 85696c58962..517d746efd5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc @@ -145,10 +145,16 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", - pos[i].x_offset, pos[i].y_offset); - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", - pos[i].x_advance, pos[i].y_advance); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", + pos[i].x_offset, pos[i].y_offset)); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", + pos[i].x_advance, pos[i].y_advance)); + } + + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) + { + if (info[i].mask & HB_GLYPH_FLAG_DEFINED) + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) @@ -156,9 +162,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, hb_glyph_extents_t extents; hb_font_get_glyph_extents(font, info[i].codepoint, &extents); p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", - extents.x_bearing, extents.y_bearing)); + extents.x_bearing, extents.y_bearing)); p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", - extents.width, extents.height)); + extents.width, extents.height)); } *p++ = '}'; @@ -226,6 +232,12 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); } + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) + { + if (info[i].mask &HB_GLYPH_FLAG_DEFINED) + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED)); + } + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index 3777f7f8f3e..a45062aa5ae 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -267,7 +267,7 @@ hb_buffer_t::add (hb_codepoint_t codepoint, memset (glyph, 0, sizeof (*glyph)); glyph->codepoint = codepoint; - glyph->mask = 1; + glyph->mask = 0; glyph->cluster = cluster; len++; @@ -550,9 +550,12 @@ 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; + } - uint32_t cluster = info[start].cluster; + unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) cluster = MIN (cluster, info[i].cluster); @@ -568,10 +571,10 @@ hb_buffer_t::merge_clusters_impl (unsigned int 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; + set_cluster (out_info[i - 1], cluster); for (unsigned int i = start; i < end; i++) - info[i].cluster = cluster; + set_cluster (info[i], cluster); } void hb_buffer_t::merge_out_clusters (unsigned int start, @@ -583,7 +586,7 @@ hb_buffer_t::merge_out_clusters (unsigned int start, if (unlikely (end - start < 2)) return; - uint32_t cluster = out_info[start].cluster; + unsigned int cluster = out_info[start].cluster; for (unsigned int i = start + 1; i < end; i++) cluster = MIN (cluster, out_info[i].cluster); @@ -599,14 +602,16 @@ hb_buffer_t::merge_out_clusters (unsigned int start, /* 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; + set_cluster (info[i], cluster); for (unsigned int i = start; i < end; i++) - out_info[i].cluster = cluster; + 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) { @@ -619,9 +624,10 @@ hb_buffer_t::delete_glyph () /* 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--) - out_info[i - 1].cluster = cluster; + set_cluster (out_info[i - 1], cluster, mask); } goto done; } @@ -638,6 +644,32 @@ done: } 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 || @@ -1380,6 +1412,23 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, } /** + * 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. * @@ -1666,6 +1715,58 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, } +/** + * 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) @@ -1736,7 +1837,8 @@ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) { assert (buffer->have_positions); - assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); + 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); @@ -1775,6 +1877,94 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g } } + +/* + * Comparing buffers. + */ + +/** + * hb_buffer_diff: + * + * + * 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) + return HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH; + + hb_buffer_diff_flags_t result = HB_BUFFER_DIFF_FLAG_EQUAL; + + 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 (info[i].codepoint == dottedcircle_glyph) + result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; + else if (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 (ref_info->codepoint == dottedcircle_glyph) + result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; + else if (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. */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h index bf289c19b34..ffbf66ee12f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h @@ -63,7 +63,7 @@ HB_BEGIN_DECLS */ typedef struct hb_glyph_info_t { hb_codepoint_t codepoint; - hb_mask_t mask; + hb_mask_t mask; /* Holds hb_glyph_flags_t after hb_shape(), plus other things. */ uint32_t cluster; /*< private >*/ @@ -71,6 +71,19 @@ typedef struct hb_glyph_info_t { hb_var_int_t var2; } hb_glyph_info_t; +typedef enum { /*< flags >*/ + HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, + + HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */ +} hb_glyph_flags_t; + +HB_EXTERN hb_glyph_flags_t +hb_glyph_info_get_glyph_flags (const hb_glyph_info_t *info); + +#define hb_glyph_info_get_glyph_flags(info) \ + ((hb_glyph_flags_t) ((unsigned int) (info)->mask & HB_GLYPH_FLAG_DEFINED)) + + /** * hb_glyph_position_t: * @x_advance: how much the line advances after drawing this glyph when setting @@ -163,6 +176,7 @@ HB_EXTERN void * hb_buffer_get_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key); + /** * hb_buffer_content_type_t: * @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer. @@ -359,6 +373,11 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, unsigned int item_offset, int item_length); +HB_EXTERN void +hb_buffer_append (hb_buffer_t *buffer, + hb_buffer_t *source, + unsigned int start, + unsigned int end); HB_EXTERN hb_bool_t hb_buffer_set_length (hb_buffer_t *buffer, @@ -403,7 +422,8 @@ typedef enum { /*< flags >*/ HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u, HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u, HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u, - HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u + HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u, + HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u } hb_buffer_serialize_flags_t; /** @@ -453,6 +473,45 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, /* + * Compare buffers + */ + +typedef enum { /*< flags >*/ + HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000, + + /* Buffers with different content_type cannot be meaningfully compared + * in any further detail. */ + HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH = 0X0001, + + /* For buffers with differing length, the per-glyph comparison is not + * attempted, though we do still scan reference for dottedcircle / .notdef + * glyphs. */ + HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH = 0X0002, + + /* We want to know if dottedcircle / .notdef glyphs are present in the + * reference, as we may not care so much about other differences in this + * case. */ + HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT = 0x0004, + HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT = 0x0008, + + /* If the buffers have the same length, we compare them glyph-by-glyph + * and report which aspect(s) of the glyph info/position are different. */ + HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH = 0x0010, + HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH = 0x0020, + HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH = 0x0040, + HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH = 0x0080 + +} hb_buffer_diff_flags_t; + +/* Compare the contents of two buffers, report types of differences. */ +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); + + +/* * Debugging. */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc index e237335e7d3..ba96d3994ee 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc @@ -1180,6 +1180,9 @@ resize_and_retry: pos->x_advance = info->mask; pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; + + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + info++, pos++; } else @@ -1188,6 +1191,9 @@ resize_and_retry: pos->y_advance = info->mask; pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; + + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + info++, pos++; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc index ab07d8a3098..14df8221b1d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc @@ -880,6 +880,8 @@ retry_getglyphs: pos->x_offset = x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32); pos->y_offset = y_mult * info->var2.i32; + + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; } if (isRightToLeft) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-private.hh index eb0e850aa87..72f08a599ad 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-private.hh @@ -55,10 +55,10 @@ struct hb_face_t { mutable unsigned int num_glyphs; /* Number of glyphs. */ enum dirty_t { - NOTHING = 0x0000, - INDEX = 0x0001, - UPEM = 0x0002, - NUM_GLYPHS = 0x0004, + DIRTY_NOTHING = 0x0000, + DIRTY_INDEX = 0x0001, + DIRTY_UPEM = 0x0002, + DIRTY_NUM_GLYPHS = 0x0004, } dirty; struct hb_shaper_data_t shaper_data; /* Various shaper data. */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index 1800c995a46..22998f00586 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -51,7 +51,7 @@ const hb_face_t _hb_face_nil = { 1000, /* upem */ 0, /* num_glyphs */ - hb_face_t::NOTHING, /* dirty */ + hb_face_t::DIRTY_NOTHING, /* dirty */ { #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, @@ -370,7 +370,7 @@ hb_face_set_index (hb_face_t *face, if (face->index == index) return; - face->dirty |= face->INDEX; + face->dirty |= face->DIRTY_INDEX; face->index = index; } @@ -410,7 +410,7 @@ hb_face_set_upem (hb_face_t *face, if (face->upem == upem) return; - face->dirty |= face->UPEM; + face->dirty |= face->DIRTY_UPEM; face->upem = upem; } @@ -459,7 +459,7 @@ hb_face_set_glyph_count (hb_face_t *face, if (face->num_glyphs == glyph_count) return; - face->dirty |= face->NUM_GLYPHS; + face->dirty |= face->DIRTY_NUM_GLYPHS; face->num_glyphs = glyph_count; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font-private.hh index fbb16a0b72f..ed9f2c54adc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font-private.hh @@ -117,13 +117,13 @@ struct hb_font_t { hb_destroy_func_t destroy; enum dirty_t { - NOTHING = 0x0000, - FACE = 0x0001, - PARENT = 0x0002, - FUNCS = 0x0004, - SCALE = 0x0008, - PPEM = 0x0010, - VARIATIONS = 0x0020, + DIRTY_NOTHING = 0x0000, + DIRTY_FACE = 0x0001, + DIRTY_PARENT = 0x0002, + DIRTY_FUNCS = 0x0004, + DIRTY_SCALE = 0x0008, + DIRTY_PPEM = 0x0010, + DIRTY_VARIATIONS = 0x0020, } dirty; struct hb_shaper_data_t shaper_data; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index e900bd3f65a..a684c234d0a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc @@ -1196,7 +1196,7 @@ hb_font_get_empty (void) NULL, /* user_data */ NULL, /* destroy */ - hb_font_t::NOTHING, /* dirty */ + hb_font_t::DIRTY_NOTHING, /* dirty */ { #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, @@ -1353,7 +1353,7 @@ hb_font_set_parent (hb_font_t *font, if (parent == font->parent) return; - font->dirty |= font->PARENT; + font->dirty |= font->DIRTY_PARENT; hb_font_t *old = font->parent; @@ -1400,7 +1400,7 @@ hb_font_set_face (hb_font_t *font, if (font->face == face) return; - font->dirty |= font->FACE; + font->dirty |= font->DIRTY_FACE; hb_face_t *old = font->face; @@ -1455,7 +1455,7 @@ hb_font_set_funcs (hb_font_t *font, if (!klass) klass = hb_font_funcs_get_empty (); - font->dirty |= font->FUNCS; + font->dirty |= font->DIRTY_FUNCS; hb_font_funcs_reference (klass); hb_font_funcs_destroy (font->klass); @@ -1515,7 +1515,7 @@ hb_font_set_scale (hb_font_t *font, if (font->x_scale == x_scale && font->y_scale == y_scale) return; - font->dirty |= font->SCALE; + font->dirty |= font->DIRTY_SCALE; font->x_scale = x_scale; font->y_scale = y_scale; @@ -1561,7 +1561,7 @@ hb_font_set_ppem (hb_font_t *font, if (font->x_ppem == x_ppem && font->y_ppem == y_ppem) return; - font->dirty |= font->PPEM; + font->dirty |= font->DIRTY_PPEM; font->x_ppem = x_ppem; font->y_ppem = y_ppem; @@ -1603,7 +1603,7 @@ _hb_font_adopt_var_coords_normalized (hb_font_t *font, return; } - font->dirty |= font->VARIATIONS; + font->dirty |= font->DIRTY_VARIATIONS; free (font->coords); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index 48d6a0efb3f..492992ee425 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -493,7 +493,7 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) return NULL; buffer = (FT_Byte *) malloc (length); - if (buffer == NULL) + if (!buffer) return NULL; error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length); @@ -521,7 +521,7 @@ hb_ft_face_create (FT_Face ft_face, { hb_face_t *face; - if (ft_face->stream->read == NULL) { + if (!ft_face->stream->read) { hb_blob_t *blob; blob = hb_blob_create ((const char *) ft_face->stream->base, @@ -632,9 +632,9 @@ hb_ft_font_create (FT_Face ft_face, hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis); } - free (coords); - free (ft_coords); } + free (coords); + free (ft_coords); free (mm_var); } #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc index c9799e9da00..9e0761e63d1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc @@ -355,6 +355,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j]; info->codepoint = gids[clusters[i].base_glyph + j]; info->cluster = clusters[i].cluster; + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; info->var1.i32 = clusters[i].advance; // all glyphs in the cluster get the same advance } } @@ -365,7 +366,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, float yscale = (float) font->y_scale / upem; yscale *= yscale / xscale; /* Positioning. */ - int currclus = -1; + unsigned int currclus = (unsigned int) -1; const hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL); if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index 2ce29cdffbf..d3251caf724 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc @@ -224,7 +224,7 @@ struct hb_ot_face_cbdt_accelerator_t const OT::CBDT *cbdt; unsigned int cbdt_len; - float upem; + unsigned int upem; inline void init (hb_face_t *face) { @@ -254,11 +254,11 @@ struct hb_ot_face_cbdt_accelerator_t { unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ - if (cblc == NULL) + if (!cblc) return false; // Not a color bitmap font. const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); - if (subtable_record == NULL) + if (!subtable_record || !x_ppem || !y_ppem) return false; if (subtable_record->get_extents (extents)) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh index 180e5f086eb..578d850c184 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh @@ -941,7 +941,7 @@ struct Coverage } struct Iter { - Iter (void) : format (0) {}; + Iter (void) : format (0), u () {}; inline void init (const Coverage &c_) { format = c_.u.format; switch (format) { @@ -982,8 +982,8 @@ struct Coverage private: unsigned int format; union { + CoverageFormat2::Iter format2; /* Put this one first since it's larger; helps shut up compiler. */ CoverageFormat1::Iter format1; - CoverageFormat2::Iter format2; } u; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh index 952fd60fec5..738ca8c444e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh @@ -432,6 +432,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde hb_position_t mark_x, mark_y, base_x, base_y; + buffer->unsafe_to_break (glyph_pos, buffer->idx); mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y); glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y); @@ -643,6 +644,7 @@ struct PairSet min = mid + 1; else { + buffer->unsafe_to_break (buffer->idx, pos + 1); valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); if (len2) @@ -790,6 +792,7 @@ struct PairPosFormat2 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); + buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; valueFormat1.apply_value (c, this, v, buffer->cur_pos()); valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); @@ -929,6 +932,7 @@ struct CursivePosFormat1 unsigned int i = buffer->idx; unsigned int j = skippy_iter.idx; + buffer->unsafe_to_break (i, j); hb_position_t entry_x, entry_y, exit_x, exit_y; (this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); (this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh index 66fcb3f3af3..85be7e7ea98 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh @@ -1014,14 +1014,17 @@ struct ReverseChainSingleSubstFormat1 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); + unsigned int start_index = 0, end_index = 0; if (match_backtrack (c, backtrack.len, (USHORT *) backtrack.array, - match_coverage, this) && + match_coverage, this, + &start_index) && match_lookahead (c, lookahead.len, (USHORT *) lookahead.array, match_coverage, this, - 1)) + 1, &end_index)) { + c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); c->replace_glyph_inplace (substitute[index]); /* Note: We DON'T decrease buffer->idx. The main loop does it * for us. This is useful for preventing surprises if someone diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh index 2235d3a0ad7..472628a3937 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh @@ -891,7 +891,8 @@ static inline bool match_backtrack (hb_apply_context_t *c, unsigned int count, const USHORT backtrack[], match_func_t match_func, - const void *match_data) + const void *match_data, + unsigned int *match_start) { TRACE_APPLY (NULL); @@ -903,6 +904,8 @@ static inline bool match_backtrack (hb_apply_context_t *c, if (!skippy_iter.prev ()) return_trace (false); + *match_start = skippy_iter.idx; + return_trace (true); } @@ -911,7 +914,8 @@ static inline bool match_lookahead (hb_apply_context_t *c, const USHORT lookahead[], match_func_t match_func, const void *match_data, - unsigned int offset) + unsigned int offset, + unsigned int *end_index) { TRACE_APPLY (NULL); @@ -923,6 +927,8 @@ static inline bool match_lookahead (hb_apply_context_t *c, if (!skippy_iter.next ()) return_trace (false); + *end_index = skippy_iter.idx + 1; + return_trace (true); } @@ -1145,10 +1151,11 @@ static inline bool context_apply_lookup (hb_apply_context_t *c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, &match_length, match_positions) - && apply_lookup (c, + && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length), + apply_lookup (c, inputCount, match_positions, lookupCount, lookupRecord, - match_length); + match_length)); } struct Rule @@ -1666,7 +1673,7 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, const LookupRecord lookupRecord[], ChainContextApplyLookupContext &lookup_context) { - unsigned int match_length = 0; + unsigned int start_index = 0, match_length = 0, end_index = 0; unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, @@ -1674,15 +1681,17 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, &match_length, match_positions) && match_backtrack (c, backtrackCount, backtrack, - lookup_context.funcs.match, lookup_context.match_data[0]) + lookup_context.funcs.match, lookup_context.match_data[0], + &start_index) && match_lookahead (c, lookaheadCount, lookahead, lookup_context.funcs.match, lookup_context.match_data[2], - match_length) - && apply_lookup (c, + match_length, &end_index) + && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index), + apply_lookup (c, inputCount, match_positions, lookupCount, lookupRecord, - match_length); + match_length)); } struct ChainRule diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh index b476339e1c0..d4ac60b06fe 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh @@ -197,8 +197,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout); #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ -/* loop over syllables */ - +/* Loop over syllables. Based on foreach_cluster(). */ #define foreach_syllable(buffer, start, end) \ for (unsigned int \ _count = buffer->len, \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc index 014e4430a6c..5764a110478 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc @@ -138,7 +138,11 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, const int *coords, unsigned int num_coords) { - m.global_mask = 1; + ASSERT_STATIC (!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))); + unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1; + unsigned int global_bit_shift = _hb_popcount32 (HB_GLYPH_FLAG_DEFINED); + + m.global_mask = global_bit_mask; unsigned int required_feature_index[2]; hb_tag_t required_feature_tag[2]; @@ -190,7 +194,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, /* Allocate bits now */ - unsigned int next_bit = 1; + unsigned int next_bit = global_bit_shift + 1; + for (unsigned int i = 0; i < feature_infos.len; i++) { const feature_info_t *info = &feature_infos[i]; @@ -249,8 +254,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, map->auto_zwj = !(info->flags & F_MANUAL_ZWJ); if ((info->flags & F_GLOBAL) && info->max_value == 1) { /* Uses the global bit */ - map->shift = 0; - map->mask = 1; + map->shift = global_bit_shift; + map->mask = global_bit_mask; } else { map->shift = next_bit; map->mask = (1u << (next_bit + bits_needed)) - (1u << next_bit); @@ -287,7 +292,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, add_lookups (m, face, table_index, required_feature_index[table_index], variations_index, - 1 /* mask */); + global_bit_mask); for (unsigned i = 0; i < m.features.len; i++) if (m.features[i].stage[table_index] == stage) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc index 5dbbcd9af99..ed7b3f2dd9b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc @@ -321,7 +321,10 @@ arabic_joining (hb_buffer_t *buffer) const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; if (entry->prev_action != NONE && prev != (unsigned int) -1) + { info[prev].arabic_shaping_action() = entry->prev_action; + buffer->unsafe_to_break (prev, i + 1); + } info[i].arabic_shaping_action() = entry->curr_action; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc index 23e07e59f39..0e74802ee52 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc @@ -202,6 +202,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, if (start < end && end == buffer->out_len) { /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */ + buffer->unsafe_to_break_from_outbuffer (start, buffer->idx); buffer->next_glyph (); if (!is_zero_width_char (font, u)) { @@ -258,6 +259,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, else t = 0; /* The next character was not a trailing jamo. */ } + buffer->unsafe_to_break (buffer->idx, buffer->idx + (t ? 3 : 2)); /* We've got a syllable <L,V,T?>; see if it can potentially be composed. */ if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t))) @@ -322,6 +324,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, end = start + 1; continue; } + else + buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */ } /* Otherwise, decompose if font doesn't support <LV> or <LVT>, @@ -368,6 +372,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, buffer->merge_out_clusters (start, end); continue; } + else if ((!tindex && buffer->idx + 1 < count && isT (buffer->cur(+1).codepoint))) + buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */ } if (has_glyph) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc index 02aab082cd3..3cd8fd6c3d7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc @@ -624,6 +624,8 @@ setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer) { find_syllables (buffer); + foreach_syllable (buffer, start, end) + buffer->unsafe_to_break (start, end); } static int diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc index 4e912c361fc..ebd2b40966f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc @@ -297,6 +297,8 @@ setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer) { find_syllables (buffer); + foreach_syllable (buffer, start, end) + buffer->unsafe_to_break (start, end); } static int diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc index e75b3537927..924247f1742 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc @@ -244,6 +244,7 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED, /* At least one of the above/below actions is NOP. */ thai_action_t action = above_edge.action != NOP ? above_edge.action : below_edge.action; + buffer->unsafe_to_break (base, i); if (action == RD) info[base].codepoint = thai_pua_shape (info[base].codepoint, action, font); else diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc index af6870686cd..a5ab0ab2a2d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc @@ -354,6 +354,8 @@ setup_syllables (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { find_syllables (buffer); + foreach_syllable (buffer, start, end) + buffer->unsafe_to_break (start, end); setup_rphf_mask (plan, buffer); setup_topographical_masks (plan, buffer); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc index ea8312b223b..4da53f4cc7d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc @@ -307,6 +307,9 @@ position_around_base (const hb_ot_shape_plan_t *plan, unsigned int end) { hb_direction_t horiz_dir = HB_DIRECTION_INVALID; + + buffer->unsafe_to_break (base, end); + hb_glyph_extents_t base_extents; if (!font->get_glyph_extents (buffer->info[base].codepoint, &base_extents)) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 29f5e58e519..bc5366969be 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -509,9 +509,10 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) /* 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--) - info[k - 1].cluster = cluster; + buffer->set_cluster (info[k - 1], cluster, mask); } continue; } @@ -782,6 +783,31 @@ hb_ot_position (hb_ot_shape_context_t *c) _hb_buffer_deallocate_gsubgpos_vars (c->buffer); } +static inline void +hb_propagate_flags (hb_buffer_t *buffer) +{ + /* Propagate cluster-level glyph flags to be the same on all cluster glyphs. + * Simplifies using them. */ + + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK)) + return; + + hb_glyph_info_t *info = buffer->info; + + foreach_cluster (buffer, start, end) + { + unsigned int mask = 0; + for (unsigned int i = start; i < end; i++) + if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + { + mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + break; + } + if (mask) + for (unsigned int i = start; i < end; i++) + info[i].mask |= mask; + } +} /* Pull it all together! */ @@ -825,6 +851,8 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) if (c->plan->shaper->postprocess_glyphs) c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); + hb_propagate_flags (c->buffer); + _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc index 61737669c08..3abf555c5f0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc @@ -160,7 +160,7 @@ hb_shape_plan_create2 (hb_face_t *face, assert (props->direction != HB_DIRECTION_INVALID); hb_face_make_immutable (face); - shape_plan->default_shaper_list = shaper_list == NULL; + shape_plan->default_shaper_list = !shaper_list; shape_plan->face_unsafe = face; shape_plan->props = *props; shape_plan->num_user_features = num_user_features; @@ -423,7 +423,7 @@ hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && hb_shape_plan_user_features_match (shape_plan, proposal) && hb_shape_plan_coords_match (shape_plan, proposal) && - ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) || + ((shape_plan->default_shaper_list && !proposal->shaper_list) || (shape_plan->shaper_func == proposal->shaper_func)); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh index aa86a72c437..34513e1324c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh @@ -105,6 +105,10 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE inline unsigned int modified_combining_class (hb_codepoint_t unicode) { + /* XXX This hack belongs to the Arabic shaper: + * Put HAMZA ABOVE in the same class as SHADDA. */ + if (unlikely (unicode == 0x0654u)) unicode = 0x0651u; + /* XXX This hack belongs to the Myanmar shaper. */ if (unlikely (unicode == 0x1037u)) unicode = 0x103Au; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc index 58f983dbec1..d25accd56b1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc @@ -1024,6 +1024,8 @@ retry: pos->x_advance = x_mult * (int32_t) info->mask; pos->x_offset = x_mult * (backward ? -info->var1.i32 : info->var1.i32); pos->y_offset = y_mult * info->var2.i32; + + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; } if (backward) |