Implement more granular cluster-merging TODO: Documentation. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=71445
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 32d5a5f..3a2db48 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh
@@ -50,6 +50,7 @@ /* Information about how the text in the buffer should be treated */ hb_unicode_funcs_t *unicode; /* Unicode functions */ hb_buffer_flags_t flags; /* BOT / EOT / etc. */ + hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ /* Buffer contents */
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 0a11fec..03fe8e1 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc
@@ -507,9 +507,8 @@ hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + return; unsigned int cluster = info[start].cluster; @@ -536,9 +535,8 @@ hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + return; if (unlikely (end - start < 2)) return; @@ -738,6 +736,7 @@ const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), HB_BUFFER_FLAG_DEFAULT, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, @@ -1083,6 +1082,41 @@ return buffer->flags; } +/** + * hb_buffer_set_cluster_level: + * @buffer: a buffer. + * @cluster_level: + * + * + * + * Since: 0.9.42 + **/ +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->cluster_level = cluster_level; +} + +/** + * hb_buffer_get_cluster_level: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 0.9.42 + **/ +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer) +{ + return buffer->cluster_level; +} + /** * hb_buffer_set_replacement_codepoint:
diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 520141b..4b285bb 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h
@@ -185,7 +185,19 @@ hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer); +typedef enum { + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES +} hb_buffer_cluster_level_t; +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level); + +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer); #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu
diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc index 6ac18b0..763dbf0 100644 --- a/src/hb-ot-shape-complex-hangul.cc +++ b/src/hb-ot-shape-complex-hangul.cc
@@ -209,13 +209,8 @@ hb_glyph_info_t tone = info[end]; memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t)); info[start] = tone; + buffer->merge_out_clusters (start, end + 1); } - /* Merge clusters across the (possibly reordered) syllable+tone. - * We want to merge even in the zero-width tone mark case here, - * so that clustering behavior isn't dependent on how the tone mark - * is handled by the font. - */ - buffer->merge_out_clusters (start, end + 1); } else { @@ -296,7 +291,8 @@ } else end = start + 2; - buffer->merge_out_clusters (start, end); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + buffer->merge_out_clusters (start, end); continue; } } @@ -368,7 +364,8 @@ info[i++].hangul_shaping_feature() = VJMO; if (i < end) info[i++].hangul_shaping_feature() = TJMO; - buffer->merge_out_clusters (start, end); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + buffer->merge_out_clusters (start, end); continue; } }
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 5ead0b7..d290cad 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc
@@ -264,6 +264,9 @@ static void hb_form_clusters (hb_buffer_t *buffer) { + if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + return; + /* Loop duplicated in hb_ensure_native_direction(). */ unsigned int base = 0; unsigned int count = buffer->len; @@ -301,10 +304,14 @@ if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) { buffer->reverse_range (base, i); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buffer->merge_clusters (base, i); base = i; } } buffer->reverse_range (base, count); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buffer->merge_clusters (base, count); buffer->reverse ();