Merge pull request #3027 from harfbuzz/buffer-sync

Improving buffer synchronization
This commit is contained in:
Behdad Esfahbod 2021-07-12 16:51:43 -07:00 committed by GitHub
commit f51384d375
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 52 deletions

View File

@ -96,14 +96,15 @@ hb_segment_properties_hash (const hb_segment_properties_t *p)
* As an optimization, both info and out_info may point to the * As an optimization, both info and out_info may point to the
* same piece of memory, which is owned by info. This remains the * same piece of memory, which is owned by info. This remains the
* case as long as out_len doesn't exceed i at any time. * case as long as out_len doesn't exceed i at any time.
* In that case, swap_buffers() is no-op and the glyph operations operate * In that case, swap_buffers() is mostly no-op and the glyph operations
* mostly in-place. * operate mostly in-place.
* *
* As soon as out_info gets longer than info, out_info is moved over * As soon as out_info gets longer than info, out_info is moved over
* to an alternate buffer (which we reuse the pos buffer for!), and its * to an alternate buffer (which we reuse the pos buffer for), and its
* current contents (out_len entries) are copied to the new place. * current contents (out_len entries) are copied to the new place.
*
* This should all remain transparent to the user. swap_buffers() then * This should all remain transparent to the user. swap_buffers() then
* switches info and out_info. * switches info over to out_info and does housekeeping.
*/ */
@ -281,22 +282,13 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info)
} }
void
hb_buffer_t::remove_output ()
{
have_output = false;
have_positions = false;
out_len = 0;
out_info = info;
}
void void
hb_buffer_t::clear_output () hb_buffer_t::clear_output ()
{ {
have_output = true; have_output = true;
have_positions = false; have_positions = false;
idx = 0;
out_len = 0; out_len = 0;
out_info = info; out_info = info;
} }
@ -316,29 +308,23 @@ hb_buffer_t::clear_positions ()
void void
hb_buffer_t::swap_buffers () hb_buffer_t::swap_buffers ()
{ {
if (unlikely (!successful)) return; assert (have_output);
assert (idx <= len); assert (idx <= len);
if (unlikely (!next_glyphs (len - idx))) return;
assert (have_output); if (unlikely (!successful || !next_glyphs (len - idx)))
have_output = false; goto reset;
if (out_info != info) if (out_info != info)
{ {
hb_glyph_info_t *tmp; pos = (hb_glyph_position_t *) info;
tmp = info;
info = out_info; info = out_info;
out_info = tmp;
pos = (hb_glyph_position_t *) out_info;
} }
unsigned int tmp;
tmp = len;
len = out_len; len = out_len;
out_len = tmp;
reset:
have_output = false;
out_len = 0;
idx = 0; idx = 0;
} }

View File

@ -107,7 +107,7 @@ struct hb_buffer_t
unsigned int idx; /* Cursor into ->info and ->pos arrays */ unsigned int idx; /* Cursor into ->info and ->pos arrays */
unsigned int len; /* Length of ->info and ->pos arrays */ unsigned int len; /* Length of ->info and ->pos arrays */
unsigned int out_len; /* Length of ->out array if have_output */ unsigned int out_len; /* Length of ->out_info array if have_output */
unsigned int allocated; /* Length of allocated arrays */ unsigned int allocated; /* Length of allocated arrays */
hb_glyph_info_t *info; hb_glyph_info_t *info;
@ -189,13 +189,10 @@ struct hb_buffer_t
hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; }
hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
HB_NODISCARD bool has_separate_output () const { return info != out_info; }
HB_INTERNAL void reset (); HB_INTERNAL void reset ();
HB_INTERNAL void clear (); HB_INTERNAL void clear ();
unsigned int backtrack_len () const { return have_output? out_len : idx; } unsigned int backtrack_len () const { return have_output ? out_len : idx; }
unsigned int lookahead_len () const { return len - idx; } unsigned int lookahead_len () const { return len - idx; }
unsigned int next_serial () { return serial++; } unsigned int next_serial () { return serial++; }
@ -209,7 +206,6 @@ struct hb_buffer_t
HB_INTERNAL void guess_segment_properties (); HB_INTERNAL void guess_segment_properties ();
HB_INTERNAL void swap_buffers (); HB_INTERNAL void swap_buffers ();
HB_INTERNAL void remove_output ();
HB_INTERNAL void clear_output (); HB_INTERNAL void clear_output ();
HB_INTERNAL void clear_positions (); HB_INTERNAL void clear_positions ();

View File

@ -1886,27 +1886,20 @@ apply_string (OT::hb_ot_apply_context_t *c,
if (likely (!lookup.is_reverse ())) if (likely (!lookup.is_reverse ()))
{ {
/* in/out forward substitution/positioning */ /* in/out forward substitution/positioning */
if (Proxy::table_index == 0u) if (!Proxy::inplace)
buffer->clear_output (); buffer->clear_output ();
buffer->idx = 0;
bool ret; buffer->idx = 0;
ret = apply_forward (c, accel); apply_forward (c, accel);
if (ret)
{ if (!Proxy::inplace)
if (!Proxy::inplace) buffer->swap_buffers ();
buffer->swap_buffers ();
else
assert (!buffer->has_separate_output ());
}
} }
else else
{ {
/* in-place backward substitution/positioning */ /* in-place backward substitution/positioning */
if (Proxy::table_index == 0u) assert (!buffer->have_output);
buffer->remove_output ();
buffer->idx = buffer->len - 1; buffer->idx = buffer->len - 1;
apply_backward (c, accel); apply_backward (c, accel);
} }
} }
@ -1942,10 +1935,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
} }
if (stage->pause_func) if (stage->pause_func)
{
buffer->clear_output ();
stage->pause_func (plan, font, buffer); stage->pause_func (plan, font, buffer);
}
} }
} }

View File

@ -1158,8 +1158,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
_hb_buffer_allocate_unicode_vars (c->buffer); _hb_buffer_allocate_unicode_vars (c->buffer);
c->buffer->clear_output ();
hb_ot_shape_initialize_masks (c); hb_ot_shape_initialize_masks (c);
hb_set_unicode_props (c->buffer); hb_set_unicode_props (c->buffer);
hb_insert_dotted_circle (c->buffer, c->font); hb_insert_dotted_circle (c->buffer, c->font);