diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 4e92fb5ff..6cfb115c3 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -89,6 +89,7 @@ struct hb_buffer_t { hb_unicode_funcs_t *unicode; /* Unicode functions */ hb_segment_properties_t props; /* Script, language, direction */ + hb_buffer_flags_t flags; /* BOT / EOT / etc. */ /* Buffer contents */ diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 6aff7b9b4..b7701447b 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -153,6 +153,7 @@ hb_buffer_t::clear (void) hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT; props = default_props; + flags = HB_BUFFER_FLAGS_DEFAULT; content_type = HB_BUFFER_CONTENT_TYPE_INVALID; in_error = false; @@ -590,6 +591,7 @@ hb_buffer_get_empty (void) const_cast (&_hb_unicode_funcs_nil), _HB_BUFFER_PROPS_DEFAULT, + HB_BUFFER_FLAGS_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, true, /* in_error */ @@ -724,6 +726,22 @@ hb_buffer_get_language (hb_buffer_t *buffer) return buffer->props.language; } +void +hb_buffer_set_flags (hb_buffer_t *buffer, + hb_buffer_flags_t flags) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->flags = flags; +} + +hb_buffer_flags_t +hb_buffer_get_flags (hb_buffer_t *buffer) +{ + return buffer->flags; +} + void hb_buffer_reset (hb_buffer_t *buffer) diff --git a/src/hb-buffer.h b/src/hb-buffer.h index fbd809cf5..533bac842 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -68,6 +68,12 @@ typedef enum { HB_BUFFER_CONTENT_TYPE_GLYPHS } hb_buffer_content_type_t; +typedef enum { + HB_BUFFER_FLAGS_DEFAULT = 0x00000000, + HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */ + HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */ + HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004 +} hb_buffer_flags_t; hb_buffer_t * hb_buffer_create (void); @@ -129,6 +135,13 @@ hb_buffer_set_language (hb_buffer_t *buffer, hb_language_t hb_buffer_get_language (hb_buffer_t *buffer); +void +hb_buffer_set_flags (hb_buffer_t *buffer, + hb_buffer_flags_t flags); + +hb_buffer_flags_t +hb_buffer_get_flags (hb_buffer_t *buffer); + /* Resets the buffer. Afterwards it's as if it was just created, * except that it has a larger buffer allocated perhaps... */ diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index cba793394..59c971675 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -250,17 +250,18 @@ arabic_joining (hb_buffer_t *buffer) HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); /* Check pre-context */ - for (unsigned int i = 0; i < buffer->context_len[0]; i++) - { - unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i])); + if (!(buffer->flags & HB_BUFFER_FLAG_BOT)) + for (unsigned int i = 0; i < buffer->context_len[0]; i++) + { + unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i])); - if (unlikely (this_type == JOINING_TYPE_T)) - continue; + if (unlikely (this_type == JOINING_TYPE_T)) + continue; - const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; - state = entry->next_state; - break; - } + const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; + state = entry->next_state; + break; + } for (unsigned int i = 0; i < count; i++) { @@ -282,18 +283,19 @@ arabic_joining (hb_buffer_t *buffer) state = entry->next_state; } - for (unsigned int i = 0; i < buffer->context_len[1]; i++) - { - unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[0][i])); + if (!(buffer->flags & HB_BUFFER_FLAG_EOT)) + for (unsigned int i = 0; i < buffer->context_len[1]; i++) + { + unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[0][i])); - if (unlikely (this_type == JOINING_TYPE_T)) - continue; + if (unlikely (this_type == JOINING_TYPE_T)) + continue; - const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; - if (entry->prev_action != NONE && prev != (unsigned int) -1) - buffer->info[prev].arabic_shaping_action() = entry->prev_action; - break; - } + const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; + if (entry->prev_action != NONE && prev != (unsigned int) -1) + buffer->info[prev].arabic_shaping_action() = entry->prev_action; + break; + } HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 26ec4db9f..634fe6fb2 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -237,7 +237,7 @@ hb_set_unicode_props (hb_buffer_t *buffer) static void hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) { - if (buffer->context_len[0] || + if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || _hb_glyph_info_get_general_category (&buffer->info[0]) != HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) return; @@ -509,8 +509,11 @@ hb_ot_position (hb_ot_shape_context_t *c) /* Post-process */ static void -hb_ot_hide_zerowidth (hb_ot_shape_context_t *c) +hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) { + if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + return; + hb_codepoint_t space = 0; unsigned int count = c->buffer->len; @@ -554,7 +557,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ot_substitute (c); hb_ot_position (c); - hb_ot_hide_zerowidth (c); + hb_ot_hide_default_ignorables (c); HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1); HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0); diff --git a/test/api/test-buffer.c b/test/api/test-buffer.c index 7cc99bdda..51b227793 100644 --- a/test/api/test-buffer.c +++ b/test/api/test-buffer.c @@ -110,6 +110,7 @@ test_buffer_properties (fixture_t *fixture, gconstpointer user_data) g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID); g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID); g_assert (hb_buffer_get_language (b) == NULL); + g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT); /* test property changes are retained */ @@ -127,6 +128,9 @@ test_buffer_properties (fixture_t *fixture, gconstpointer user_data) hb_buffer_set_language (b, hb_language_from_string ("fa", -1)); g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1)); + hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT); + g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT); + /* test clear clears all properties but unicode_funcs */ @@ -137,6 +141,7 @@ test_buffer_properties (fixture_t *fixture, gconstpointer user_data) g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID); g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID); g_assert (hb_buffer_get_language (b) == NULL); + g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT); /* test reset clears all properties */ @@ -150,12 +155,16 @@ test_buffer_properties (fixture_t *fixture, gconstpointer user_data) hb_buffer_set_language (b, hb_language_from_string ("fa", -1)); g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1)); + hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT); + g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT); + hb_buffer_reset (b); g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ()); g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID); g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID); g_assert (hb_buffer_get_language (b) == NULL); + g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT); } static void