Optimize runs without Default_Ignorable's

Now that we have a buffer-wide scratch flags facility, use it to
optimize away a few passes.
This commit is contained in:
Behdad Esfahbod 2015-11-04 18:46:22 -08:00
parent 14c2de3218
commit 6986208ba3
5 changed files with 16 additions and 8 deletions

View File

@ -43,7 +43,8 @@ template <> class hb_mark_as_flags_t<hb_buffer_serialize_flags_t> {};
enum hb_buffer_scratch_flags_t { enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u,
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000001u, HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000001u,
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000002u,
}; };
template <> class hb_mark_as_flags_t<hb_buffer_scratch_flags_t> {}; template <> class hb_mark_as_flags_t<hb_buffer_scratch_flags_t> {};

View File

@ -240,8 +240,9 @@ enum hb_unicode_props_flags_t {
template <> class hb_mark_as_flags_t<hb_unicode_props_flags_t> {}; template <> class hb_mark_as_flags_t<hb_unicode_props_flags_t> {};
static inline void static inline void
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
{ {
hb_unicode_funcs_t *unicode = buffer->unicode;
unsigned int u = info->codepoint; unsigned int u = info->codepoint;
unsigned int gen_cat = (unsigned int) unicode->general_category (u); unsigned int gen_cat = (unsigned int) unicode->general_category (u);
unsigned int props = gen_cat; unsigned int props = gen_cat;
@ -250,6 +251,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *uni
{ {
if (unlikely (unicode->is_default_ignorable (u))) if (unlikely (unicode->is_default_ignorable (u)))
{ {
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
props |= UPROPS_MASK_IGNORABLE; props |= UPROPS_MASK_IGNORABLE;
if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ; if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ;
if (u == 0x200Du) props |= UPROPS_MASK_ZWJ; if (u == 0x200Du) props |= UPROPS_MASK_ZWJ;

View File

@ -99,7 +99,7 @@ output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
{ {
buffer->cur().glyph_index() = glyph; buffer->cur().glyph_index() = glyph;
buffer->output_glyph (unichar); /* This is very confusing indeed. */ buffer->output_glyph (unichar); /* This is very confusing indeed. */
_hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode); _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
} }
static inline void static inline void
@ -399,7 +399,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* Modify starter and carry on. */ /* Modify starter and carry on. */
buffer->out_info[starter].codepoint = composed; buffer->out_info[starter].codepoint = composed;
buffer->out_info[starter].glyph_index() = glyph; buffer->out_info[starter].glyph_index() = glyph;
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode); _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
continue; continue;
} }

View File

@ -228,7 +228,7 @@ hb_set_unicode_props (hb_buffer_t *buffer)
unsigned int count = buffer->len; unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
_hb_glyph_info_set_unicode_props (&info[i], buffer->unicode); _hb_glyph_info_set_unicode_props (&info[i], buffer);
} }
static void static void
@ -245,7 +245,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
hb_glyph_info_t dottedcircle = {0}; hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu; dottedcircle.codepoint = 0x25CCu;
_hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); _hb_glyph_info_set_unicode_props (&dottedcircle, buffer);
buffer->clear_output (); buffer->clear_output ();
@ -416,7 +416,8 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
{ {
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES))
return; return;
unsigned int count = buffer->len; unsigned int count = buffer->len;
@ -433,7 +434,8 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
{ {
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES))
return; return;
unsigned int count = buffer->len; unsigned int count = buffer->len;

View File

@ -892,6 +892,9 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
/* Enable bitwise ops on enums marked as flags_t */ /* Enable bitwise ops on enums marked as flags_t */
/* To my surprise, looks like the function resolver is happy to silently cast
* one enum to another... So this doesn't provide the type-checking that I
* originally had in mind... :( */
template <class T> class hb_mark_as_flags_t; template <class T> class hb_mark_as_flags_t;
template <class T> static inline T operator | (T l, T r) template <class T> static inline T operator | (T l, T r)
{ hb_mark_as_flags_t<T> unused HB_UNUSED; return T ((unsigned int) l | (unsigned int) r); } { hb_mark_as_flags_t<T> unused HB_UNUSED; return T ((unsigned int) l | (unsigned int) r); }