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.
pull/107/merge
Behdad Esfahbod 10 years ago
parent b3a2f6afba
commit 82b521aeb7
  1. 18
      src/hb-buffer-private.hh
  2. 65
      src/hb-ot-shape.cc

@ -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)
return;
hb_buffer_t *buffer = c->buffer;
hb_codepoint_t space;
enum {
SPACE_DONT_KNOW,
SPACE_AVAILABLE,
SPACE_UNAVAILABLE
} space_status = SPACE_DONT_KNOW;
if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
return;
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;
}
/* No default-ignorables found; return. */
if (i == count)
return;
if (space_status == SPACE_AVAILABLE)
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)
}
else
{
/* Merge clusters and delete default-ignorables. */
buffer->clear_output ();
buffer->idx = 0;
buffer->next_glyphs (i);
while (buffer->idx < buffer->len)
{
info[j] = info[i];
pos[j] = pos[i];
if (!_hb_glyph_info_ligated (&info[buffer->idx]) &&
_hb_glyph_info_is_default_ignorable (&info[buffer->idx]))
{
buffer->skip_glyph ();
continue;
}
buffer->next_glyph ();
}
j++;
buffer->swap_buffers ();
}
c->buffer->len = j;
}

Loading…
Cancel
Save