Make it easier to use HB_BUFFER_FLAG_BOT/EOT

Previously, we expected users to provide BOT/EOT flags when the
text *segment* was at paragraph boundaries.  This meant that for
clients that provide full paragraph to HarfBuzz (eg. Pango), they
had code like this:

  hb_buffer_set_flags (hb_buffer,
                       (item_offset == 0 ? HB_BUFFER_FLAG_BOT : 0) |
                       (item_offset + item_length == paragraph_length ?
                        HB_BUFFER_FLAG_EOT : 0));

  hb_buffer_add_utf8 (hb_buffer,
                      paragraph_text, paragraph_length,
                      item_offset, item_length);

After this change such clients can simply say:

  hb_buffer_set_flags (hb_buffer,
                       HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT);

  hb_buffer_add_utf8 (hb_buffer,
                      paragraph_text, paragraph_length,
                      item_offset, item_length);

Ie, HarfBuzz itself checks whether the segment is at the beginning/end
of the paragraph.  Clients that only pass item-at-a-time to HarfBuzz
continue not setting any flags whatsoever.

Another way to put it is: if there's pre-context text in the buffer,
HarfBuzz ignores the BOT flag.  If there's post-context, it ignores
EOT flag.
This commit is contained in:
Behdad Esfahbod 2014-08-02 16:17:44 -04:00
parent 0a5ae93362
commit 763e5466c0
2 changed files with 20 additions and 21 deletions

View File

@ -248,18 +248,17 @@ arabic_joining (hb_buffer_t *buffer)
unsigned int prev = (unsigned int) -1, state = 0;
/* Check pre-context */
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]));
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++)
{
@ -281,19 +280,18 @@ arabic_joining (hb_buffer_t *buffer)
state = entry->next_state;
}
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[1][i]));
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[1][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)
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)
info[prev].arabic_shaping_action() = entry->prev_action;
break;
}
}
static void

View File

@ -236,6 +236,7 @@ static void
hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
{
if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
buffer->context_len[0] ||
_hb_glyph_info_get_general_category (&buffer->info[0]) !=
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
return;