Rewrite hide_default_ignorables
Separate the loops for the two cases of replacing with space and deleting. For deleting, use the out-buffer machinery. Needed for upcoming cluster merge fix.
This commit is contained in:
parent
b3a2f6afba
commit
82b521aeb7
|
@ -151,6 +151,24 @@ struct hb_buffer_t {
|
|||
|
||||
idx++;
|
||||
}
|
||||
inline void
|
||||
next_glyphs (unsigned int count)
|
||||
{
|
||||
if (have_output)
|
||||
{
|
||||
if (unlikely (out_info != info || out_len != idx)) {
|
||||
if (unlikely (!make_room_for (count, count))) return;
|
||||
{
|
||||
while (count--)
|
||||
out_info[out_len++] = info[idx++];
|
||||
return;
|
||||
}
|
||||
}
|
||||
out_len += count;
|
||||
}
|
||||
|
||||
idx += count;
|
||||
}
|
||||
|
||||
/* Advance idx without copying to output. */
|
||||
inline void skip_glyph (void) { idx++; }
|
||||
|
|
|
@ -647,45 +647,58 @@ hb_ot_position (hb_ot_shape_context_t *c)
|
|||
static void
|
||||
hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
|
||||
{
|
||||
if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
|
||||
if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
|
||||
return;
|
||||
|
||||
hb_codepoint_t space;
|
||||
enum {
|
||||
SPACE_DONT_KNOW,
|
||||
SPACE_AVAILABLE,
|
||||
SPACE_UNAVAILABLE
|
||||
} space_status = SPACE_DONT_KNOW;
|
||||
|
||||
unsigned int count = c->buffer->len;
|
||||
hb_glyph_info_t *info = c->buffer->info;
|
||||
hb_glyph_position_t *pos = c->buffer->pos;
|
||||
unsigned int j = 0;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
unsigned int i = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (unlikely (!_hb_glyph_info_ligated (&info[i]) &&
|
||||
_hb_glyph_info_is_default_ignorable (&info[i])))
|
||||
{
|
||||
if (space_status == SPACE_DONT_KNOW)
|
||||
space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (space_status == SPACE_AVAILABLE)
|
||||
/* No default-ignorables found; return. */
|
||||
if (i == count)
|
||||
return;
|
||||
|
||||
hb_codepoint_t space;
|
||||
if (c->font->get_glyph (' ', 0, &space))
|
||||
{
|
||||
/* Replace default-ignorables with a zero-advance space glyph. */
|
||||
for (/*continue*/; i < count; i++)
|
||||
{
|
||||
if (!_hb_glyph_info_ligated (&info[i]) &&
|
||||
_hb_glyph_info_is_default_ignorable (&info[i]))
|
||||
{
|
||||
info[i].codepoint = space;
|
||||
pos[i].x_advance = 0;
|
||||
pos[i].y_advance = 0;
|
||||
pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
continue; /* Delete it. XXX Merge clusters? */
|
||||
}
|
||||
if (j != i)
|
||||
{
|
||||
info[j] = info[i];
|
||||
pos[j] = pos[i];
|
||||
/* Merge clusters and delete default-ignorables. */
|
||||
buffer->clear_output ();
|
||||
buffer->idx = 0;
|
||||
buffer->next_glyphs (i);
|
||||
while (buffer->idx < buffer->len)
|
||||
{
|
||||
if (!_hb_glyph_info_ligated (&info[buffer->idx]) &&
|
||||
_hb_glyph_info_is_default_ignorable (&info[buffer->idx]))
|
||||
{
|
||||
buffer->skip_glyph ();
|
||||
continue;
|
||||
}
|
||||
j++;
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
c->buffer->len = j;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue